c语言函数调用详细过程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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
即保存main函数的上级调用
函数的栈基地址
0x08048311
设置main函数的栈基址
0x08048313
配8字节堆栈空间
0x08048316
字节对齐
0x08048319
0x0804831e
0x08048320
0x08048325
前栈内的上级函数栈的基地址给
ebp,恢复原栈基址.
0x08048326
0x08048327
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>