2012-02-04 56 views
8

我正在学习汇编语言。参数推送顺序究竟是什么?我理解它是如何将参数推入堆栈的,但左边和右边的部分是什么意思?什么左边或右边? 或者这仅仅是与命令的语义写入方式有关,即:什么是参数推送顺序

mov ebp,esp; esp被移到ebp中,从右到左。

这是正确的还是有人能够启发我?

非常感谢!

回答

11

处理器不知道'函数参数'。因此,当你想写f(a,b,c)时,你真的需要将参数推到某处。

这是约定。我知道在大多数x86机器上,函数参数从右到左被推入堆栈,即先c,然后b,然后a。

push c 
push b 
push a 
call f 

现在被调用函数可以使用ebx -1了,ebx - 2 b和ebx - 3对C。

你也可以建立一个约定:前两个参数在寄存器ebxecx中,其余的都在堆栈上。只要主叫方和被叫方同意,你就没事。

7

除了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 - 你的架构肯定会有一个标准的调用约定,因为没有它的工作很困难。

+0

非常感谢你们俩。这非常有帮助,我现在明白它好多了!非常感谢! – Axolotl 2012-02-06 12:19:15