我写了一个简单的C程序,并试图使用GDB来debugging程序。 我明白在主要function中使用以下内容:
在进入
push %ebp mov %esp,%ebp
退出时
leave ret
然后我尝试gdb的_start,我得到了以下
xor %ebp,%ebp pop %esi mov %esp,%ecx and $0xfffffff0,%esp push %eax push %esp push %edx push $0x80484d0 push $0x8048470 push %ecx push %esi push $0x8048414 call 0x8048328 <__libc_start_main@plt> hlt nop nop nop nop
我无法理解这些线,以及这背后的逻辑。
有人可以提供任何指导,以帮助解释_start
的代码?
以下是您发布代码的评论汇编源代码。
总结起来,它做了以下几件事情:
esi
以便将它们传递给__libc_start_main
__libc_csu_fini
, __libc_csu_init
,参数向量,参数个数和main
地址的地址作为参数推送到__libc_start_main
__libc_start_main
被调用。 这个函数(源代码在这里 )设置了一些glibc内部的变量,并最终调用main
函数。 它永远不会返回。 __libc_start_main
应该返回,那么之后__libc_start_main
指令。 这个指令在用户代码中是不允许的,并且会导致程序崩溃(希望)。 nop
指令是由汇编程序插入的填充,所以下一个函数以16字节的倍数开始,以获得更好的性能。 正常执行中永远不会达到。 对于gnu工具,_start标签是程序的入口点。 为了使C语言正常工作,你需要有一个堆栈,你需要有一些内存/变量归零,有些设置为你选择的值:
int x = 5; int y; int fun ( void ) { static int z; }
所有这三个变量x,y,z基本上是全局的,一个是局部全局的。 因为我们这样写,所以我们假设当我们的程序开始时x包含值5,并且假定y是零。 为了发生这些事情,需要一些引导代码,这就是(_start和main()之间发生的事情)。
其他工具链可以选择使用不同的标签来定义入口/起点,但是GNU工具使用_start。 在调用main()之前,你的工具可能需要其他的东西,例如C ++需要C