2012-07-01 59 views
0

我需要选择正确的函数调用函数foo,而不是写在c中。 foo得到1个参数0x100fa500。汇编中的推送指令(英特尔8086)

第一个答案是:

sub esp,2 
mov word[esp],0xa500 
sub esp,2 
mov word[esp] , 0x100f 
call foo 
add esp 4 

与第二:

sub esp,2 
mov word[esp],0x100f 
sub esp,2 
mov word[esp] , 0xa500 
call foo 

为什么第二次是真的吗?我认为第一个实现右推参数,然后调用

+0

标记为家庭作业吗? – ndkrempel

回答

3
从末失踪 add esp, 4

除此之外,第二个版本是正确的,因为英特尔架构是little-endian的。这意味着一个DWORD被存储在内存中,其最低有效BYTE或WORD占用较低的内存地址。在你的情况下,0xA500是DWORD中最不重要的WORD,第二个版本正确地将它放在堆栈的一个4字节区域的低2字节中。

+0

但是不是从高地址开始堆栈? 我的意思是,如果我将执行第一个代码,我会得到: 10在堆栈的最低地址和00最高。我会得到,如果我这样做:推0x100fa500。我对吗? 这也是什么 – user1462787

+0

@ user1462787:你所说的一切都与一个大端的体系结构一致,在这里并不是这样。你试图把10放在堆栈的最低地址的事实已经是错误的。实际上,第一个代码会将0F放在堆栈的最低地址中 - 事实上,您犯了两次相同的错误(一次是DWORD中的字节顺序,与问题要求相关,一次是字节顺序一个WORD,与'mov'指令的操作有关。) – ndkrempel

+0

@ user1462787:或许你的困惑与堆栈向下增长有关。从这个意义上讲,堆栈是'向后'的,但堆栈中的单个数据项以正常顺序存储,否则使用标准的DWORD和WORD大小的'mov's将无法正确访问它们。 – ndkrempel

0

它取决于调用约定,但对于“cdecl”,由调用者清理堆栈。这意味着这是你的第一个答案是正确的,因为它“添加了特别的,4”。然而,就像他在回答中的ndkrempel通知一样,参数应该像第二个答案一样以小尾数的形式传递。

http://en.wikipedia.org/wiki/X86_calling_conventions

+0

我认为调用者堆栈清理与否仅仅是一个错误的问题。注意“mov”的顺序不同 - 我认为这是问题的主要核心。 – ndkrempel

+0

@ndkrempel:我认为你是对的。我编辑了我的答案。这确实可能是一个家庭作业问题:-) –