C calling conventions and passed arguments

后端 未结 4 1001
-上瘾入骨i
-上瘾入骨i 2021-01-06 05:35

When making a function call in Linux (or OS X for that matter), can the callee modify the values of the arguments on the stack? I was under the assumption that since the ca

相关标签:
4条回答
  • 2021-01-06 06:07

    Yes, the callee can modify the arguments on the stack. As far as the callee is concerned, they are the same as local variables. The caller does clean them up but ignores the value.

    If you're talking C or C++ POD, clean up is simply modifying the stack pointer.

    If you're talking about C++ with a destructor, the caller is responsible for invoking the destructor but destructors for generic classes need to be written to cleanup any value.

    0 讨论(0)
  • 2021-01-06 06:10

    In standard C, the callee can modify the values of its arguments all it wants, but the caller will never see the changes.

    What may be confusing is that if one passes a POINTER to a value, then the callee can change that value by dereferencing the pointer, but if the callee actually changes the pointer itself the caller will not see that change.

    A small nit: the C standard does not require that the implementation even HAVE a stack.

    0 讨论(0)
  • 2021-01-06 06:11

    If you pass by value:

    call do_it(to_it);
    

    The argument is copied (probably to the begining of the stack but maybe not depending on your compiler) the celled program can mess with this copy as much as it wants but the variable in the clling program will not be changed.

    If you pass by reference:

    call do_it(&to_it);
    

    Then the address of the variable is passed. Any changes the called variable makes will be to the original variable in the calling program.

    0 讨论(0)
  • 2021-01-06 06:18

    Although the caller (in some calling conventions) is the one that cleans up the arguments, all it's really doing is deallocating the space previously allocated on the stack to hold the argument values. The callee is free to modify the values during execution of the function, because the caller isn't going to look at their values later.

    In the example you posted, GCC has emitted the popl %eax instruction to deallocate the space taken by the parameter on the stack. All it really needs to do is add 4 to %esp (the stack on x86 grows downwards in memory), and executing the popl %eax instruction is the shortest and fastest way to do this. If the compiler needed to deallocate 20 values, it would probably modify %esp directly instead of emitting 20 popl instructions.

    You will probably find that the new value of %eax is not used in the following code.

    0 讨论(0)
提交回复
热议问题