堆栈寻址和esp使用的行为

时间:2016-02-23 13:38:25

标签: c assembly x86

我有这个C代码部分:

#include <stdio.h>
void main()
{
int n, array[1000], c, d, t, e;
char step;

puts("Enter a number\n");
scanf("%d", &n);

puts("any help? [y/n]");
scanf(" %c",&step);

puts("Enter integers\n");
}

我的相应汇编代码:

push prompt1
call _printf
add esp, 4        ;print and add 4 bytes to esp
push num
push sc1    
call _scanf
add esp, 8       ;scan and add 8 bytes to esp

section .data
prompt1 db "Enter a number",13,10,0
sc2     db " %c",0 ;other constants

在命令提示符下将C文件转换为NASM格式后得到的汇编代码。

mov dword [esp], ?_001       ;?_001 is prompt1                    
call    _puts                                   
lea     eax, [esp+0FBCH]                        
mov     dword [esp+4H], eax                     
mov     dword [esp], ?_002   ;?_002 is sc1                 
call    _scanf                                  
mov     dword [esp], ?_003                  
call    _puts               

完整汇编代码:http://pastebin.com/R6UHRw8x 但是,我不理解转换后的汇编代码,因为mov dword [esp + 4H],eax使用[esp + 4]而下一行只使用[esp]。 不应该先[esp]然后[esp + 4]吗?我不明白,我在文件中看到了很多次出现。 除了push和mov之外,生成的代码与esp有什么不同?

1 个答案:

答案 0 :(得分:3)

编译器输出将scanf指针传递给堆栈空间,而不是静态存储。

它允许args在堆栈上构建而不是在每次调用后弹出(因此它可以使用mov)。不幸的是,这两种方式都没有避免inserting stack-engine synchronization uops

根据ABI /调用约定,第一个arg(按C顺序)位于最低地址,就在返回地址之上。将esp+0FBCH放入[esp+0x4],将格式字符串指针放入[esp]是正确的。有关链接,请参阅代码Wiki。