参数入栈
c/c++:通常函数参数是默认的入栈方式:__cdecl,即参数入
栈顺序是从右至左。
至于其他的方式:__fastcall, __thiscall等,参考:
Keyword | Stack cleanup | Parameter passing |
---|---|---|
Caller | Pushes parameters on the stack, in reverse order (right to left) | |
n/a | Load parameters onto CLR expression stack in order (left to right). | |
Callee | Pushes parameters on the stack, in reverse order (right to left) | |
Callee | Stored in registers, then pushed on stack | |
Callee | Pushed on stack; this pointer stored in ECX | |
Callee | Stored in registers, then pushed on stack in reverse order (right to left) |
各个入栈方式的说明,微软链接:
入栈方式的原因(为什么如此入栈)
从右至左的入栈方式,对于函数是可变参数而言,可以根据最后入栈的是参数个数(即最左边的参数,也是栈顶位置),得到全部其他参数,根据栈顶依次得到全部可变的参数。
试想如果从左至右入栈,要知道入栈的参数个数是不是很困难呢
参数计算逻辑
c/c++中没有规定函数参数的计算顺序,跟各自的编译器相关。根据验证,gcc和vs,它们都是从右至左计算参数。
并且,对于函数参数的内部读取逻辑,是在入栈前会把参数列表里的表达式从右向左算一遍得到表达式的结果后再把这些运算结果统一入栈。
注意:对于自增,形式:value++,编译器会开一个临时缓冲区来保存当前value的值,然后再对value操作,最后参数入栈时的取值是从临时缓冲区里取,而不是从value原地址里取。