c语言函数调用详细过程

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

作者: Badcoffee

Email: *********************

2004年10月

原文出处: /yayong

这是作者在学习X86汇编过程中的学习笔记,难免有错误和疏漏之处,欢迎指正。

1. 编译环境

OS: Axianux 1.0

Compiler: gcc 3..2.3

Linker: Solaris Link Editors 5.x

Debug Tool: gdb

Editor: vi

2. 最简C代码分析

为简化问题,来分析一下最简的c代码生成的汇编代码:

# vi test1.c

int main()

{

return 0;

}

编译该程序,产生二进制文件:

# gcc -o start start.c

# file start

start: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), not stripped start是一个ELF格式32位小端(Little Endian)的可执行文件,动态链接并且符号表没有去除。这正是Unix/Linux平台典型的可执行文件格式。

用gdb反汇编可以观察生成的汇编代码:

[wqf@15h166 attack]$ gdb start

GNU gdb Asianux (6.0post-0.20040223.17.1AX)

Copyright 2004 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB. Type "show warranty" for details.

This GDB was configured as "i386-asianux-linux-gnu"...(no debugging symbols found)ing host libthread_db library

"/lib/tls/libthread_db.so.1".

(gdb) disassemble main --->反汇编main函数

Dump of assembler code for function main:

0x08048310 : push %ebp --->ebp寄存器内容压栈,

即保存main函数的上级调用

函数的栈基地址

0x08048311 : mov %esp,%ebp---> esp值赋给ebp,

设置main函数的栈基址

0x08048313 : sub $0x8,%esp --->通过ESP-8来分

配8字节堆栈空间

0x08048316 : and $0xfffffff0,%esp --->使栈地址16

字节对齐

0x08048319 : mov $0x0,%eax ---> 无意义

0x0804831e : sub %eax,%esp ---> 无意义

0x08048320 : mov $0x0,%eax ---> 设置函数返回值0

0x08048325 : leave --->将ebp值赋给esp,pop先

前栈内的上级函数栈的基地址给

ebp,恢复原栈基址.

0x08048326 : ret ---> main函数返回,回到上级调用.

0x08048327 : nop

End of assembler dump.

注:这里得到的汇编语言语法格式与Intel的手册有很大不同,Unix/Linux采用AT&T汇编格式作为汇编语言的语法格式,如果想了解AT&T汇编可以参考文章Linux 汇编语言开发指南.

问题一:谁调用了 main函数?

在C语言的层面来看,main函数是一个程序的起始入口点,而实际上,ELF 可执行文件的入口点并不是main而是_start。

gdb也可以反汇编_start:

(gdb)disass _start --->从_start的地址开始反汇编

Dump of assembler code for function _start:

0x08048264 <_start+0>: xor %ebp,%ebp

0x08048266 <_start+2>: pop %esi

0x08048267 <_start+3>: mov %esp,%ecx

0x08048269 <_start+5>: and $0xfffffff0,%esp

0x0804826c <_start+8>: push %eax

0x0804826d <_start+9>: push %esp

0x0804826e <_start+10>: push %edx

0x0804826f <_start+11>: push $0x8048370

0x08048274 <_start+16>: push $0x8048328

0x08048279 <_start+21>: push %ecx

0x0804827a <_start+22>: push %esi

0x0804827b <_start+23>: push $0x8048310

0x08048280 <_start+28>: call 0x8048254 <__libc_start_main>

相关文档
最新文档