第五章 [BX]和loop指令
[bx]
表示内存地址,内存地址为bx的值,这里只能使用bxloop
循环指令inc 寄存器
寄存器中的值自增
5.2 Loop指令
- 格式
loop 标号
,cpu执行loop
指令时进行两步操作
- cx=cx-1
- 判断cx中的值是否不为0,不为零跳转至标号处执行程序,如果为零则向下执行
s:
标号,代表一个内存地址,s可替换为任意合法字符- 下面是一个实例计算2的11次方
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
5.3 在DEBUG中跟踪用loop指令实现的循环程序
- 数据长度不一致可以用寄存器暂存数据
- 汇编源程序中数据不能以字母开头,要在前面加0,数据尾部有H表示才是16进制的数据
- 单步执行为
t
命令,跳过循环可以使用p
命令(要在loop命令处使用),跳转到指定地址跟踪使用g 内存地址
实现
5.4 Debug和汇编编译器masm对指令的不同处理
- 在debug中
[0]
表示内存单元0的数据,但在汇编源程序中会被当作0进行处理,在对[bx]
上的处理是一致的
5.5 loop和[bx]的联合应用
- 计算ffff:0-ffff:b单元中的数据的和,结果存储在dx中
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
作为段地址,我们也可以显示指定其他合法寄存器比如 mov ax,ss:[bx]
ds:
,cs:
,ss:
,es:
都可以用于显示地指明内存单元得段地址,这在汇编语言中称为***段前缀***- 在需要频繁切换段地址的时候可以使用***段前缀***
实验4 [bx]和loop的使用
- 编程,向内存
0:200~0:23f
依次传送数据0~63(3fh) - 编程,在1的条件下,程序中只能使用9条指令,包括
mov ax,4c00h
和int21h
;向内存`0:200~0:23f`依次传送数据0~63(3fh)
;解析内存范围等同于20:00~20:3f
assume cs:code
code segment
;初始化
mov ax,20h
mov ds,ax
mov bx,0
mov cx,40h
s: mov [bx],bx
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end
- 下面的的程序功能是将
mov ax,4c00h
之前的指令复制到内存0:200
处,补全程序
;; 复制的是指令数据,从`mov ax,cx`到`loop s`
;; 程序在debug加载时cx存放程序的字节数,我们可以通过其他方式获得“程序退出”指令占用了5个字节,所以要复制的字节数量为cx-5,感觉这个还是有点问题的,因为我们在不运行程序的情况下不能得到cx的值,虽然我们可以随便填充数据让程序可执行拿到cx的值
assume cs:code ;这是伪指令
code segment ;这是伪指令
mov ax,cs ;cs存放了指令的起始地址
mov ds,ax
mov ax,0020h
mov es,ax
mov bx,0
mov cx,17h ;这个程序一共17字节(cx-5 `mov...int 21h`一共占用5个字节,程序初始化时,cx保存了程序的字节数)
s: mov al,[bx]
mov es:[bx],al
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end