【问题标题】:assembler code of my C function我的 C 函数的汇编代码
【发布时间】:2014-11-30 01:28:02
【问题描述】:

这是我的 C 函数:

int reg(struct my_callback_struct *p, int data)
{
   return p->data = data;
}

这在汇编中也是一样的:

0x000000000040057d <+0>:  push   %rbp
0x000000000040057e <+1>:  mov    %rsp,%rbp
0x0000000000400581 <+4>:  mov    %rdi,-0x8(%rbp)
0x0000000000400585 <+8>:  mov    %esi,-0xc(%rbp)
0x0000000000400588 <+11>: mov    -0x8(%rbp),%rax
0x000000000040058c <+15>: mov    -0xc(%rbp),%edx
0x000000000040058f <+18>: mov    %edx,(%rax)
0x0000000000400591 <+20>: mov    -0x8(%rbp),%rax
0x0000000000400595 <+24>: mov    (%rax),%eax
0x0000000000400597 <+26>: pop    %rbp
0x0000000000400598 <+27>: retq

我想我明白发生了什么。 $rdi 持有指针(地址),$esi 持有数字 12。

这就是我调用函数的方式:

p->callback_func(p,12);

我不明白的是:

0x0000000000400591 <+20>: mov -0x8(%rbp),%rax

因为在&lt;+11&gt; 上,我们已经用指针地址填充了$rax。为什么要加载两次?

【问题讨论】:

  • 通常的原因是人们忘记开启优化,所以编译器生成的代码效率低。
  • 您应该确定这是汇编程序的哪个亚种。看起来它可能是针对英特尔 x86_64 系列芯片的,但这样说是明智的。不同的汇编器也使用不同的符号——识别您正在使用的汇编器/编译器以及您使用它的平台也可能是相关的。
  • gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2; x86_64
  • gcc -O -fverbose-asm -S编译

标签: c assembly x86-64


【解决方案1】:

确实,代码是正确的,因为指令执行了 C 代码调用的功能。但即使是最微不足道的优化也没有执行。

这很容易通过开启某种程度的编译器优化来纠正。无论使用哪种编译器,第一级可能都会清理多余的负载。

请注意,极端程度的优化可能会导致正确的代码非常难以遵循。

【讨论】:

  • 好吧,如果是这个原因,现在我明白了;-)
猜你喜欢
  • 1970-01-01
  • 2015-04-27
  • 1970-01-01
  • 2016-09-03
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
  • 2021-07-18
相关资源
最近更新 更多