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标号中的指令的栈画出来,这样比较清晰

猜你喜欢

转载自www.cnblogs.com/pro-love/p/10917451.html