[bx]和内存单元的描述:
[bx]和[0]有些类似,[0]表示内存单元,它的偏移地址为0
mov ax,[0]:将一个内存单元的内容送入ax中,这个内存单元的长度为2字节,存放一个字,偏移地址为0,段地址在ds中
用[0]表示一个内存单元时,0表示单元的偏移地址,段地址默认在ds中
mov ax,[bx]:将一个内存单元内容送入ax中,这个内存单元的长度为2字节,存放一个字,偏移地址在bx中,段地址在ds中
[bx]同样表示一个内存单元,它的偏移地址在bx中
5.1 [BX]
mov ax,[bx]:将bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将SA:EA处的数据送入ax中
即(ax)=((ds)*16+(bx))
mov [bx],ax:bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将ax中的数据送入内存SA:EA处
即((ds)*16+(bx))=(ax)
inc bx 的含义是bx中内容加1
5.2 Loop指令
loop指令的格式是:loop 标号,CPU执行loop指令时,要进行两步操作,(1),(cx) = (cx) - 1,(2)判断cx中的值,不为0则转至标号处执行程序,如果为0则向下执行
cx影响着loop指令的循环结果,通常我们用loop指令来实现循环功能,cx中存放着循环次数
mov cx,循环次数
s:
循环执行的程序段
loop s
示例:
assume cs:code
code segement
mov ax,2
mov cx,11
s: add ax,ax
loop s
mov ax,4c00h
int 21h
code ends
end
cx和loop指令配合实现循环功能的3个要点:
1,在cx中存放循环次数
2,loop指令中的标号所标识地址写在前面
3,要循环执行的程序段,写在标号和loop指令中间
5.3 在debug中跟踪loop指令实现的循环
计算ffff:0006单元中的数乘以3,将其结果存储在dx中
分析:ffff:6单元是一个字节单元,将其存储在寄存器中时,需要将寄存器的高8位设置为0,将值赋值给寄存器的低8位
编辑:
注:在汇编程序中,数据不能以字母开头,如9038h在汇编中可以写成9138h,而A000h在汇编中要写成0A000h
编译,连接:
使用debug进行调试:
设定ds:bx指向ffff:6,可知ds:0006中内容为37
完成ffff:6单元向ax赋值
循环过程,最终ds值为所得
当出现多次loop指令时,可以不需要使用多次t命令
可以使用 g 标号编码或遇到loop指令时直接用p命令跳过循环
5.4 debug和masm对指令的不同处理
(1),在汇编源程序中,如果用指令访问一个内存单元,则在指令中必须用 [ ]来表示内存单元,如果在 [ ] 里用一个常量idata直接给出内存单元的偏移地址,就要在[ ]前面显示的给出段地址所在的段寄存器
如:mov al,ds:[0]
如果不加段寄存器 如 mov al,[0]
那么编译器masm将指令中的[idata]解释为常量
(2),如果在[ ]里用寄存器,如bx,间接给出内存单元的偏移地址,则段地址默认在ds中,
5.5 loop和[bx]的联合应用
计算ffff:0-ffff:b单元中数据的总和,将其结果存储在dx中
思考存储方式
1,(dx) = (dx) + 内存中的八位数据
2,(dl) = (dl) + 内存中的八位数据
存储方式1的问题是两个运算对象的类型不一样,存储方式2的问题是结果有可能超界
为了解决存储的问题,选择用一个16位寄存器作为中介,将内存单元中的8位数据赋值到一个16位寄存器ax中,再将ax中的数据加到dx上,从而使得两个运算对象类型匹配且不超界
程序示例:
执行结果:
5.6 段前缀
指令mov ax,[bx]中,内存单元的偏移地址由bx给出,而段地址默认存储在ds中,我们可以在访问内存单元的指令中显式的给出内存单元的段地址所在的寄存器
如:mov ax,ds:[bx]
mov ax,cs:[0]
这些出现在访问内存单元的指令中,用于显式的指明内存单元的段地址的
ds:,cs:等,在汇编语言中称为段前缀
5.7 一段安全空间
在8086模式中,随意向一段内存空间写入内容是很危险的,因为这段空间中可能存放着重要的系统数据或代码
在不确定一段内存空间中是否存放着重要的数据或代码时,不能随意的向其中写入内容,我们在操作系统的环境中工作,操作系统管理着所有的资源,也包括内存,我们应该使用操作系统分配的内存空间,但学习汇编语言,我们尽量直接对硬件编程,而不去理会操作系统
总结:
1,直接向一段内存中写入内容
2,这段内存空间不应该存放系统或其它程序的数据或代码,否则写入操作很可能引发错误
3,dos方式下,一般情况,0:200-0:2ff空间中没有系统或其它程序的数据或代码,需要向内存中写入内容时,使用0:200-0:2ff这段空间
5.8 段前缀的使用
将ffff:0-ffff:b单元中的数据复制到0:200-020b单元中
使用段前缀编程: