【问题标题】:Some questions about prologue/calling a function gcc intel x86关于序言/调用函数 gcc intel x86 的一些问题
【发布时间】:2015-11-15 17:14:37
【问题描述】:

我不太了解 gcc 的序言,尤其是对于 main。 为什么会有指令and esp, 0xfffffff0?我知道它的作用,但为什么有必要?

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

最后,gcc 首先使用 sub 指令 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 !!");}

【问题讨论】:

  • gcc -O0 甚至不使用 xor eax, eax 作为归零习语? ://

标签: gcc assembly x86


【解决方案1】:

堆栈对齐只针对main进行,其余函数仅保持ABI要求的对齐。

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

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

每个进程都有自己的虚拟内存地址空间,因此其他人不可能使用从堆栈分配的内存。

【讨论】:

  • “浪费内存”:我认为他是在谈论每个 arg 在堆栈上占用 4B 的事实,即使它是更窄的类型。 @x4rkz:这是 ABI 要求的。原因包括:保持堆栈对齐,以及将 args 发送到同一个位置,而不管它们的类型如何。但是,您的示例并未证明这一点。要么是那个,要么是他在谈论本地变量的存储位置和函数 arg 的位置之间的差距。那是为了保持堆栈对齐。
  • 谢谢,我明白了大部分,我明白了为什么需要对齐感谢这个链接en.wikipedia.org/wiki/Data_structure_alignment,显然它与硬件相关。我只是不明白你的意思是买“他们可以随机访问”
  • @Peter 感谢您的评论,一旦我理解了堆栈对齐的目的,我就明白了。我需要一个实际的原因,我有一个。
  • @x4rkz:“随机访问”:您最初可以将 push 本地人放到堆栈中。一旦它们在那里,您将通过它们从esp 的偏移量访问它们,而不是使用pop。推送它们将是针对特殊情况的微优化,-O0 肯定无法做到这一点。此外,push 将使下一个mov eax, [esp + 1c] 变慢,因为堆栈引擎将必须插入一个额外的微指令以将esp 与堆栈引擎的内部偏移量同步。 (agner.org/optimize)。由于main 已经将espand 指令一起使用,因此该价格已经支付,因此push 有一点成本。
猜你喜欢
  • 2012-11-27
  • 2018-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 2019-11-30
相关资源
最近更新 更多