1、汇编模拟函数调用的基本过程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | assume cs:code, ds:data, ss:stack stack segment db 20h dup(1) stack ends data segment db 20h dup(2) data ends code segment start: ;---初始化---- mov ax, stack;加载栈 mov ds, ax mov sp, 20h mov ax, data;加载数据 mov ds, ax ;---业务代码--- push 1122h push 3344h; call sum;系统会push下一行代码地址到栈 add sp, 4;人为压栈的数据执行出栈操作(否则会造成内存泄漏) ;---退出----- mov ah, 4ch int 21h ;---函数实现 sum: mov bp, sp;获取栈顶位置 mov ax, ss:[bp+2];取出栈最上面数据(3344h) add ax, ss:[bp+4];取出下一条数据(1122h)累加到ax ret;返回时系统会取出上一次压栈的位置 code ends end start |
2、C++中函数调用时的反汇编代码
2.1、C++源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // VCTest.cpp : Defines the entry point for the console application. // #include "stdafx.h" int sum(int a, int b) { return a + b; } int main(int argc, char* argv[]) { sum(2, 3); return 0; } |
2.2、反汇编部分代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | --- E:\Project\Assemble\VCTest\VCTest.cpp -------------------- 10: int main(int argc, char* argv[]) 11: { 00401050 push ebp 00401051 mov ebp,esp 00401053 sub esp,40h 00401056 push ebx 00401057 push esi 00401058 push edi 00401059 lea edi,[ebp-40h] 0040105C mov ecx,10h 00401061 mov eax,0CCCCCCCCh 00401066 rep stos dword ptr [edi] 12: sum(2, 3); 00401068 push 3 0040106A push 2 0040106C call @ILT+15(print) (00401014) 00401071 add esp,8 13: return 0; 00401074 xor eax,eax 14: } 00401076 pop edi 00401077 pop esi 00401078 pop ebx 00401079 add esp,40h 0040107C cmp ebp,esp 0040107E call __chkesp (00401120) 00401083 mov esp,ebp 00401085 pop ebp 00401086 ret --- No source file -------------------------------------------- |
Pingback: AT&T汇编中函数的基本实现 | 一天到晚游泳的余
Pingback: 函数调用原理–完善篇(栈帧) | 一天到晚游泳的余
Pingback: 汇编中函数局部变量的实现(本质) | 一天到晚游泳的余
Pingback: 三种常用的函数调用约定 | 一天到晚游泳的余