【发布时间】:2017-04-03 17:17:17
【问题描述】:
我写了这个简单的代码:
#include <stdio.h>
void ok(){}
int main()
{
int k=1;
int l=1337;
int *p;
p=NULL;
p=&k;
ok();
}
我已经反汇编了它,看看编译器做了什么。 使用 objdump 我获得:
0000000000400546 <main>:
400546: 55 push rbp
400547: 48 89 e5 mov rbp,rsp
40054a: 48 83 ec 20 sub rsp,0x20
40054e: 64 48 8b 04 25 28 00 mov rax,QWORD PTR fs:0x28
400555: 00 00
400557: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax
40055b: 31 c0 xor eax,eax
40055d: c7 45 e8 01 00 00 00 mov DWORD PTR [rbp-0x18],0x1
400564: c7 45 ec 39 05 00 00 mov DWORD PTR [rbp-0x14],0x539
40056b: 48 c7 45 f0 00 00 00 mov QWORD PTR [rbp-0x10],0x0
400572: 00
400573: 48 8d 45 e8 lea rax,[rbp-0x18]
400577: 48 89 45 f0 mov QWORD PTR [rbp-0x10],rax
40057b: b8 00 00 00 00 mov eax,0x0
400580: 48 8b 55 f8 mov rdx,QWORD PTR [rbp-0x8]
400584: 64 48 33 14 25 28 00 xor rdx,QWORD PTR fs:0x28
40058b: 00 00
40058d: 74 05 je 400594 <main+0x4e>
40058f: e8 8c fe ff ff call 400420 <__stack_chk_fail@plt>
400594: c9 leave
400595: c3 ret
400596: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
40059d: 00 00 00
我可以理解除了mov QWORD PTR [rbp-0x10],0x0 之外的所有内容,这对应于(我认为)p=NULL;,但从mov QWORD PTR [rbp-0x8],rax 我知道我的指针在rbp-0x8 上并且看起来是正确的(指针的大小是8 字节)。
那么为什么在rbp-0x10 上调用mov QWORD PTR [rbp-0x10],0x0?
我也不知道为什么会调用xor eax,eax;对齐?(如果是这样,为什么不使用nop)。
P.S 我知道这是将 eax 设置为零,但为什么呢?
【问题讨论】:
-
您的指针“p”实际上位于
[rbp-0x10]- 有关[rbp-0x8]的用途的更多信息,请参阅stackoverflow.com/questions/14414763/…(特别是紧接在其前面的mov rax,QWORD PTR fs:0x28)。跨度> -
不要假设,您可以在 objdump 输出中将程序集与源代码混合在一起。使用调试信息编译:
gcc -g file.c并运行objdump -S a.out或objdump --source a.out
标签: c linux gcc x86-64 disassembly