[bx]和内存单元的描述
要完整的描述一个内存单元,需要两种信息:
内存单元的地址
[0]表示一个内存单元时,0表示单元的偏移地址,段地址默认在
ds中[bx]表示一个内存单元时,偏移地址在
bx中,段地址在ds中内存单元的长度(类型)
单元的长度(类型)可由具体指令中的其他操作对象(如寄存器)指出
约定描述性符号
()
表示一个寄存器或一个内存单元中存放的内容
()中的元素有三种类型:寄存器名
段寄存器名
内存单元的物理地址(一个20位的数据)
()所表示的数据类型有两类:字节
字
是哪种类型由寄存器名或具体的运算决定
idata表示常量
[BX]
功能
mov ax,[bx]bx中存放的数据为偏移地址EA,段地址SA默认在ds中,将SA:EA处的数据送入ax中,即:(ax)=((ds)*16+(bx))mov [bx],axbx中存放的数据为偏移地址EA,段地址SA默认在ds中,将ax中的数据送入内存SA:EA处,即:((ds)*16+(bx))=(ax)
loop指令
格式:loop 标号
CPU执行loop指令时,要进行两步操作:
(cx)=(cx)-1判断
cx中的值,不为零则转至标号处执行程序,为零则向下执行
通常,使用loop指令来实现循环功能,cx中存放循环次数
使用方法
计算2^12
1 | assume cs:code |
在
cx中存放循环次数loop指令中的标号标识要循环执行的语句,标号所标识地址要在前面要循环执行的程序段,要写在标号和
loop指令中间
用cx和loop指令相配合实现循环功能的程序框架:
1 | mov cx,循环次数 |
在Debug中跟踪用loop指令实现的循环程序
计算ffff:0006单元中的数乘以3,结果存储在dx中
1 | assume cs:code |
程序中第一条指令mov ax,0ffffh,在汇编源程序中,数据不能以字母开头,所以在前面加0

(ds)=0b3dh,则程序在0b3d:0处(程序内存前存在256个字节的程序段前缀)
(cs)=0b3dh,(IP)=0指向程序的第一条指令

使用u命令查看被Debug加载入内存的程序,此时,loop s已变为loop 0012h,用于实现跳转






程序执行结束
可以使用g命令跳过某些不想单步执行的代码段,g 0012将使Debug从当前的CS:IP指向的指令开始执行,一直到(IP)=0012h为止

可以使用p命令来让Debug自动重复执行循环中的指令,直到(cx)=0为止
使用g命令同样可以达到跳过循环过程的效果

Debug和汇编编译器masm对指令的不同处理
对于类似mov ax,[0]的汇编指令
在Debug中,表示将ds:0内存单元处的数据送入ax中
在masm中,被当作mov ax,0处理,表示将ax寄存器赋值为0
汇编源程序中以下指令的含义:
mov al,[0]:(al)=0,将常量0送入al中mov al,ds:[0]:(al)=((ds)*16+0),将内存单元中的数据送入al中mov al,[bx]:(al)=((ds)*16+(bx)),将内存单元中的数据送入al中mov al,ds:[bx]:与mov al,[bx]含义相同
如何实现在源程序中将内存单元中的数据送入寄存器呢?
- 使用
bx,间接给出内存单元的偏移地址,则段地址默认存储在ds中1
2
3
4mov ax,2000h
mov ds,ax
mov bx,0
mov al,[bx]
- 在汇编源程序中,若在
[]中用一个常量直接给出内存单元的偏移地址,需在[]前显式的给出段地址所在的段寄存器,如:mov al,ds:[0]
loop与[bx]的联合应用
计算ffff:0-ffff:b单元中的数据的和,结果存储在dx中
问题:
结果是否会超出
dx范围一个存储单元存储一个字节数据,范围在0-255,12个字节型数据相加,结果不大于65535,不会超出存储范围
能否将数据直接累加到
dx中不行,内存单元数据为8位,不可直接累加到16位寄存器中
能否将内存单元中数据累加到
dl中,设置(dh)=0,实现累加不行,会出现进位丢失
可使用一个16位寄存器做中介,将内存单元中的数据送入16位寄存器ax中,再将ax中数据加到dx中,实现运算对象类型匹配且结果不会超界
1 | assume cs:code |
使用loop指令,使程序更简洁
1 | assume cs:code |
段前缀
如:mov ax,ds:[bx],出现在访问内存单元的指令中,用于显式指明内存单元的段地址的ds等,在汇编语言中称为段前缀
一段安全的空间
在8086模式中,随意向一段内存空间中写入内容是非常危险的,因为这段空间中可能存放着重要的系统数据或代码
在纯DOS方式(实模式)下,可直接使用汇编语言去操作真实的硬件,因为在CPU实模式下的DOS,没有能力对硬件系统进行全面、严格的管理
在运行于CPU保护模式下的操作系统中,无法用汇编语言去操作真实的硬件,硬件已被操作系统利用CPU保护模式所提供的功能全面而严格的管理了
总结
我们需要直接向一段内存中写入内容
这段内存空间不应该存放系统或其他程序的数据或代码,否则写入操作可能引发错误
DOS方式下,一般情况,0:200-0:2ff空间中没有系统或其他程序的数据或代码在使用内存空间时,可使用
Debug查看内存空间是否被使用
段前缀的使用
将内存ffff:0-ffff:b单元中的数据复制到0:200-0:20b单元中
0:200-0:20b单元等同于0020:0-0020:b单元,它们描述的是同一段内存空间
1 | assume cs:code |
程序中使用dl寄存器作为中介进行数据复制
每次循环需要设置两次ds,用于切换源段地址与目的段地址,源内存单元与目的内存单元相距大于64KB,效率不高,可以设置两个段寄存器,分别用于存放源段地址与目的段地址,即可省略每次循环需设置两次ds的操作
1 | assume cs:code |