10 c assembly stack gdb disassembly
我正在分析X86_64上GDB中以下(非常简单的)C程序的反汇编.
int main()
{
int a = 5;
int b = a + 6;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
据我所知,在X86_64中,堆栈会逐渐减少.这是堆栈顶部的地址低于堆栈底部的地址.上述程序的汇编程序如下:
Dump of assembler code for function main:
0x0000000000400474 <+0>: push %rbp
0x0000000000400475 <+1>: mov %rsp,%rbp
0x0000000000400478 <+4>: movl $0x5,-0x8(%rbp)
0x000000000040047f <+11>: mov -0x8(%rbp),%eax
0x0000000000400482 <+14>: add $0x6,%eax
0x0000000000400485 <+17>: mov %eax,-0x4(%rbp)
0x0000000000400488 <+20>: mov $0x0,%eax
0x000000000040048d <+25>: leaveq
0x000000000040048e <+26>: retq
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)
我明白那个:
-0x8(%rbp).因为在int中是4个字节,所以不应该在堆栈中的下一个地址-0x4(%rbp)而不是-0x8(%rbp)?.a到%eax,添加6,然后将值复制到地址中-0x4(%rbp).使用此图形作为参考:
http://eli.thegreenplace.net/images/2011/08/x64_frame_nonleaf.png
它看起来像堆栈具有以下内容:
|--------------|
| rbp | <-- %rbp
| 11 | <-- -0x4(%rbp)
| 5 | <-- -0x8(%rbp)
Run Code Online (Sandbox Code Playgroud)
当我期待这个:
|--------------|
| rbp | <-- %rbp
| 5 | <-- -0x4(%rbp)
| 11 | <-- -0x8(%rbp)
Run Code Online (Sandbox Code Playgroud)
这似乎是7-understanding-c-by-learning-assembly的情况,他们展示了大会:
(gdb) disassemble
Dump of assembler code for function main:
0x0000000100000f50 <main+0>: push %rbp
0x0000000100000f51 <main+1>: mov %rsp,%rbp
0x0000000100000f54 <main+4>: mov $0x0,%eax
0x0000000100000f59 <main+9>: movl $0x0,-0x4(%rbp)
0x0000000100000f60 <main+16>: movl $0x5,-0x8(%rbp)
0x0000000100000f67 <main+23>: mov -0x8(%rbp),%ecx
0x0000000100000f6a <main+26>: add $0x6,%ecx
0x0000000100000f70 <main+32>: mov %ecx,-0xc(%rbp)
0x0000000100000f73 <main+35>: pop %rbp
0x0000000100000f74 <main+36>: retq
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)
为什么值b被放入堆栈中的一个更高的内存地址比a当a被明确宣布,并首先初始化?
b无论编译器感觉如何,都将值放在堆栈上.你没有影响力.你不应该.订单可能会在编译器的次要版本之间发生变化,因为某些内部数据结构已更改或某些代码已重新排列.有些编译器甚至会故意在不同的编译中随机化堆栈的布局,因为它可能会使某些错误难以利用.
实际上,编译器可能根本不使用堆栈.没有必要.这是在启用了一些优化的情况下编译的同一程序的反汇编:
$ cat > foo.c
int main()
{
int a = 5;
int b = a + 6;
return 0;
}
$ cc -O -c foo.c
$ objdump -S foo.o
foo.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: 31 c0 xor %eax,%eax
2: c3 retq
$
Run Code Online (Sandbox Code Playgroud)
通过一些简单的优化,编译器发现你不使用变量'b',所以不需要计算它.因此你不使用变量'a',所以不需要分配它.只有没有优化的编译(或非常糟糕的编译器)才会在此处放置任何内容.即使您使用这些值,基本优化也会将它们放入寄存器中,因为触摸堆栈非常昂贵.
| 归档时间: |
|
| 查看次数: |
494 次 |
| 最近记录: |