第五章 bx和loop指令
第五章 [BX]和loop指令
描述性符号约定
(…)表示一个寄存器或内存单元中的内容
idata表示常量
5.1~5.3[BX]和loop及其跟踪
1. [BX]
mov ax,[bx]
该指令中bx存放的是内存单元的偏移地址。该指令将ds:bx处的数据送入ax中。亦即(ax)=((ds)*16+(bx))
mov [bx],ax
表示将ax中的内容送入ds:bx处,亦即((ds)*16+(bx))=(ax)
2. inc 寄存器将寄存器的内容加1,即(寄存器)=(寄存器)+1
3. loop指令的格式:
loop 标号
执行loop指令的操作:
①(cx)=(cx)-1
②判断cx中的值,若(cx)==0,向下执行,若(cx)!=0,则转到标号处执行程序
4. loop指令的使用:计算2^12
Program 5-1
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为一个标号,标识了一个地址,该地址上有一条指令 add ax,ax
总结
(1)cx中存放的是循环次数
(2)loop指令中的标号所标识地址要在前面
(3)要循环执行的程序段,要写在loop和标号的中间
循环功能的程序框架
mov cx,循环次数
s:循环执行的程序段
loop s
5. 在汇编源程序中,数据不能以字母开头,可以在前面加0解决
6. 在debug中,loop指令的标号变成具体的偏移地址
7. debug的命令
G 偏移地址使得DEBUG从当前的CS:IP处开始执行,直到(IP)=偏移地址为止
P用于循环时可以将循环一次性执行完
5.4 Debug和masm对指令的不同处理
masm将[idata]解释为立即数idata。若是内存单元,需要显式指定段寄存器,masm将ds:[idata]解释为ds:idata处的内存单元,masm对于[bx]的处理与debug一致。
5.5 loop和[BX]的联合应用
将ffff:0~ffff:b单元中数据累加,保存在dx中
问题:8位的数据无法送入16位的寄存器,而8位的寄存器累加会溢出
解决:使用一个16位通用寄存器作为中介(如ax),将数据送入al中,再使用ax进行累加。
程序实现:
Program 5-2
assume cs:code
code segment
mov ax,0ffffh;初始化
mov ds,ax
mov bx,0
mov dx,0
mov cx,12
s:mov al,[bx];累加
mov ah,0
add dx,ax
inc bx
loop s
mov ax,4c00h;;程序返回
int 21h
code ends
end
5.6 段前缀
ds:[idata]表示ds:idata处的内存单元
cs:[idata]表示cs:idata处的内存单元
ss:[idata]表示ss:idata处的内存单元
es:[idata]表示es:idata处的内存单元es是附加段寄存器
cs:[bx]表示cs:bx处的内存单元
ss:[bx]表示ss:bx处的内存单元
ds:[bx]表示ds:bx处的内存单元
es:[bx]表示es:bx处的内存单元
出现在访问内存的指令中的用于显式指示内存单元段地址的ds: cs: es: ss:在汇编语言中叫做段前缀
5.7一段安全的空间
一般情况下,DOS和其他合法程序不使用0:200~0:2ff共256个字节的空间
实验4 [BX]和loop的使用
(1) 编程,向内存0:200~0:23f依次传递数据0~63(3fh)。
Program ex-4-1
assume cs:coding
coding segment
mov ax,0h
mov ds,ax
mov bx,23fh
mov cx,64
mov dl,63
;初始化
;ds:bx=0:23f,cx=64,dl=63
s: mov ds:[bx],dl
sub dl,1 ;dl--
sub bx,1 ;bx--
loop s
mov ax,4c00h
int 21h
coding ends
end
(2) 编程,向内存0:200~0:23f依次传递数据0~63(3fh),程序中只能使用9条指令,9条指中包括“mov ax,4c00h”和“int 21h”。
Program ex-4-2
assume cs:code
code segment
mov ax,20h
mov ds,ax
mov bx,0
mov cx,40h;或mov cx,64
s:mov [bx],bl
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end
(3)下面的程序功能是将“mov ax,4c00h"之前的指令复制到内存0:200处,补全程序。上机调试,跟踪运行结果。
assume cs:code
code segment
mov ax, code ;或mov ax, cs
mov ds,ax
mov ax,0020h
mov es,ax
mov bx,0
mov cx, 18h ;或mov cx, 17h ;或sub cx,5
s: mov al,[bx]
mov es:[bx],al
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end
此题有多个答案,因为mov用在寄存器之间传送数据的指令是2个字节,用在寄存器和立即数之间是3个字节
答案1:mov ax,cs (占2个字节)
mov cx,17
答案2:mov ax,code (占3个字节)
mov cx,18
答案3:mov ax,cs 或mov ax,code
把mov cx, 改成 sub cx,5
(因为在载入程序时,cx保存程序的长度,减去5是为减去mov ax,4c00h和int 21h的长度)
答案4:mov ax,cx
mov cx,23
可以用debug来查看指令的长度
