我写了这么简单的代码:
#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字节)。那么为什么在
mov QWORD PTR [rbp-0x10],0x0
上调用rbp-0x10
?我也不知道为什么要调用
xor eax,eax
;用于allignment?(如果是,为什么不使用nop
)。我知道这是把eax设为零,但为什么?
最佳答案
从这些线
6 int k=1;
7 int l=1337;
8 int *p;
9 p=NULL;
10 p=&k;
很明显,这些汇编程序指令与
6 int k=1;
40055d: c7 45 e8 01 00 00 00 mov DWORD PTR [rbp-0x18],0x1
7 int l=1337;
400564: c7 45 ec 39 05 00 00 mov DWORD PTR [rbp-0x14],0x539
9 p=NULL;
40056b: 48 c7 45 f0 00 00 00 mov QWORD PTR [rbp-0x10],0x0
400572: 00
10 p=&k;
400573: 48 8d 45 e8 lea rax,[rbp-0x18]
400577: 48 89 45 f0 mov QWORD PTR [rbp-0x10],rax
因此,局部变量
p
被放置在[rbp-0x10]
处,并且从QWORD
开始到[rbp-0x10]
([rbp-0x8]
)关于c - 堆栈中奇怪的指针位置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43190621/