转移指令:
修改IP或同时修改CS和IP的行为称为转移指令。
8086CPU的转移指令有:
- 无条件转移指令(JMP)
- 条件转移指令
- 循环转移指令(如:LOOP)
- 过程
- 中断
80886CPU的转移行为:
- 段内转移:只修改IP。段内转移又有短转移和近转移,近转移范围更大。
- 段间转移:同时修改CS和IP
操作符OFFSET:
操作符offset可以取得标号的偏移地址。用法:如 mov ax,offset s , mov ax,offset start 前者把标号s的偏移地址存入AX中,后者把标号start的偏移地址存入AX中。
如果我们要将一个标号后的指令复制到另一个标号后面,我们就可以用offset指令。
如要将s处的指令复制到s0处。因为 s 后面的指令 mov ax,bx 占两个字节,所以我们在s0后面用了两个 nop ,指令 nop 是空操作符,一个nop占一个字节。我们可以看到我们已经用 offset 将s处的偏移地址存入SI,s0处的偏移地址存入DI ,所以在横线处我们可以这样写:mov ax,cs:[si] mov cs:[di],ax
jmp 指令:
段内转移
类似于c++中的goto指令。比如我们用 jmp short s ,这个指令是个跳转指令,当运行到这个指令时,CPU将会转而去运行,标号s后面的指令, short表示的是这里是8位位移,也是段内转移中的短转移,范围是-128~127(字节)。近转移表示为 jmp near 标号。范围是-32768~32767。而其实在jmp的机器码中其实不包含要跳转的标号的偏移地址,它是通过修改ip来达到目的的。
我们得先回顾一下CPU执行指令的过程,CPU先把CS,IP指定地址中的数据传入指令缓冲器,然后IP增加指向后面的指令,但是此时指令缓冲器的是 jmp指令,这个指令是修改IP的,它修改的方法是将JMP后面标号的地址减去JMP指令后一条指令的地址,得出来的结果就是要增加的位移。然后将此时的IP加上这个值,然后后面就会执行我们所要跳转的那个地方的指令。
段间转移
jmp far ptr 标号 实现段间转移,用法和上面的段内转移一样,但是这个指令其中包含目的地址。
转移地址在寄存器中
jmp 16 位偏移地址 (之前介绍过的)(jmp 段地址:偏移地址 这个是DEBUG中的指令,用在汇编中会报错)
转移地址在内存中的jmp指令
段内转移:jmp word ptr 内存单元地址。它将从指定的内存单元地址开始读取一个字来作为转移的偏移地址。段地址在DS中,内存单元可以用任意一寻址方式给出。如:
执行完这个指令后,IP将变为0123
段间转移:jmp dword ptr 内存单元地址。它将从指定的内存单元开始读取两字单元,高位的字作为转移的段地址,低位的作为转移的偏移地址。内存单元可以用任意一寻址方式给出。如:
执行完后CS=0,IP=0123。内存单元地址也可以用寄存器指出。
有条件转移指令:
JCXZ指令:所有有条件转移指令都是短转移指令,所以它的范围也是-128~127,它的原理也和 jmp short 标号一样,也是机器码中没有目的地址,而是改变IP,计算方法也是和 jmp short 一样,也是8位位移,位移用补码显示。但它有一个不同的就是只有当CX中的值为0时它才执行,不等于0时什么都不做,执行下一个指令。
loop指令:所有循环指令也都是短转移,范围和原理也都和上面的短转移的一样,用法之前已经介绍过了。
jxcz和loop指令的不同之处在于,jxcz是只有当CX中的值为0时,指令才执行,否则上面也不做,而loop是只有当CX中的值不位0时才执行,并且每次 运行到loop时,loop会将CX中的值减一,而 jxcz 不会 。
注意:使用转移时不能超界,否则会报错。短转移范围是-128~127,近转移范围是-32768~32767。
根据材料编程:
如果要在显示屏上显示一段字符,我们可以向 80*25彩色字符模式显示缓冲区写入数据,写入的内容会立马显示在显示屏上。这个显示缓冲区在内存中占32KB,位于B8000~BFFFF上。
显示缓冲区分为8页,每页4KB。而因为每个字符占两个字节,低位字节为字符的ASCII码,高位字节为字符的属性,并且每页都是80*25,也就是每页有25行,每行80列。所以每页有2000个字符,占4000个字节(约等于4KB)。
每个字符的属性可以有256种不同的组合
这表示的是在属性的字节中,各个位的含义。每个位 1 表示有 0 表示没有,我们可以根据这个调出我们想要的字符,然后将这个二进制编码转换成16进制和我们字符的ASCII码一起存入显示缓冲区中。比如我们要打出一个红底高亮闪烁绿色的字符A,我们可以向显示缓冲区输入数据: 41 CA 41是A的ASCII码,而上述信息:红底 高亮 闪烁 绿色 根据上图提供的规则,我们的二进制数为 1 1 0 0 1 0 1 0 转换成16进制就是CA。