关于序言/调用函数gcc intel x86的一些问题

时间:2015-08-21 17:01:25

标签: gcc assembly x86

我不安静地了解gcc的序幕,特别是对于主要的。 为什么有and esp, 0xfffffff0指令?我知道它的作用,但为什么有必要呢?

当我们调用一个函数时,我们首先必须推送参数,但是为什么gcc不使用push指令而是使用movs呢?此外,使用这些movs,它会创建一个空填充。它看起来像浪费记忆,为什么会这样?

最后,gcc首先使用子指令来esp以便为堆栈“保留”内存,但是确保其他程序不使用此内存的是什么?

我想我理解得很安静但是我找不到一个文件来解释更多关于实践中的记忆(几个程序的记忆如何重叠,......)。谢谢你的回答。

PS:我添加汇编代码和cpp代码:

    Dump of assembler code for function main(int, char**):
0x08048657 <+0>:     push   ebp
   0x08048658 <+1>:     mov    ebp,esp
   0x0804865a <+3>:     and    esp,0xfffffff0
   0x0804865d <+6>:     sub    esp,0x20
   0x08048660 <+9>:     mov    DWORD PTR [esp+0x1c],0x3
   0x08048668 <+17>:    mov    BYTE PTR [esp+0x1b],0x61
=> 0x0804866d <+22>:    mov    DWORD PTR [esp],0x8048771
   0x08048674 <+29>:    call   0x804863c <p(char*)>
   0x08048679 <+34>:    mov    eax,0x0
   0x0804867e <+39>:    leave  
   0x0804867f <+40>:    ret    
End of assembler dump.


 int main(int argc, char *argv[]) {
  int b = 3;
  char c = 'a';
  p("hello woooooooooorld !!");}

1 个答案:

答案 0 :(得分:3)

仅对main进行堆栈对齐,其余函数只保留ABI所需的对齐。

编译器对本地使用mov指令,因此可以随机访问它们。对于传出函数参数,您可以使用可能产生较小代码的push编译器选项来请求-mpush-args指令。

至于浪费的内存,你可能没有启用优化编译(这当然会完全消除你的bc,因为它们没有被使用;))

每个进程都有自己的虚拟内存地址空间,因此任何其他人都无法使用从堆栈中分配的内存。