我正在学习汇编语言。参数推送顺序究竟是什么?我理解它是如何将参数推入堆栈的,但左边和右边的部分是什么意思?什么左边或右边? 或者这仅仅是与命令的语义写入方式有关,即:什么是参数推送顺序
mov ebp,esp; esp被移到ebp中,从右到左。
这是正确的还是有人能够启发我?
非常感谢!
我正在学习汇编语言。参数推送顺序究竟是什么?我理解它是如何将参数推入堆栈的,但左边和右边的部分是什么意思?什么左边或右边? 或者这仅仅是与命令的语义写入方式有关,即:什么是参数推送顺序
mov ebp,esp; esp被移到ebp中,从右到左。
这是正确的还是有人能够启发我?
非常感谢!
处理器不知道'函数参数'。因此,当你想写f(a,b,c)
时,你真的需要将参数推到某处。
这是约定。我知道在大多数x86机器上,函数参数从右到左被推入堆栈,即先c,然后b,然后a。
push c
push b
push a
call f
现在被调用函数可以使用ebx -1
了,ebx - 2
b和ebx - 3
对C。
你也可以建立一个约定:前两个参数在寄存器ebx
和ecx
中,其余的都在堆栈上。只要主叫方和被叫方同意,你就没事。
除了xtofl的解释,你可能想看看x86 calling conventions这张表。你会注意到,关于参数顺序是几乎所有的参数都是从右到左推进的(最右边的参数是先推动的),但Pascal除外。
xtofl没有涉及的另一个场景是寄存器参数 - 一些ABI要求某些参数在寄存器中,而不是在堆栈中的。在一个x86_64
系统,例如,函数:
int add3(int a, int b, int c)
会把参数:
a -> rdi
b -> rsi
c -> rdx
具体而言,这看起来像(Intel语法):
mov rdi, [source-of-a]
mov rsi, [source-of-b]
mov rdx, [source-of-c]
call add3
所以寄存器从注册表中填入从左到右然后堆栈被使用从右到左。
由于xtofl说,没关系,你不提供什么样的主叫用户和被叫同意 - 但是很显然,如果主叫用户和被叫反对这会导致不兼容的问题,其实这是一种不关注只适用于汇编程序,但也适用于更高级别的语言 - 幸运的是,编译器很大程度上正确运行。为了进一步阅读,您可能会发现堆栈的被调用者/调用者清除有趣 - 并注意它是如何标准化为x86_64
的一种方法的。
你不会说你正在使用x86
- 你的架构肯定会有一个标准的调用约定,因为没有它的工作很困难。
非常感谢你们俩。这非常有帮助,我现在明白它好多了!非常感谢! – Axolotl 2012-02-06 12:19:15