第五章 [bx]和loop指令
1. [bx]和内存单元的描述
在debug中mov ax,[0]表示将ds:0中的字型数据送入ax寄存器,而在编译器中此命令表示将0数据送入ax,则需改为mov ax,[bx]。间直接是编译器将内存单元送入ax。
完整描述一个内存单元:1.内存单元的地址,2.内存单元的长度(类似al字节型,ax字型)
2.loop
loop循环的意思
3.我们定义的描述性的符号:“()”
用“( )”表示一个寄存器或一个内存单元的内容,(al)、(20000H)、((ds)*16+(bx))
比如add ax,2 描述为:(ax) = (ax)+2
(X)可表示两种数据类型:字,字节。取决于寄存器或具体的运算比如(al)表示字节型数据(ax)表示字型数据。
4.约定符号idata表示常量
例如mov ax,[idata] 可表示mov ax,[1]、mov ax,[5]。mov ax,idata可表示mov ax,1、 mov ax,3。等等
5.1 [bx]
mov ax,[bx],可以看成是:mov bx,idata mov ax,[bx]
问题5.1
需要注意的是数据类型是字节型还是字型,其他就跟着题目看就是了。
5.2 loop指令
loop指令与cx通用寄存器有关,执行loop时要进行两步操作:1.(cx) = (cx)-1 、2.判断(cx)不为0则执行标号处程序。例:求2的12次方
assume cs:code
code segment
mov ax,2
mov cx,11
s: add ax,ax
loop s
mov ax,4c00h
int 21h
code ends
end
其中s是标号,当cx不为0时转至s处程序。
问题5.2 用加法计算123*236
assume cs:code
code segment
mov ax,0
mov cx,236
s: add ax,123
loop s
mov ax,4c00h
int 21h
code ends
end
问题5.3 上面程序循环236次可以改进程序为循环123次
assume cs:code
code segment
mov ax,0
mov cx,123
s: add ax,256
loop s
mov ax,4c00h
int 21h
code ends
end
5.3 在debug中跟踪用loop指令实现的循环程序
问题:计算ffff:0006单元中的数乘以3结果存储在dx中
(1)考虑dx存储范围:ffff;0006是字节型数据0~255,乘3不会超过65535。
(2)用哪个寄存器进行累加:先赋值给ax,在用dx累加。
(3)ax是16位,ffff:0006单元是字节型,长度不一样如何赋值:令(ah)=0、(al)=(ffff6H)
编程如下:
assume cs:code
code segment
mov ax,0ffffh
mov ds,ax
mov bx,6
mov al,[bx]
mov ah,0
mov dx,0
mov cx,3
s: add dx,ax
loop s
mov ax,4c00h
int 21h
code ends
end
注意:汇编程序中,数据不能以字母开头。
debug执行情况如下:
将上面问题改进 将ffff:0006中的数据乘以123次:只需将(cx)=123即可,执行过程中用t一步一步太麻烦可以用g命令
当执行loop指令时不想执行123次怎么办呢?当遇到loop指令时可以用p命令
5.4 Debug和汇编编译器masm对指令的不同处理
在以下程序
mov ax,2000
mov ds,ax
mov al,[0]
mov bl,[1]
mov cl,[2]
mov dl,[3]
debug中表现为:
在汇编编译器中:
可以看出“[idata]”在debug和汇编编译器中的不同处理,在汇编编译器中[idata]会被编译为idata值所以在汇编编译器中需要使用中间寄存器(比如bx)将idata送入“[ ]”(比如[bx])中。也可以用显示给出地址:mov al,ds:[0]
5.5 loop和[bx]的联合应用
计算ffff:0~ffff:b单元的数据和,结果存入dx中。
(1)是否会超出范围:((0~255) *12)<65535不会超出范围。
(2)能否直接存入dx:内存一个单元为8位数据,dx为16位寄存器,不能。
(3) 能否将(dh)=0,(dl)=(ffff:0~b),不能会造成进位丢失。
和5.3节一样只是内存编译地址在变化每次+1.
写出程序:
MOV AX,0ffffH MOV DS,AX mov bx,0 mov dx,0 mov cx,12 s: mov ah,0 mov al,[bx] add dx,AX inc bx loop s 编译debug查看如下:
5.6 段前缀
访问内存单元时可以显示给出段地址例如:mov ax,ds:[bx] mov ax,cs:[0]等等
5.7 一段安全的空间
在不能确定一段内存空间中是否存放着重要的数据或代码时,不能随意向其中写入数据,我试了一下结果debug卡死了。
5.8 段前缀的使用
将内存ffff:0~b,单元的数据复制到0:200~20b单元中,
编写程序:
mov AX,0ffffH mov ds,AX mov ax,20H mov es,ax mov bx,0 mov cx,12 s: mov al,ds:[bx] mov es:[bx],al inc bx loop s
实验4 [bx] 和loop的使用
(1)向0:200~0:23f依次传送数据0~63
(2)将上面改为9条指令,上面程序刚刚好。
(3)
程序如下。
1.复制的时数据,从cs :ip来
2.cx需要用debug试出来。先使(cx)=1,用debug u命令查看指令长度