繁体   English   中英

gcc堆栈优化?

[英]gcc stack optimization?

我刚刚在C中编写了一个代码示例,并尝试将其拆解。 以下是代码示例。

void start() {
    char phone[100];
    strcmp(phone, "12312312313");

    char name[100];
    strcmp(name, "eQuiNoX");

    char contact[100];
    strcmp(contact, "PM twitter.com/eQuiNoX__");
}

当我反汇编启动功能时,我得到以下内容: -

08048414 <start>:
 8048414: 55                    push   ebp
 8048415: 89 e5                 mov    ebp,esp
 8048417: 81 ec 58 01 00 00     sub    esp,0x158
 804841d: c9                    leave  
 804841e: c3                    ret   
  1. 我没有启用任何类型的优化。 有人可以解释为什么我从esp中减去158而不是将值推入堆栈并调用strcmp方法的汇编代码吗? 是因为它不依赖于任何用户输入吗?
  2. 另外,有什么方法可以生成extended assembly (我不确定这是否是正确的术语,我只是希望看到用于将值推送到堆栈和调用strcmp函数的汇编代码)。 有什么办法可以吗?
  3. 这种行为是特定于处理器体系结构还是gcc版本或两者兼有?

首先, strcmp是一个标准的库函数,因此gcc可以自由地了解它的工作原理。 事实上,它确实; 它很少会产生库调用。 您可以尝试-fno-builtin来禁用。

其次,您要与单位化值进行比较。 这是,我相信未定义的行为。 因此编译器可以做任何事情,包括生成随机代码。

您可以尝试使用-S选项来获取更详细的反汇编(或者更确切地说,缺少汇编); 或者,如果使用-g (调试)进行编译,则objdump -S将显示源以及汇编代码。

这是我用gcc -fno-builtin -g -O0 test.c -c编译的一个例子,然后用objdump -S test.o转储:

test.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
#include <string.h>

int main() {
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 10             sub    $0x10,%rsp
    const char foo[] = "foo";
   8:   8b 05 00 00 00 00       mov    0x0(%rip),%eax        # e <main+0xe>
   e:   89 45 f0                mov    %eax,-0x10(%rbp)
    return strcmp(foo, "bar");
  11:   48 8d 45 f0             lea    -0x10(%rbp),%rax
  15:   be 00 00 00 00          mov    $0x0,%esi
  1a:   48 89 c7                mov    %rax,%rdi
  1d:   e8 00 00 00 00          callq  22 <main+0x22>
}
  22:   c9                      leaveq 
  23:   c3                      retq   

关于sub esp,0x158指令,而不是生成sub esp,0x158 push操作(包括将操作数复制到堆栈,而不仅仅是保留空间),通常编译器将通过移动堆栈指针为所有局部变量保留足够的空间就一次。 这就是这条指令正在做的事情。 0x158是十进制的344,因此它为数组保留了300个字节,并且可能为编译器生成的结构留出了一些额外的空间(或者也可能将strcmp操作数放在堆栈上)。

  1. 因为您的代码对程序执行没有影响。 所有变量都在函数调用中使用,其返回值被丢弃,因此编译器将其标记为未使用的代码,并认为它应该删除。 如果你想保留未使用的代码,请确保你没有使用任何优化 - 使用-O0编译。

  2. 看到我的观点。

  3. 我怀疑大多数编译器会执行此优化,而不依赖于体系结构。

它似乎真的被优化了。 您可以尝试使用-O0标志进行编译,以确保不进行任何优化(但我不确定它是否可行)。

或者你可以从start函数返回cmp结果,以显示你真正使用它们的编译器:

int start() {
    char phone[] = "43423432";
    return strcmp(phone, "12312312313");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM