汇编指令与机器码的对应示例
汇编指令 | 机器指令 |
---|---|
mov ax,0123 | B8 23 01 |
mov ax,ds:[0123] | A1 23 01 |
push ds:[0123] | FF 36 23 01 |
可以看到,在一般的汇编指令中,汇编指令中的idata(立即数),不论它是表示一个数据还是内存单元的偏移地址,都会在对应的机器指令中出现
转移指令
8086CPU的转移指令分为以下几类
- 无条件转移指令(如:jump)
- 条件转移指令
- 循环指令(如:loop)
- 过程(函数)
- 中断
操作符offset
操作符offset的功能是取得标号的偏移地址(相对于当前段地址)
例子:
assume cs:codesg
codesg segment
start: mov ax,offset start;相当于mov ax,0 (cs:offset start)
s: mov ax,offset s ;相当于mov ax,3 (cs:offset s)
codesg ends
end start
jmp指令
jmp为无条件转移,可以只修改IP,也可以同时修改CS和IP,同时jmp指令需要给出两种信息:
- 转移的目的地址
- 转移的距离(段间转移、段内短转移、段内近转移)
依据位移进行转移的jmp指令
jmp short 标号(转移到标号处执行指令)
这种格式的jmp指令实现的是段内短转移,它对IP的修改范围为**-128~127**,也就是说它向前转移时可以最多越过128个字节,向后转移可以最多越过127个字节
例子:
assume cs:codesg
codesg segment
start: mov ax,0
jmp short s
add ax,1
s: inc ax
codesg ends
end start
实际上指令jmp short 标号
的功能为(IP)=(IP)+8位位移
- 8位位移 = “标号”处的地址 - jmp指令后的第一个字节的地址
- short指明此处的位移为8位位移
- 8位位移的范围为-128~127,用补码表示
- 8位位移由编译程序在编译时算出
jmp near ptr 标号
这个指令实现的是段内近转移,即(IP)=(IP)+16位位移
- 16位移 = “标号”处的地址 - jmp指令后的第一个字节的地址
- near ptr指明此处的位移为16位位移
- 16位位移的范围为-32769~32767,用补码表示
- 16位位移由编译程序在编译时算出
转移的目的地址在指令中的jmp指令
jmp far ptr 标号
实现的是段间转移,又称为远转移
- (CS)= 标号所在段的段地址
- (IP) = 标号所在段中的偏移地址
- far ptr 指明了指令用标号的段地址和偏移地址修改了CS和IP
例子:
assume 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位寄存器
功能:(IP)= (16位寄存器)
转移地址在内存中的jmp指令
jmp word ptr 内存单元地址(段内转移)
功能:从内存单元地址处开始存放着一个字型数据,是转移的目的偏移地址,内存单元地址可用寻址方式的任一格式给出
例子:
mov ax,0123H
mov ds:[0],ax
jmp word ptr ds:[0]
jmp dword ptr 内存单元地址(段内转移)
功能:从内存单元地址处开始存放着两个字型数据,高地址处的字是转移的目的段地址,低地址是转移的目的偏移地址,内存单元地址可用寻址方式的任一格式给出
- (CS)=(内存单元地址+2)
- (IP)=(内存单元地址)
例子:
mov ax,0123H
mov ds:[0],ax
mov word ptr ds:[2],0
jmp dword ptr ds:[0]
mov ax,0123H
mov ds:[0],ax
mov word ptr [bx+2],0
jmp dword ptr [bx]
jcxz指令
jcxz指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为**-128~127**,一般的有条件转移指令看的都是cx寄存器,例如loop指令
jcxz 标号 (如果(cx)=0,则转移到标号初执行)
jcxz实际的指令操作:
- 当(cx)= 0时,(IP)=(IP)+ 8位位移
- 8位位移 = “标号”处的地址 - jcxz指令后的第一个字节的地址
- 8位位移的范围为-128~127,用补码表示
- 8位位移由编译程序在编译时算出
- 当(cx)=0时,什么也不做(程序向下执行)
其实也可以理解为
if((cx)==0)
jmp short 标号
loop指令
loop指令为循环指令,所有的循环指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为**-128~127**
loop 标号
loop实际的指令操作:
-
(cx)=(cx)- 1
-
当(cx)!= 0时,(IP)=(IP)+ 8位位移
- 8位位移 = “标号”处的地址 - loop指令后的第一个字节的地址
- 8位位移的范围为-128~127,用补码表示
- 8位位移由编译程序在编译时算出
-
当(cx)=0时,什么也不做(程序向下执行)
其实也可以理解为
(cx)--;
if((cx)!=0)
jmp short 标号