This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

how to save 2byte code address to stack manually

Hello,
I have a function void myfunc(int){...}
I want to place the address of this function on the stack, so that later I can use RET to pop the address back.
May I know how to do this in C code?
Regards,
KC

Parents
  • Hello,
    -------------------------------------------
    char *stackPointer;
    void *VoidPointer;
    char *GenericPointer;

    VoidPointer = GenericPointer;
    -------------------------------------------

    I want to save the 3byte "VoidPointer" into the stack space, which is pointed to by stackPointer.

    // Tried
    *(void *)stackPointer = VoidPtr;
    // but it doesnt work

    // this works
    *(void **)stackPointer = VoidPtr;
    // May I know why?

    Regards,
    KC

Reply
  • Hello,
    -------------------------------------------
    char *stackPointer;
    void *VoidPointer;
    char *GenericPointer;

    VoidPointer = GenericPointer;
    -------------------------------------------

    I want to save the 3byte "VoidPointer" into the stack space, which is pointed to by stackPointer.

    // Tried
    *(void *)stackPointer = VoidPtr;
    // but it doesnt work

    // this works
    *(void **)stackPointer = VoidPtr;
    // May I know why?

    Regards,
    KC

Children
  • I want to save the 3byte "VoidPointer" into the stack space, which is pointed to by stackPointer

    WHY, explain IN DETAIL?

    There are many ways to do what you are talking about and "saving on the stack may not be the right thing. Most cases this is an automatic compilr function, but if you are doing some fancy compiler/assmbler mix, maybe you need do something unique. Again, without knowing why - no answer.

    Erik

  • You must have a rather strange meaning of "this works", it seems.

    Your first example is outright incorrect code. You can't legally dereference a pointer-to-void. There *is* nothing it points to, thus the name "void".

    The second example would overwrite StackPointer with VoidPointer, rather than storing VoidPointer on the stack. The code does the equivalent of

    	(void *)StackPointer = VoidPointer
    

    because the * before the (void **) and the second * inside the cast cancel each other.

    To do what you said you want to do, you need something along the lines of

    memcpy(StackPointer, &VoidPointer, sizeof(VoidPointer));
    StackPointer += sizeof(VoidPointer);

    NOTE: This may still be gravely wrong, depending on byte order and stack growth direction)


  • For the moment, I'm assuming "stackPointer" has nothing to do with the 8051 stack, and is just a good old C pointer for some software-maintained stack.

    You have a three-byte pointer which you want to stuff onto the stack, for some reason.

    To assign through a pointer, you need to make sure that the pointer actually points to a place where you can write your data. I'll assume that you've managed to get stackPointer to point at a spot with three bytes free that can be overwritten.

    So, the only thing left is to convince the compiler that stackPointer points at the same sort of thing that you're trying to store. I'll call the type of that thing "???". If you had a pointer to ???, you could then just dereference that pointer with '*', and do an assignment:

    ???* mysteryPointer;
    ??? m;

    *mysteryPointer = m;

    We can use a cast to change the type of the stackPointer instead of actually having a pointer declared of the correct type. So replace mysteryPointer with a cast of stackPointer:

    * ((??? *) stackPointer) = m;

    Filling in the question marks is actually pretty easy. You need cast stackPointer as a pointer to the type of thing that you're storing -- in this case a (void*). So:

    * (( (void*) *) stackPointer) = voidPointer;

    Which says "pretend stackPointer is a pointer to a void-pointer, then dereference it, and put a void-pointer there".

    You can strip off some of the spaces and redundant parentheses (hi Mark!) if you like:

    *(void**)stackPointer = voidPointer;

    which is the code that you said works. Now, you know why.

    As Hans noted, there are some other issues, like whether your stack pointer points at the last-occupied region, or whether it points at the next free spot.