当前位置:网站首页>X86 function call model analysis
X86 function call model analysis
2022-08-03 19:03:00 【mingjie】
相关: 《Postgresql中的pg_memory_barrier_impl和C的volatile》《X86Function call model analysis》
函数A调用函数B,BContinue to execute the function after executionA,How to implement such a call?
Direct thinking may involve the following steps:
- AThe local variables if in registers,需要保存起来.
- These variables are kept on the stack,The position on the stack needs to be recorded.
- If there are multiple layers of calls, there will be multiple sets of information to record the stack location,Records are also required.
- A调用完BNeed to continue after that,The position to continue execution needs to be saved.
下面分析x86的具体实现. (资料汇编)
速查:
- For stack frames:Used at the top of the stack framebp指针(高地址),栈帧底部(低地址)用sp指针.
- 对于堆栈来说:The top of the overall stack is sp指针(The lowest address to which the stack grows).
一、内存结构
The memory structure of the binary program execution time:
- code section:The machine code that holds the program execution instructions.
- static section:Constants and static variables that do not change during program execution.
- heap:使用malloc申请的堆内存,向Memory addresses grow in ascending order:grows up.
- stack:Holds control information for function local variables and function calls,向Memory addresses grow in descending order:grows down.
二、寄存器
- The program's virtual memory space is provided
space to save data,地址从0x00000000到0xFFFFFFFF(A hexadecimal for the corresponding4个二进制位,所以是2的32次方).
- Registers provide additional storage space,Each register can hold one word(4字节).
Registers associated with function calls(emeans to expand):
- eip:指令指针,Stores the address of the currently executing machine instruction.也叫PC(程序计数器).
- ebp:帧指针,Save the top address of the current stack frame(高地址).
- esp:堆栈指针,Save the current stack bottom address(低地址).
The diagram below is easy to understand:
|----------------------| high address
| ... |
|-------frame----------|
| ... |
| ... |
| ... |
|-------frame----------| # current frame <----- ebp
| ... |
| ... |
| ... | <----- esp
|----------------------| low address三、x86函数调用
- when another function needs to be called,Stack space needs to grow,Used to save some local variables 或者 寄存器信息.
- when calling a function happens,callerThe execution logic will jump tocallee,拿到结果后,In the jump willcaller.This requires changing the values of the following registers:
- eip指令指针,Need to be changed to point tocallee的指令.
- ebp 和 esp currently point to respectivelycallerThe top and bottom of the stack frame.Both registers need to be updated as 指向calleeThe top and bottom of the new stack frame.
- 当函数返回时,The old value in the register needs to be restored,才可以返回caller.So update the value of the register,It needs to save its old value on the stack,in order to restore the old value after the function returns.
下面是main调用foo的执行过程:
step0
step1:参数入栈
将参数压入堆栈. x86Pass parameters by pushing them on the stack.请注意,When we push parameters onto the stack,esp 会递减.Arguments are pushed onto the stack in reverse order.(上面是高地址)
step2:旧的eip入栈
旧的eip(rip)压入堆栈.Jump to subfunction executioneipNeed to point to subfunction,So save it here.
step3:修改eip指向
已经保存了 eip 的旧值,可以安全地将 eip Change to point to becallee的指令.
step4:将旧的ebp入栈
step5:ebpMove down to point to the top of the new stack frame
这就是mov %esp %ebp的含义:
step6:esp向下移动
通过sub esp(esp地址–) to allocate new space for the new stack frame.The compiler determines based on the complexity of the function esp How much should be reduced.
- 例如,A function with only a few local variables doesn't need much stack space,因此 esp It will only reduce a few bytes.
- 例如,If a function declares a large array as a local variable,那么 esp would reduce a lot to fit the array on the stack.
step7:执行callee
The function's local variables and jump control information are now stored on the stack;由于ebp指向栈帧的顶部,所以可以用ebp+8Find where the first parameter is saved.
step8:返回espback to the top of the stack
step9:恢复旧的ebp
使用esp从堆栈中pop出一个值(old ebp),把old ebp的值赋给ebp.
step10:弹出eip
继续使用esp弹出old eip的值赋给eip.
step11:Remove the parameter from the stack
Continue talking about popping parameters on the stack into registers,然后删除espThe element below the top of the stack.Elements below the top of the stack are no longer on the stack,没有意义.
四、实例分析
int main(void) {
foo(1, 2);
}
void foo(int a, int b) {
int bar[4];
}
gcc -O0 t.c -o t -gmain执行过程
(gdb) disassemble /rm
Dump of assembler code for function main:
3 int main(void) {
# 由_start调入main函数
0x0000000000401122 <+0>: 55 push %rbp # The top of the stack frame is pushed onto the stack
0x0000000000401123 <+1>: 48 89 e5 mov %rsp,%rbp # Pointer to the top of the stack framerbpPoints to the top of the new stack frame
4 foo(1, 2);
=> 0x0000000000401126 <+4>: be 02 00 00 00 mov $0x2,%esi # 参数1passed into the register
0x000000000040112b <+9>: bf 01 00 00 00 mov $0x1,%edi # 参数2passed into the register
0x0000000000401130 <+14>: e8 07 00 00 00 callq 0x40113c <foo> # push %rip 然后 jmpq
# push %rip 等价与 sub $0x8, %rsp
# mov $rip, %rsp
0x0000000000401135 <+19>: b8 00 00 00 00 mov $0x0,%eax
5 }
0x000000000040113a <+24>: 5d pop %rbp # 先恢复rbp的值
0x000000000040113b <+25>: c3 retq # 在恢复rip的值 popq %rip
End of assembler dump.foo函数
(gdb) disassemble /rm
Dump of assembler code for function foo:
7 void foo(int a, int b) {
0x000000000040113c <+0>: 55 push %rbp # Frame top position 入栈
0x000000000040113d <+1>: 48 89 e5 mov %rsp,%rbp # rbpframe top pointer,Point to the top of the new frame
0x0000000000401140 <+4>: 89 7d ec mov %edi,-0x14(%rbp) # 参数2入栈(Push the last parameter onto the stack first)
0x0000000000401143 <+7>: 89 75 e8 mov %esi,-0x18(%rbp) # 参数1入栈
8 int bar[4];
9 }
=> 0x0000000000401146 <+10>: 90 nop
0x0000000000401147 <+11>: 5d pop %rbp # 先恢复rbp的值
0x0000000000401148 <+12>: c3 retq # 在恢复rip的值 popq %rip
End of assembler dump.边栏推荐
- Postgresql快照优化Globalvis新体系分析(性能大幅增强)
- Brush the topic of mobile zero power button
- 【微信小程序】NFC 标签打开小程序
- 国产虚拟化云宏CNware WinStack安装体验-5 开启集群HA
- MySQL【变量、流程控制与游标】
- Shell:循环语句
- 首届MogDB征文活动开启啦!
- Zhong Hua, senior architect of Ali: China-Taiwan strategic thinking and architecture practice; including internal implementation manual
- 阿里二面:多线程间的通信方式有几种?举例说明
- 字节跳动三面拿offer:网络+IO+redis+JVM+GC+红黑树+数据结构,助你快速进大厂!!
猜你喜欢

