我刚刚在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
158
而不是将值推入堆栈并调用strcmp
方法的汇编代码?是因为它不依赖于任何用户输入吗? extended assembly
(我不确定这是不是正确的术语,我只是希望看到用于将值推送到堆栈和调用strcmp函数的汇编代码) 。我有什么方法可以做到吗?答案 0 :(得分:10)
首先,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
答案 1 :(得分:4)
关于sub esp,0x158
指令,而不是生成一堆push
操作(涉及将操作数复制到堆栈中,而不仅仅是保留空间),通常编译器将保留足够的空间用于通过仅移动堆栈指针一次所有局部变量。这就是这条指令正在做的事情。 0x158
是十进制的344,所以它为数组保留了300个字节,并且可能为编译器生成的结构留出了一些额外的空间(或者也可能将strcmp操作数放在堆栈上)。
答案 2 :(得分:4)
因为您的代码对程序执行没有影响。所有变量都在函数调用中使用,其返回值被丢弃,因此编译器将其标记为未使用的代码,并认为它应该删除。如果您想保留未使用的代码,请确保您没有使用任何优化 - 使用-O0
进行编译。
请参阅上面的观点。
我怀疑大多数编译器会执行此优化,而不依赖于架构。
答案 3 :(得分:0)
它似乎确实已经过优化。您可以尝试使用-O0标志进行编译,以确保不进行优化(但我不确定它是否可行)。
或者您可以从start函数返回cmp结果,以显示您真正使用它们的编译器:
int start() {
char phone[] = "43423432";
return strcmp(phone, "12312312313");
}