转移指令概念和offset操作符
可以修改 IP ,或同时修改 CS 和 IP 的指令统称为转移指令。概括地说,转移指令就是可以控制CPU执行内存某处代码的指令。
8086CPU转移行为的分类:
- 只修改 IP 时,称为段内转移
- 同时修改 CS 和 IP 时,称为段间转移
段内转移对 IP 的修改范围不同时,又分为
- 短转移:IP 的修改范围为:-128~127(8位)
- 近转移:IP 的修改范围为:-32768~32767(16位)
8086CPU的转移指令的分类:
- 无条件转移指令(如 JMP )
- 条件转移指令
- 循环指令(如 LOOP )
- 过程
- 中断
操作符 offset 在汇编语言中是由编译器处理的符号,功能是取得标号的偏移地址。例如:
关于JMP指令
之前介绍了 JMP 指令。该指令要给出两种信息:
- 转移的目的地址
- 转移的距离(段间转移、段内短转移、段内近转移)
该指令有以下用法:
JMP short label
该语句转到标号 label
处执行指令。关键字 short 说明指令进行的是短转移,它向前转移时最多可以越过128字节,向后转移时最多可以越过127字节。
转移指令结束后,CS:IP
应该指向标号处的指令。
“ JMP short label
”的功能为:(IP)
+=8位位移。
8位位移以补码的形式给出。
在“ JMP short label
”指令所对应的机器码中,并不包含转移的目的地址,而是包含转移的位移。该位移由编译器计算出结果。
JMP near ptr label
该转移语句,关键字 near ptr 说明实现的是段内近转移。
“ JMP near ptr label
”的功能为:(IP)
+=16位位移。
JMP far ptr label
该指令实现的是段间转移,又称为远转移。
“ JMP far ptr label
”的功能为:(CS)
=标号所在段的段地址;(IP)
=标号所在段中的偏移地址。
关键字 far ptr 指明了用标号的段地址和偏移地址修改 CS 和 IP 。
JMP 16bit-reg
使用16位寄存器 16bit-reg
中的值修改 IP 。
JMP word ptr memory
该指令是段内转移,将内存单元地址 memory
处的字型数据(16位)作为转移目的的偏移地址。
内存单元地址可用寻址方式的任意格式给出。
JMP dword ptr memory
该指令是段间转移,对应内存单元地址 memory
处存放的连续两个字,高地址处存放的字是转移目的的段地址,低地址处存放的字是转移目的的偏移地址。
内存单元地址可用寻址方式的任意格式给出。
JCXZ、NOP指令
JCXZ 指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是转移的目的地址。
label
处执行;当寄存器
CX
的值不为零时,程序继续向下执行(什么也不做)。对比一下 LOOP 指令:
LOOP 指令为循环指令,所有的循环指令也都是短转移。
LOOP 指令会先使 CX 寄存器中的值减1,如果 CX 中的值不为零时,程序跳转到标号 label
处执行;当寄存器 CX 的值为0时,程序继续向下执行(什么也不做)。
NOP 指令除了占用三个周期,什么操作都没有。因此它一般用于控制时间周期。
位移转移与转移越界
目前介绍的转移指令,包括 JMP 、JCXZ 、LOOP ,它们对 IP 的修改是根据转移起始地址和转移目的地址的位移来进行的。
这种位移的实现由编译器完成。它的优点是无需得到目标代码的真实地址,方便程序在内存中浮动装配。
根据位移进行转移的指令,它们的转移范围受到转移位移的限制,如果在源程序中出现了转移越界的问题,在编译时编译器会报错。
DOS字符显示
DOS操作系统采用80×25彩色字符模式显示缓冲区,该缓冲区的结构为:
内存地址空间中,B8000H~BFFFFH共32KB的空间,为80×25彩色字符模式的显示缓冲区。向这个地址空间写入数据,写入的内容将立即出现在显示器上。
在80×25彩色字符模式下,显示器可以显示25行,每行80个字符,每个字符可以有256种属性(背景色、前景色、闪烁、高亮组合信息)。
这样,一个字符在显示缓冲区中要占2个字节:低字节存放字符的ASCII码信息,高字节存放字符的属性信息。
属性字节的格式见下图:

在属性对应的位中,0代表无效果或无色值,1代表有效果和有色值。色值可以叠加,背景色最多有8种。
可以按位设置属性字节,从而得到不同的属性。
80×25模式下,一个显示屏的内容在缓冲区中共占用4000个字节。
显示缓冲区分8页,每页4KB。显示器可以显示任意一页的内容,但一般情况下,显示第0页的内容。通常情况下,B8000H~B8F9FH中的4000个字节的内容将出现在显示器上。
在一页显示缓冲区中:
偏移000H~09FH对应显示器上的第1行(80个字符,占160字节); |
偏移0A0H~13FH对应显示器上的第2行; |
偏移140H~1DFH对应显示器上的第3行; |
…… |
偏移F00H~1DFH对应显示器上的第25行。 |
在一行中:
00H~01H单元对应显示器上的第1列; |
02H~03H单元对应显示器上的第2列; |
04H~05H单元对应显示器上的第3列; |
…… |
9EH~9FH单元对应显示器上的第80列。 |
以下是一个字符显示示例:
它在显示器上第0EH(14)行、23H(35)列(都以0开始计数)处显示“ Hello, world
”,显示的效果为:
