lit*_*3rd 5 c assembly gcc gdb ubuntu-14.04
我糊涂了.我在main函数中声明了一个变量,在另一个函数中声明了另一个变量.但是在gdb中,我发现程序main通过%esp寄存器访问函数中的变量,并通过寄存器访问另一个函数中的变量%ebp.不应该全部被%ebp功能访问?或者这是一个隐藏的规则,通过%esp注册访问main,我不知道?
/* source_file.c */
#include <stdio.h>
void localfunc(void)
{
int local_in_func;
local_in_func = 0x21;
printf("local_in_func = %d\n", local_in_func);
}
int main(int argc, char **argv)
{
int local_in_main;
local_in_main = 0x97;
printf("local_in_main = %d\n", local_in_main);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它的反汇编代码如下:
(gdb) disassemble main
Dump of assembler code for function main:
0x08048407 <+0>: push %ebp
0x08048408 <+1>: mov %esp,%ebp
0x0804840a <+3>: and $0xfffffff0,%esp ; visit local_in_main by esp
0x0804840d <+6>: sub $0x20,%esp
0x08048410 <+9>: movl $0x97,0x1c(%esp)
0x08048418 <+17>: mov $0x8048524,%eax
0x0804841d <+22>: mov 0x1c(%esp),%edx
0x08048421 <+26>: mov %edx,0x4(%esp)
0x08048425 <+30>: mov %eax,(%esp)
0x08048428 <+33>: call 0x8048300 <printf@plt>
0x0804842d <+38>: mov $0x0,%eax
0x08048432 <+43>: leave
0x08048433 <+44>: ret
End of assembler dump.
(gdb) disassemble localfunc
Dump of assembler code for function localfunc:
0x080483e4 <+0>: push %ebp
0x080483e5 <+1>: mov %esp,%ebp
0x080483e7 <+3>: sub $0x28,%esp
0x080483ea <+6>: movl $0x21,-0xc(%ebp) ; visit local_in_func by ebp
0x080483f1 <+13>: mov $0x8048510,%eax
0x080483f6 <+18>: mov -0xc(%ebp),%edx
0x080483f9 <+21>: mov %edx,0x4(%esp)
0x080483fd <+25>: mov %eax,(%esp)
0x08048400 <+28>: call 0x8048300 <printf@plt>
0x08048405 <+33>: leave
0x08048406 <+34>: ret
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)
我的工具是:
操作系统:ubuntu 12.04
编译:gcc版本4.6.3(Ubuntu/Linaro 4.6.3-1ubuntu5)
debug:GNU gdb(Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1)7.4-2012.04
通常,%esp是堆栈指针并且%ebp是"基本"指针,它通常设置为堆栈指针在函数开始处的位置.
函数通过将局部变量推送到堆栈上,使用直接push或逻辑等效的方法来减去偏移量,%esp并访问旧%esp(ie %ebp)和new 之间的空间%esp.
这可以通过正偏移%esp(例如via 0x1c(%esp)in main)或通过负偏移%ebp(例如-0xc(%ebp)在`local_function1中)来完成.尽管编译器在多种方式之间进行选择以获得相同的东西,但是没有逻辑差异.
由于你的代码没有经过优化,我不会在选择中给予太多的重视,它可能是启发式的结果,在其他情况下有一些影响,但我不希望它在这里有很大的不同.