首页 > 代码库 > 汇编入门学习笔记 (八)—— 转移指令
汇编入门学习笔记 (八)—— 转移指令
疯狂的暑假学习之 汇编入门学习笔记 (八)—— 转移指令
參考: 《汇编语言》 王爽 第9章
能够改动ip或者同一时候改动cs和ip的指令统称为转移指令。
8086CPU转移行为分为:
段内转移:仅仅改动ip
段间转移:同一时候改动cs和ip
段内转移按ip改动的范围可分为:
短转移:ip改动范围 -128~127
近转移:ip改动范围 -32768~32767
转移指令分为:
无条件转移指令。如 jmp
条件转移指令
循环指令。如 loop
过程。
中断。
1. offset,nop指令
offset 获取标号的偏移地址
nop 占用1一个字节
样例:
assume cs:code code segment start: mov ax,bx mov si,offset start mov di,offset s mov ax,cs:[si] mov cs:[di],ax s: nop nop code ends end start
2. 根据位移进行转移的jmp指令
(1)jmp short 标号
是段内短转移。
表示转移到指定的标号处。且转移的距离范围为-128~127
用debug查看此指令时,会看见机器码。不会保存标号的地址,自会保存转移的距离
(2)jmp near ptr 标号
是段内近转移,转移的距离范围为-32768~32767。其它与jmp short 标号同样
2. 转移地址在寄存器中的jmp指令
jmp 16位 reg
表示 (IP)=(16位 reg)
3.转移地址在内存中的jmp指令
(1)jmp word ptr 内存单元地址
是段内近转移。
样例:转移到偏移地址为0123H的指令去,即使(IP)= 0123H
mov ax,0123H mov ds:[0],ax jmp word ptr ds:[0]
(2)jmp dword ptr 内存单元地址
是段间转移
高地址表示转移的段地址
低地址表示偏移地址
用debug查看机器码,能够发现。它是保存了段地址与偏移地址,而不是像段内转移的指令时保存转移的距离
样例:转移到段地址为0,偏移地址为0123H的指令去。即使得(CS)= 0。(IP)= 0123H
mov ax,0123H mov ds:[0],ax mov word ptr ds:[2],0 jmp dword ptr ds:[0]
4. jcxz 指令
jcxz 指令为条件转移指令。当cx为0时,转移(与loop刚刚相反)。
全部条件转移指令都是短转移。
样例:在内存2000H段中查找第一个值位0 的字节。并把它的偏移指定存储在dx中。
assume cs:code code segment start: mov ax,2000H mov ds,ax mov bx,0 s: mov ch,0 mov cl,[bx] jcxz ok inc bx jmp short s ok: mov dx,bx mov ax,4c00H int 21H code ends end start
5. jmp指令具体分析
向前转移:jmp s
jmp short s
jmp near ptr s
jmp far ptr s
在像前转移时。编译器能够在读到标号s后记下AC(地址计算器)的值as。在读到jmp ...s (上面5种)后记下AC的值aj。编译器能够用as-aj计算出disp
(1)假设disp 在 -128~127 内
上面的每一种指令都将转化为 jmp short s
(2)假设disp 在 -32768~32767 内
对于jmp short s会编译错误
对于jmp s,jmp near ptr s会产生jmp near ptr s所相应的机器码。
对于jmp far ptr s,所相应的机器码为:EA 偏移地址 段地址。
先后转移:
因为不能确定s位置,编译器先将上面的指令都当做 jmp short s来读取。记下jmp ..s 指令的位置和AC的值aj。
对于jmp short s 编译器生成一个EB和一个nop指令
对于jmp near ptr s 编译器生成一个EB和两个nop指令
对于jmp far ptr s 编译器生成一个EB和四个nop指令
当读到s时,记下AC的值as,计算disp = as - aj
(1)假设disp 在 -128~127 内
指令都为 EB disp 。它们后面的一个nop变成8位的disp 。jmp s(1个)、jmp near ptr s (1个)跟jmp far ptr s (3个) nop指令不变
(2)假设disp 在 -32768~32767 内
对于jmp short s会编译错误
jmp s、jmp near ptr s 后面 两个nop变成转移的16位disp。
jmp far ptr s 这填上对应的段地址。偏移地址。
6. 分析一个奇怪的程序
assume cs:code code segment mov ax,4c00h int 21h start: mov ax,0 s: nop nop mov di,offset s mov si,offset s2 mov ax,cs:[si] mov cs:[di],ax s0: jmp short s s1: mov ax,0 int 21h mov ax,0 s2: jmp short s1 nop code ends end start
追后程序会执行s处的
mov ax,4c00h
int 21h
而正常终止。
为什么?
debug能够发现,jmp short s1 拷贝到s处后,由原来的jmp 0018H变成 jmp 0000H。
可是本质的机器码是EBF6没变就是ip = ip - 10。
汇编入门学习笔记 (八)—— 转移指令