online 方式创建索引触发trigger怎么办?

PHP base notes - NO. 1

盲僧发现了华点——教你如何使用API接口获取数据

谷歌浏览器安装插件教程步骤,开发用这2个插件工作效率倍增
![[笔记]机器学习之前言介绍](/img/69/e2acd3efd5f513c9c32fca701b66c0.png)
[笔记]机器学习之前言介绍

懵逼!阿里一面被虐了,幸获内推华为技术四面,成功拿到offer,年薪40w

awk语法-02-运算、数组、格式化输出

ctfshow php特性

Don't look down upon the WebSocket!Long connection, stateful, two-way, full-duplex king is Fried

Protobuf Grpc使用异常 类型有未导出的方法,并且是在不同的软件包中定义
随机推荐
Shell:循环语句
awk语法-02-运算、数组、格式化输出
mysql跨库关联查询(dblink)
力扣刷题之爬楼梯(7/30)
if/else或switch替换为Enum
丙二醇二乙酸酯(Propylene Glycol Diacetate)
Big guy, who is free to help me to see what the problem is, I just read MySQL source print, and I just came into contact with flink.
使用安全浏览器将网页保存为pdf的方法步骤
ImportError: /lib/libgdal.so.26: undefined symbol: sqlite3_column_table_name
MySQL如何 drop 大表
WEB 渗透之SSRF
机器学习的方法总结
Zhong Hua, senior architect of Ali: China-Taiwan strategic thinking and architecture practice; including internal implementation manual
分享即时通讯开发之WebSocket:概念、原理、易错常识、动手实践
普通用户如何利用小红书赚钱呢?小红书的流量是真的吗?
dd命令:用于读取、转换并输出数据
力扣刷题之移动零
excel写入不完全sheet.append方法(openpyxl)
ScrollView嵌套RV,滑动有阻力不顺滑怎么办?
CC2530_ZigBee+华为云IOT:设计一套属于自己的冷链采集系统