张狂的暑假学习之 汇编入门学习笔记 (八)—— 搬运指令
参阅: 《汇编语言》 王爽 第9章
能够修正ip或许一起修正cs和ip的指令统称为搬运指令。
8086CPU搬运转为分为:
段内搬运:只修正ip
段间搬运:一起修正cs和ip
段内搬运按ip修正的规模可分为:
短搬运:ip修正规模 -128~127
近搬运:ip修正规模 -32768~32767
搬运指令分为:
无条件搬运指令。如 jmp
条件搬运指令
循环指令。如 loop
进程。
中止。
1. offset,nop指令
offset 获取标号的偏移地址
nop 占用1一个字节
比如:
- assumecs:code
- codesegment
- start:movax,bx
- movsi,offsetstart
- movdi,offsets
- movax,cs:[si]
- movcs:[di],ax
- s:nop
- nop
- codeends
- endstart
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
- movax,0123H
- movds:[0],ax
- jmpwordptrds:[0]
(2)jmp dword ptr 内存单元地址
是段间搬运
高地址表明搬运的段地址
低地址表明偏移地址
用debug检查机器码,能够发现,它是保存了段地址与偏移地址,而不是像段内搬运的指令时保存搬运的间隔
比如:搬运到段地址为0,偏移地址为0123H的指令去,即便得(CS)= 0,(IP)= 0123H
- movax,0123H
- movds:[0],ax
- movwordptrds:[2],0
- jmpdwordptrds:[0]
4. jcxz 指令
jcxz 指令为条件搬运指令。当cx为0时,搬运(与loop刚刚相反)。一切条件搬运指令都是短搬运。
比如:在内存2000H段中查找第一个值位0 的字节,并把它的偏移指定存储在dx中。
- assumecs:code
- codesegment
- start:movax,2000H
- movds,ax
- movbx,0
- s:movch,0
- movcl,[bx]
- jcxzok
- incbx
- jmpshorts
- ok:movdx,bx
- movax,4c00H
- int21H
- codeends
- endstart
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. 剖析一个古怪的程序
- assumecs:code
- codesegment
- movax,4c00h
- int21h
- start:movax,0
- s:nop
- nop
- movdi,offsets
- movsi,offsets2
- movax,cs:[si]
- movcs:[di],ax
- s0:jmpshorts
- s1:movax,0
- int21h
- movax,0
- s2:jmpshorts1
- nop
- codeends
- endstart
追后程序会运转s处的
mov ax,4c00h
int 21h
而正常停止。
为什么?
debug能够发现,jmp short s1 复制到s处后,由本来的jmp 0018H变成 jmp 0000H。
可是实质的机器码是EBF6没变便是ip = ip – 10。