当前位置:网站首页>函数的底层机制
函数的底层机制
2022-07-30 03:50:00 【小鸡岛~】
一.寻址方式
提出问题:
- D3 FF FF FF和07E1080h有什么关系?
C++
int z = Add(1, 2);
汇编代码
007E10A4 push 2
007E10A6 push 1
007E10A8 call Add (07E1080h)
007E10AD add esp,8
007E10B0 mov dword ptr [z],eax
机器码
6A 02
6A 01
E8 D3 FF FF FF
83 C4 08
89 45 FC
猜测:D3 FF FF FF是具有符号的偏移量
实证:计算器
D3 FF FF FF
11111111111111111111111111010011
00000000000000000000000000101100 0x2C
00000000000000000000000000101101 0x2D
00C110ADh - 0C11080h = 2D
发现规律:
call指的偏移量寻址计算公式:偏移量 = 转跳到的地址 - call指令后一条指令的起始地址
二.函数地址
CALL指令相当于push指令和jmp指令的组合
push 返回地址
jmp 函数入口地址
三.参数的传递和获取参数的方式
C++
int Add(int x, int y) {
int num = x + y;
return num;
}
汇编语言
00FC17C0 push ebp
00FC17C1 mov ebp,esp
00FC17C3 sub esp,0CCh //分配局部变量
00FC17C9 push ebx
00FC17CA push esi
00FC17CB push edi
00FC17CC lea edi,[ebp+FFFFFF34h]
00FC17D2 mov ecx,33h
00FC17D7 mov eax,0CCCCCCCCh
00FC17DC rep stos dword ptr es:[edi]
00FC17DE mov ecx,0FCC02Ch
00FC17E3 call 00FC1339
00FC17E8 mov eax,dword ptr [ebp+8]
00FC17EB add eax,dword ptr [ebp+0Ch]
00FC17EE mov dword ptr [ebp-8],eax
00FC17F1 mov eax,dword ptr [ebp-8]
00FC17F4 pop edi
00FC17F5 pop esi
00FC17F6 pop ebx
00FC17F7 add esp,0CCh
00FC17FD cmp ebp,esp
00FC17FF call 00FC1258
00FC1804 mov esp,ebp //局部变量不存在了
00FC1806 pop ebp
00FC1807 ret
机器码
00FC17C0 55
00FC17C1 8B EC
00FC17C3 81 EC CC 00 00 00
00FC17C9 53
00FC17CA 56
00FC17CB 57
00FC17CC 8D BD 34 FF FF FF
00FC17D2 B9 33 00 00 00
00FC17D7 B8 CC CC CC CC
00FC17DC F3 AB
00FC17DE B9 2C C0 FC 00
00FC17E3 E8 51 FB FF FF
00FC17E8 8B 45 08
00FC17EB 03 45 0C
00FC17EE 89 45 F8
00FC17F1 8B 45 F8
提出问题:
- 怎么获取到栈上存储的参数1和2呢?
- 函数是通过哪一条指令让局部变量消失的呢?
- 这个函数从传递参数开始一共执行了多少条连续的push指令呢?
猜测:通过寄存器保存esp里面的地址,然后寄存器+偏移量去访问实参
实证: 函数开头一定有以下指令
push ebp
mov ebp,esp
...
pop ebp
发现规律:
- 参数的传递是通过push 参数1传递,参数传递时,栈顶地址会不断减少
- 获取参数的方式是通过**[ebp+偏移量]的方式去访问参数**,通过**[ebp-偏移量]的方式访问局部变量**
- 函数里面的局部变量在执行完 } 后就不存在了,不能再使用了
四.返回值
但返回值小于或等于4字节时,通过寄存器存储返回值
mov eax,dword ptr [ebp-8]
提出问题:当返回值超过4字节如何存储返回值呢?
设计实验:
C++代码
struct myrd
{
int i1;
int i2;
};
myrd myfunc() {
myrd r1;
r1.i1 = 1;
r1.i2 = 2;
return r1;
};
int main()
{
myrd r;
r = myfunc();
}
汇编代码
边栏推荐
- Process priority nice
- Solve the problem of compiling and installing gdb-10.1 unistd.h:663:3: error: #error “Please include config.h first.”
- 基于全志D1-H和XR806的名贵植物监控装置
- MySQ死锁
- Nacos服务注册与发现
- 写给技术人的管理入门知识1:什么是管理
- JIT vs AOT
- TCP拥塞控制技术 与BBR的加速原理
- Send it to your friends and let TA treat you to fried chicken!
- 使命、愿景、价值观到底有什么区别
猜你喜欢
Mini Program Graduation Works WeChat Second-hand Trading Mini Program Graduation Design Finished Works (6) Question Opening Reply PPT
Rpc 和 gRpc 简介汇总
Transformation of traditional projects
EasyNVR平台级联到EasyCVR,视频播放一会就无法播放是什么原因?
(6) "Digital Electricity" - Diodes and CMOS Gate Circuits (Introduction)
Mini Program Graduation Works WeChat Points Mall Mini Program Graduation Design Finished Products (6) Question Opening and Defense PPT
OpenFeign implementation downgrade
Let's learn the layout components of flutter together
小程序毕设作品之微信积分商城小程序毕业设计成品(1)开发概要
Nacos命名空间
随机推荐
OpenFeign实现降级
Uptime Monitoring: How to Ensure Network Device Uptime
淘宝H5接口获取app数据6.0格式
SQL 入门之第一讲——MySQL 8.0.29安装教程(windows 64位)
MySQ死锁
Dataset之MNIST:MNIST(手写数字图片识别+ubyte.gz文件)数据集简介、下载、使用方法(包括数据增强)之详细攻略
SDL player in action
OpenFeign实现负载均衡
【Node访问MongoDB数据库】
STM32 SPI+WM8978 voice loopback
Monitor page deployment
OpenFeign implementation downgrade
传输层详解
小程序毕设作品之微信二手交易小程序毕业设计成品(1)开发概要
【Use of scientific research tools】A
小程序毕设作品之微信积分商城小程序毕业设计成品(6)开题答辩PPT
SDL播放器实战
状态空间表示
操作配置:如何在一台服务器中以服务方式运行多个EasyCVR程序?
Hystrix service circuit breaker