【问题标题】:different assembly instructions from gcc2.9 to 5.3从 gcc2.9 到 5.3 的不同汇编指令
【发布时间】:2016-05-11 12:23:08
【问题描述】:

我有以下 C 代码:

#include <stdio.h>

void function(int a, int b, int c) {
  int buff_1[5];
  int buff_2[10];

  buff_1[0] = 6;
  buff_2[0] = 'A';
  buff_2[1] = 'B';
}

int main(void) {
  int i = 1;
  function(1,2,3);
  return 0;
}

现在我要分析相关的汇编代码: 根据我正在阅读的书,函数调用之前的汇编指令是:

pushl $3
pushl $2
pushl $1
call function

底层对象文件是使用gcc-5.3 -O0 -c functions.c 创建的。 但是,如果我使用 objdump 创建汇编代码,我会收到以下说明:

movl $3, %edx
movl $2, %esi
movl $1, %edi

据我了解汇编(我对它很陌生),第一个对我来说更有意义。

这本书是不是完全错了?或者是因为使用gcc 2.9而导致书籍输出过时了

【问题讨论】:

  • gcc 是否有特定的中间表示或字节码?您的第二个示例看起来像目标特定程序集。 IE。不是每个处理器都会有这些寄存器,那些是 x86 特定的(我可能错了,我通常不处理低级的东西)。此外,可能是一种优化并没有全部被“-O0”关闭,构造函数省略是我知道的不是。可能相关:stackoverflow.com/questions/4534791/…
  • 这只是一个不同的调用约定——在寄存器中而不是在堆栈中传递前 N 个参数。但是,使用这些寄存器不是我认可的惯例,the Wikipedia page 也不是。这是 64 位电脑吗?尝试使用-m32 编译可能会得到 32 位约定,我认为默认情况下是堆栈。
  • 它只是使用 x86_64 调用约定,使用寄存器 RDI、RSI 和 RDX 的下半部分(它们是 x86_64 调用约定中的前 3 个寄存器)
  • "这是转贴:为什么它使用 movl 而不是 push?" - 不,这不对。该问题涉及 GCC 3.x 通过保留一些空间然后写入该空间而不是使用推送指令将参数推送到堆栈的方式。 David 是正确的:这是因为您正在编译 64 位代码,这是标准的 64 位 Linux 调用约定。尝试-m32 来获得看起来像你的书的 32 位代码,或者至少像链接问题中的代码,这相当于你书中的代码(这部分是 gcc 2.95 与更现代的 GCC)。跨度>
  • GCC 2.95.X Releases 发生在 1999 年 7 月 - 2001 年 3 月,并且已经过时了。 x86_64 那时还处于起步阶段。请参阅x86_64,因此看起来代码生成是使用 x86_64 调用约定来描述的,但要么使用寄存器的下半部分——要么只是错误地使用了 x86 寄存器名称。学习历史没有错,但是如果您打算使用当前代码,则需要更多更新的参考。

标签: c gcc assembly


【解决方案1】:

这本书在 64 位 x86 方面已经过时了。维基百科的x86-64 calling conventions 是:

System V AMD64 ABI

Solaris、Linux、FreeBSD、OS X 和其他类 UNIX 或 POSIX 兼容的操作系统遵循 System V AMD64 ABI 的调用约定。前六个整数或指针参数在寄存器 RDI、RSI、RDX、RCX(Linux 内核接口中的 R10)、R8 和 R9 中传递,而使用 XMM0、XMM1、XMM2、XMM3、XMM4、XMM5、XMM6 和 XMM7对于某些浮点参数。与 Microsoft x64 调用约定一样,附加参数在堆栈上传递,返回值存储在 RAX 中。

由于您要传递 32 位值,gcc 使用每个寄存器的下半部分,因此 %edi%esi%edx

【讨论】:

  • 次要补充:它实际上是使用整个寄存器(%rdi%rsi,...)。移入 32 位 GP 寄存器零扩展到整个 64 位寄存器。这些指令是执行mov $3, %rdx 等的有效方法。
  • @MargaretBloom:明白了。我通常不会在这个级别上工作,所以我不知道所有的细微差别。如果您认为有必要,请随时编辑答案。
猜你喜欢
  • 2015-12-03
  • 2012-07-05
  • 1970-01-01
  • 2018-05-31
  • 1970-01-01
  • 1970-01-01
  • 2012-02-27
  • 2011-11-22
  • 2016-04-21
相关资源
最近更新 更多