第10章 CALL和RET指令
# 第10章 CALL 和 RET 指令
# 10.1 ret 和 retf 指令
CPU 执行 ret 指令,相当于 pop IP
CPU 执行 retf 指令,相当于 pop IP 和 pop CS
监测点10.1:
补全程序,实现从内存1000:0000处开始执行指令。
assume cs:code
stack segment
db 16 dup (0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,16
mov ax,1000h
push ax
mov ax,0
push ax
retf
code ends
end start
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 10.2.根据位移进行转移的 call 指令
CPU 执行
call 标号,相当于进行
- push IP
- jmp near ptr 标号
检测点
# 下面程序执行后,ax中的数值是多少?
1000:0 mov ax,0 ;读取此条指令后 IP=3 ,执行完该指令后 IP=3
1000:3 call s ;读取此条指令后 IP=6 ,所以 IP=6 入栈,执行完该指令后 IP=7,跳转到 s 处
1000:6 inc ax
1000:7 s:pop ax ;所以 POP 后,ax=6
1
2
3
4
5
2
3
4
5
# 10.3.转移目的地址在指令中的 call 指令
call far ptr 标号:实现段间转移。相当于进行如下操作
push CS
push IP
jmp far ptr 标号
监测点
下面程序执行后,ax中的数值为多少?
内存地址 机器码 汇编指令
1000:0 b8 00 00 mov ax,0
1000:3 9a 09 00 00 10 call far ptr s
1000:8 40 inc ax
1000:9 58 s:pop ax
add ax,ax * 8h+8h=10h
pop bx
add ax,bx * 1000h+10h=1010h
call far ptr s :此时IP为8h push 1000h push 8h
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 10.4.转移地址在寄存器中的call指令
指令格式:call 16位 reg
功能:
- push IP
- jmp 16 位 reg
检测点
这儿用到了bp,除了之前这样用过bp外 [bx+bp] ,还会在栈中用到。
比如说,堆栈中压入了很多数据或者地址,你肯定想通过SP来访问这些数据或者地址,但SP是要指向栈顶的,是不能随便乱改的,这时候你就需要使用BP,把SP的值传递给BP,通过BP来寻找堆栈里数据或者地址
1000:0 mov ax,6
1000:2 call ax ;相当于push IP=5 ,jmp ax=6 ,此指令未改变CS的值
1000:5 inc ax ;未执行
1000:6 mov bp,sp
add ax,[bp] ;相当于add ax,[sp],默认段地址ss,所以即把栈顶元素弹出和AX相加6+5=11=BH
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 10.5.转移地址在内存中的call指令
call word ptr 内存单元地址,相当于进行:
push IP
jmp word ptr 内存单元地址
实例:
mov sp,10h,
mov ax,0123h
mov ds:[0],ax
call word ptr ds:[0]
执行后,IP=0123h,sp=10h-2=0Eh
1
2
3
4
5
6
2
3
4
5
6
call dword ptr 内存单元地址,相当于进行:
push CS
push IP
jmp dwod ptr 内存单元地址
实例:
mov sp,10h
mov ax,0123h
mov ds:[0],ax
mov word ptr ds:[2],0
call dword ptr ds:[0]
执行后,cs=0 IP=0123h sp=10h-4=0Ch
1
2
3
4
5
6
7
2
3
4
5
6
7
检测点
