堆栈中奇怪的指针位置
Strange pointer position in the stack
我写了这个简单的代码:
#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
;对齐?(如果是这样,为什么不使用 nop
)。
P.S 我知道这是将 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]
(rbp-0x10 + 0x8 == rbp-0x8
)
我写了这个简单的代码:
#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
;对齐?(如果是这样,为什么不使用 nop
)。
P.S 我知道这是将 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]
(rbp-0x10 + 0x8 == rbp-0x8
)