8086汇编-转移指令的原理(9)
引言
1.8086CPU的转移指令分为以下几个类
1 | 1.无条件转移指令【jmp】 |
1.操作符offset
1.offset:伪指令,取得标号的偏移地址
1 | assume cs:codesg |
小小的练习
填写指令,使改程序在运行中将s处的一条指令复制到s0处
1 | assume cs:codesg |
分析一下咯
1 | 1.s和s0处的指令所在的内存地址是多少? |
程序来咯
1 | assume cs:codesg |
2.jmp指令
1.jmp为无条件转移,可以只修改IP,也可以同时修改CS和IP
2.jmp指令要给处俩种信息:
1 | 1.转移的目的地址 |
3.依据位移进行转移的jmp指令
1.jmp short 标号(转到标号处执行指令)
1 | 这种格式的jmp指令实现的是段内短转移,它对IP的修改范围是-128~127,也就是说,它向前可以越过128个字节,向后可以最多越过127个字节【越后面数越大】 |
比如:
1 | assume cs:codesg ;左边的程序执行后,ax种的值为1,因为执行 |
2.jmp short s指令的读取和执行过程:
1 | 1.(cs)=0BBDH,(IP)=0006,CS:IP指向EB 03(jmp short s 的机器码) |
3.实际上,指令“jmp short 标号”的功能为(IP)=(IP)+8位位移
1 | 1.8位位移=“标号”处的地址-jmp指令后的第一个字节的地址;相互减 |
4.还有一种和“jmp short 标号”功能相近的指令格式
==>jmp near ptr 标号
功能就是
IP=IP+16位位移
1 | 1.16位位移=“标号”处的地址 - jmp指令后的第一个字节的地址 |
4.转移的目的地址在指令中的jmp指令
1.前面讲的jmp指令,其对应的机器码中并没有转移目的的地址,而是相对于当前IP的转移位移
2.现在要有一个新的
jmp far ptr 标号:实现的是段间转移,又称为远转移
1 | 1.(CS)=标号所在段的段地址 |
1 | assume cs:codesg |
5.转移地址在寄存器中的jmp指令
1.指令格式:jmp 16位的寄存器
功能: IP = (16位寄存器)
1 | jmp ax |
6.转移地址在内存中的jmp指令有2种格式
1.jmp word ptr 内存单元地址【段内转移】
功能:从内存单元地址开始存放着一个字,是转移的目的的偏移地址
内存单元地址可用寻址方式的任一格式给出
1 | mov ax,0123H mov ax,0123H |
2.jmp dword ptr 内存单元地址【段间转移】
功能:从内存单元地址处开始存放着2个字,高地址处的字是转移的目的段地址,低地址处是转移的目的的偏移地址
(CS)=(内存单元地址+2)
(IP)=(内存单元地址)
内存 单元可以由寻址的方式的任意格式给出
1 | mov ax,0123H |
7.jcxz指令
1.jcxz指令为有条件转移指令,所有的有条件跳转指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都是-128~127
2.指令格式:jcxz 标号
:如果(cx)=0 则跳转到标号处执行
3.jcxz 标号 指令操作
1 | 1.当(cx)=0时,(ip)=(ip)+8位位移 |
相当于
1 | if((cx)==0){ |
8.loop指令
1.loop指令为循环指令,所有的循环指令都是短位移,在对应的机器码中包含转移的位移,而不是目的地址
1 | loop 是用于知道循环次数的循环 |
9.根据位进行转移的意义
1.前面讲到:
1 | jmp short 标号 |
这几种汇编指令,它们对IP的修改是根据转移目的地址和转移起始地址之间的位移来进行的。
在它们对应的机器码中不包含位移的目的地址,而包含的是到目的地址的位移距离
2.这样设计是为了,方便了程序段在内存中的浮动装配
1 | mov cx,6 B9 06 00 |
3.这段程序在内存中的不同位置都可以正确执行,因为loop s 在执行时只涉及到s 的位移(-4 , 前移4个字节,补码表示为 FCH)而不是s的地址
4.如果loop s的机器码中包含的是s的地址,则就对程序段在内存中的偏移地址就有了严格的限制,就不能封装起来放在其他地方使用
5.因为机器码中包含的是s的地址,如果s处的指令不在目的地址处,程序的执行就会出错
我们之前在第二章中讲到的
jmp cs:ip
这种是在debug中的指令,汇编编译器并不认识
实验8
1 | exp8.exe |