第五章 [BX]和loop指令
描述一个内存单元需要两种信息:(1)内存单元的地址(2)内存单元的长度(类型)
[bx]表示一个内存单元,它的偏移地址在bx中,这个内存单元的长度取决于送入的寄存器的长度。eg:ax就是一个字,al就是一个字节。段地址在ds中。
“()”的定义:表示一个寄存器或一个内存单元中的内容。
“()”中的元素可以有三种类型:寄存器名、段寄存器名、内存单元的物理地址(一个20位数据)。
“(X)”所表达的数据有两种类型:字节和字,是哪种类型由寄存器名或具体的运算决定。
idata表示常量。
5.1[bx]
5.2 Loop指令
格式:loop标号
loop执行的操作:(1)(cx)=(cx)-1(2)判断cx中的值,不为零则转至标号处执行程序,如果为零则向下执行。(注意执行的顺序)
乘法可以转化为加法的循环运算,循环次数越少,效率越高。
5.3在Debug中跟踪用loop指令实现的循环程序
注:要保存某个值的时候要考虑溢出的问题,不超过65535用-x寄存器,不超过256用-l寄存器。
8位寄存器向16位寄存器赋值:这里的赋值只是指数值相等,他们的数据长度并不相等,先把高位寄存器的值改为00H,再把低位寄存器的值修改。
(问:不能直接赋值?这难道意味着汇编不存在自动的类型转换?)
在汇编源程序中,数据不能以字母开头。纯字母的数据要以0开头。
5.4Debug和汇编编译器Masm对指令的不同处理
mov ax,[0]在debug中表示把ds:[0]的数据传给ax,但在masm的编译器中被当作mov ax,0处理。
Debug将[idata]解释为一个内存单元,idata为偏移地址;编译器将[idata]解释为idata。
若要在编译器中用[idata]的格式直接给出内存单元的偏移地址则需要在[]前面显式的给出段寄存器 eg:mov ax,ds:[0]。
注:[bx]就不需要加段寄存器。
5.5 loop和[bx]的联合应用
8位数据累加到16位寄存器的方法:先把8位数据赋值到16位寄存器中再累加16位寄存器。(考虑到的问题:类型的匹配和结果的不超界)
5.6段前缀
用于显式地指明内存单元地段地址的ds:、cs:、ss、es:。
5.7一段安全的空间
在8086模式中随意向一段内存空间写入内容是很危险的。
一般DOS和其他合法程序都不会使用0:200-0:300这段空间(256字节)。
在不确定一段内存空间中是否存放着重要的数据或代码的时候,不能随意向其中写入内容。
引:我们在操作系统的环境中工作,操作系统会管理所有的资源也包括内存,如果需要向内存空间写入数据的话,要使用操作系统给我们分配的空间,而不应直接用地址任意制定内存单元。
在运行于CPU保护模式下的操作系统中不理会操作系统用汇编语言去操作真实的硬件是根本不可能的,硬件已经被这些操作系统利用CPU保护模式所提供的功能全面而严格地管理了。
但DOS是运行在CPU实模式的,没有能力对硬件系统进行全面、严格地管理。
5.8段前缀的使用
灵活转变段前缀。
复制段操作中可以通过使用多个段寄存器用于存放多个段地址,这样可以省略循环中重复设置程序段的操作。