前言
在汇编中,我们有时会遇到需要循环的情况,这时就需要loop指令来简化代码,而[bx]和loop指令联用则能达到更方便的功能。

先补点寄存器知识
在8086CPU下,寄存器eax为位寄存器,ah、al分别为ax的高、低8位寄存器,即ax的前、后两半。bx、cx、dx同理~
需要注意的是,汇编中的mov、add等指令只能对同样长度的寄存器&空间使用。

简说[bx]
来看看下面的代码:

mov ax,[bx]

它的功能很简单,即将位于内存中ds:bx的数据送入ax寄存器。
而下面的代码:

mov [bx],ax

则是与上面相反,将ax寄存器中的数据送入内存中ds:bx的位置。
可以看到,[bx]的含义即将ds视为段地址、bx视为偏移地址所指向的内存中数据。

loop指令
有点高级语言编程基础的人一看到loop一定会知道是循环。的确,汇编中loop也是循环指令,但它和其他语言的循环有着不小的区别。
首先了解一下loop指令的格式:loop 标号。当程序执行到loop指令时,会进行如下操作:
(1)cx寄存器中的值自减1
(2)判断cx寄存器的值是否为0,为0则向下执行,不为0则转到标号处运行
由此可见,loop指令可以通过改变cx的值实现计数。
简单做个题目~
用循环计算2100

assume cs:code
code segment
    mov ax,1
    mov cx,100
p:  add ax,ax
    loop p
    mov ax,4c00h
    int 21h
code ends
end

联合使用[bx]和loop指令
直接做个题吧:
计算ffff:0~ffff:b单元中数据的和,结果存在dx中。
首先要明确:ffff:0~ffff:b单元中的数据为8位,而dx为16位寄存器,故不能直接累加。
解决办法:用16位寄存器ax作中介,先将一个单元的数据转到al(ax的后八位,见第一节),再用ax累加到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

再来一个:
将ffff:0~ffff:b单元的数据复制到0:200~0:20b单元中
说明:由于CPU限制,mov指令不能直接把单元中的数据转移到另外一个单元,故要用一个寄存器中转。

assume cs:code
code segment
    mov ax,0ffffh
    mov ds,ax
    mox ax,0020h
    mov es ax
    mox bx,0
    mov cx,12
s:  mov dl,[bx]
    mov es:[bx],dl
    inc bx
    loop s
    mov ax,4c00h
    int 21h
code ends
end

结语
今天我们学习了在汇编中使用循环及[bx],需要实操以熟练。我是faryou,下次再见!

标签: 汇编(asm), 8086CPU

添加新评论