文档介绍:c语言函数调用过程图解c语言函数调用过程
c语言函数你知道多少?它的调用过程你了解吗?下面xx为大家介绍一下c语言函数,期望对你有帮助。
c语言函数编译环境
OS:Axianux
Compiler:gcc3..
Linker:SolarisLinkEditors
DebugTool:gdb
Editor:vi
c语言函数最简C代码分析
为简化问题,来分析一下最简的c代码生成的汇编代码:
#vi
intmain
{
return0;
}
编译该程序,产生二进制文件:
#gcc-ostart
#filestart
start:ELF32-bitLSBexecutable,Intel80386,version1(SYSV),forGNU/Linux,dynamicallylinked(usessharedlibs),notstripped
start是一个ELF格式32位小端(LittleEndian)的可实施文件,动态链接而且符号表没有去除。这正是Unix/Linux平台经典的可实施文件格式。
用gdb反汇编能够观察生成的汇编代码:
******@15h166attack$gdbstart
GNUgdbAsianux
Copyright2021FreeSoftwareFoundation,Inc.
GDBisfreesoftware,coveredbytheGNUGeneralPublicLicense,andyouarewelcometochangeitand/ordistributecopiesofitundercertainconditions.
Type"showcopying"toseetheconditions.
"showwarranty"fordetails.
ThisGDBwasconfiguredas"i386-asianux-linux-gnu"...(nodebuggingsymbolsfound)...Usinghostlibthread_dblibrary"/lib/tls/libthread_".
(gdb)disassemblemain--->反汇编main函数
Dumpofassemblercodeforfunctionmain:
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
Endofassemblerdump.
注:这里得到的汇编语言语法格式和Intel的手册有很大不一样,Unix/Linux采取AT&T汇编格式作为汇编语言的语法格式,假如想了解AT&T汇编能够参考文章Linux汇编语言开发指南.
问题一:谁调用了main函数?
在C语言的层面来看,main函数是一个程序的起始入口点,而实际上,ELF可实施文件的入口点并不是main而是_start。
gdb也能够反汇编_start:
(gdb)disass_start--->从_start的地址开始反汇编
Dumpofassemblercodeforfunction_start:
0x08048264:xor%ebp,%ebp
0x08048266:pop%esi
0x08048267:mov%esp,%ecx
0x08048269:and$0xfffffff0,%esp
0x0804826c:push%eax
0x0804826d:push%esp
0x0804826e:push%