综述
- 一般情况下指令是顺序地逐条执行的,而在实际中,常需要改变程序的执行流程
- 可以修改IP,或同时修改CS和IP的指令
offset 指令
- 获取标号的偏移地址
- offset 标号
- 例:
assume cs:codeseg
codeseg segment
start: mov ax,offset start ;相当于mov ax,0
s: mov ax,offset s ;相当于mov ax,3
codeseg ends
end start
jmp 无条件转移
两种段内转移
- 短转移
jmp short 标号
-128~127
= "标号"处的地址 - jmp指令后的第一个字节的地址
assume cs:codesg
codesg segment
start: mov ax,0
jmp short s
add ax,1
s: inc ax
codesg ends
end start
- 近转移
jmp near ptr 标号
-32769~32767
= "标号"处的地址 - jmp指令后的第一个字节的地址
near ptr
指明了相对于当前IP的转移位移,而不是转移的目的地址assume cs:codesg
codesg segment
start: mov ax,0
mov bx,0
jmp near ptr s
db 256 dup (0)
s: add ax,1
inc ax
codesg ends
end start
- 远转移
jmp far ptr
标号
far ptr
指明了跳转到的目的地址,即包含了标号的段地址CS和偏移地址IPassume cs:codesg
codesg segment
start: mov ax,0
mov bx,0
jmp far ptr s
db 256 dup (0)
s: add ax,1
inc ax
codesg ends
end start
- 转移地址在寄存器中的jmp指令
jmp 16位寄存器
assume cs:codesg
codesg segment
start: mov ax,0
mov bx,ax
jmp bx
mov ax,0123H
codesg ends
end start
- 转移地址在内存中的jmp指令
段内转移:jmp word ptr
内存单元地址
从内存单元地址处开始存放着一个字,是转移的目的偏移地址
段间转移:jmp dword ptr
内存单元地址
从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址
其它转移指令
jcxz
assume cs:codesg
codesg segment
start: mov ax,2000H
mov ds, ax
mov bx,0
s: mov cx, [bx]
jczx ok
inc bx
inc bx
jmp short s
ok: mov dx,bx
mov ax,4c00H
int 21H
codesg ends
end start
loop指令
call指令和ret指令
- 调用子程序:call指令
- 返回:ret指令
- 实质:修改IP,或同时修改CS和IP
call标号
call far ptr 标号 实现的是段间转移
转移地址在寄存器中的call指令
转移地址在内存中的call指令
call word ptr
内存单元地址mov sp,10h ;栈顶指针寄存器,当放入转移地址后,栈顶指针会向下偏移一个字
mov ax,0123h
mov ds:[0],ax
call word ptr ds:[0]
执行后,(IP)=0123H,(sp)=0EH
- call dword 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)=0CH
ret和retf
call和ret的配合使用
具有子程序的源程序的框架
assume cs:code
code segment
main: ...
call sub1
...
mov ax,4c00h
int 21h
sub1: ...
call sub2
...
为call和ret指令设置栈
assume cs:code ss:stack
stack segment
db 8 dup (0)
db 8 dup (0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov ax,1000
call s
mov ax,4c00h
int 21h
s: add ax,ax
ret
code ends
end start