汇编语言学习笔记5——[BX]和loop指令

时间:2021-08-21 03:33:53
[bx]指令

在使用masm对汇编代码进行编译时,[0]会被认为是0H,而不是偏移地址为0的内存地址的值。
mov ax,[0]这句代码经masm编译后会将0H送入ax,而不是对应内存中的值。在masm中可以用[bx]的格式来表示内存地址。

mov bx,0
mov ax,[bx]

如果想要在masm中使用debug中的格式,需要加上段地址,即mov ax,ds:[0]

loop指令

loop用来执行循环操作,寄存器cx中存放着循环次数。
执行loop时有两步操作:

  • cx = cx - 1;
  • 判断cx中的值,不为零则转至标号(循环语句偏移地址)处执行程序,为零则向下执行。

计算2^100^:

assume cs:code
code segment
 start: mov ax,2
        mov cx,99       ;循环次数为99
        s:add ax,ax     ;循环的内容
        loop s          ;执行循环

        mov ax,4c00h
        int 21h
code ends
end start
汇编源程序中,数据不能以字母开头

所以大于9FFFH的16进制要在前面加一,比如mov ax 0ffffH

段前缀

在指令mov ax,[bx]中,bx为内存单元的偏移地址,而段地址默认在ds中,这个指令也可以写成mov ax,ds:[bx],其中ds就是段前缀,也可以为cs、ss、es。

一段安全的空间

在DOS方式下,DOS和其它合法的程序一般都不会使用0:200~0:2FF的256个字节的空间。所以,我们使用这段空间是安全的。

小练习

将ffff:0-ffff:b中的数据复制到0:200-0:20b中:

assume cs:code
code segment
    mov bx,0        ;偏移地址从零开始
    mov cx,12       ;循环12次
s:  mov ax,0ffffh
    mov ds,ax
    mov dl,[bx]
    mov ax,0020h
    mov ds,ax
    mov [bx],dl
    inc bx
    loop s
    mov ax,4c00h
    int 21h
code ends
end

上面代码中,每次循环都要修改两次段寄存器ds的数据,效率比较低。我们可以使用另外一个寄存器存放0020h这个段地址,改进后代码如下:

assume cs:code
code segment
    mov ax,0ffffh
    mov ds,ax
    mov ax,0020h
    mov es,ax       ;使用附加段寄存器es替代
    mov 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