本文已参与「新人创作礼」活动,一起开启掘金创作之路。 9.4转移的目的地址在指令中的jmp指令
jmp short 标号与 jmp near ptr 标号
对应的机器码无转移的目的地址,而是相对于当前IP的转移位移。
jmp far ptr 标号
实现的是段间转移,又称为远转移
jmp far ptr 标号的功能:
1.(CS)=标号所在段的段地址
2.(IP)=标号所在段中的偏移地址
- far ptr指明了指令用标号的段地址和偏移地址修改CS和IP
程序9.3
机器码
源码为 jmp far ptr s
此处翻译成了jmp 至目标地址
9.5转移地址在寄存器中的jmp指令
9.6转移地址在内存中的jmp指令
(1)jmp word ptr内存单元地址(段内转移)
功能: 从内存单元地址处开始存放着一个字,是转移的目的偏移地址。
内存单元地址可用寻址方式的任一格式给出
eg
(2)jmp dword ptr 内存单元地址(段间转移)
功能:从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址
eg
检测点9.1
1.
db 0
dw 0
A: db 3 dup(0)
or dw 2 dup(0)
or dd 0
mov [bx],word ptr 0 ;mov [bx],offset start
mov [bx+2],cs ;mov [bx+2],offset seg code
CS:0006H
IP: 00BEH
9.7 jcxz指令
jcxz为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为-128~127
loop也是有条件转移指令
格式: jcxz 标号
如果(cx)=0,则转移到标号处执行
jcxz 标号的功能相当于:
if((cx)==0)
jmp short 标号;
检测点9.2
mov cl,[bx]
mov ch,0
jcxz ok
inc bx
9.8 loop指令
loop 指令为循环指令,所有循环指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址
对IP的修改范围都是-128~127
指令格式: loop 标号
((cx))=(cx)-1,如果(cx)不等于0,转移到标号处执行
C解释loop
(cx)--;
if ((cx)不等于0)
jmp short 标号
检测点9.3
inc cx
9.9根据位移进行转移的意义
eg
jmp short 标号、jmp near ptr 标号都是根据转移目的地址和转移起始地址之间的位移来进行的。在它们对应的机器码中不包含转移的目的地址,而包含的是到目的地址的位移距离
方便了程序段在内存中的浮动装配。
例如:
在内存中不同位置都可正确执行,loop s在执行时只涉及到s的位移,而不是s的地址
无论s处的指令的实际地址是多少,loop指令的转移位移不变
若loop s的机器码包含的是s的地址,则就对程序段在内存中的偏移地址有了严格的限制
试错
assume cs:code
code segment
start: jmp short s
db 128 dup(0)
s: mov ax,0ffffh
code ends
end start
编译该文件时会报错
Reason:jmp short 对IP的修改范围为 -128~127而此处需向前跳转128字节,超过了范围,故报错
实验8(错题)
是可以正确返回的
别忘了近转移是转移偏移位,而不是转移至地址
这边s2:jmp short s1
s2和s1之前设位移为-10
根据上述代码,观察得s2中代码覆盖了s的代码
s:jmp short s1(向上偏移10位)
跳至代码位置 s0-10
直接执行cs:[0]处的代码:
mov ax,4c00h
int 21h
正常中断