call指令模拟C语言函数调用
1.执行call指令时,有以下2步操作:
a).将当前ip或cs和ip压入栈中。
b).跳转到标号处。
call lable(标号),将当前ip压栈后,转移到标号处执行。
call far ptr lable,实现段间转移。将当前cs和ip压栈,转移到far ptr lable标号处执行。
call reg16/mem16(16位寄存器/2个字节内存),将当前ip压栈后,转移到reg16/mem16。
call word ptr,将当前ip压栈后,转移到word ptr内存单元处执行。
2.实现模拟C语言函数调用模板
1 data segment 2 g_szString db "HelloWorld$" 3 data ends 4 5 stack1 segment stack 6 org 64 7 stack1 ends 8 9 code1 segment 10 assume cs:code1,ds:data 11 fun_add: ;__cdecl 12 push bp ;bp压栈 13 mov bp, sp ;保存栈底 14 15 sub sp, 20h ;提升栈顶,申请局部变量空间 16 mov word ptr [bp-04h], 03h ;局部变量 17 mov word ptr [bp-02h], 02h 18 19 mov ax, [bp+6] ;参数b 20 mov bx, [bp+8] ;参数a 21 add ax,bx ;计算 22 23 mov sp, bp 24 pop bp 25 26 retf ;__cdecl调用方式 27 code1 ends 28 29 code segment 30 assume cs:code,ds:data 31 START: 32 mov ax,5 33 push ax ;参数a=5压栈 34 mov bx,6 35 push bx ;参数b=6压栈 36 37 call far ptr fun_add 38 add sp,4 ;平衡栈 39 40 mov ax,4c00h 41 int 21h 42 ret 43 44 code ends 45 end START
下面一张图显示call fun_add指令后,没有执行fun_add标号里面的指令时,返回地址以及参数压栈情况
上图显示了call执行情况,现把显示call标号前和call标号中的指令的栈画出来,这样比较清晰