《汇编语言》- 王爽 个人学习笔记

5.《汇编语言》-王爽第三版学习笔记 [BX]和loop指令

2021-02-23  本文已影响0人  Nonmfly

1.[bx], 和 内存单元的描述

[0] 表示内存单元,它的偏移地址是 0, 段地址在 ds 中,单元的长度(类型)可以由具体指令中的其他操作对象(比如说寄存器)指出
[bx] 也表示内存单元,它的偏移地址在 bx 中,段地址在 ds 中,单元的长度(类型)可以由具体指令中的其他操作对象(比如说寄存器)指出
  1. loop
    循环指令

  2. 描述性的符号 “()”

(ax)表示ax中的内容
(al)表示al中的内容
(20000H)表示内存20000H单元的内容,其中20000H为内存单元的物理地址
(ax),(ds),(al),(cx),(2000H),((ds)*16 + (bx))等都是正确的用法。
(2000:0),((ds):1000H) 是不正确的用法。
(X)的应用:
(1)ax 中的内容为 0010H      =>    (ax)=0010H
(2)2000:1000H 中的内容为 0010H      =>    (21000H)=0010H
(3)mov ax,[2]      =>    (ax) = ((ds)*16+2)
(4)mov [2],(ax)      =>    ((ds)*16+2) = (ax)
(5)add ax,2      =>    (ax)=(ax)+2
(6)add ax,bx      =>    (ax)=(ax)+(bx)
(7)push ax      =>    
        (sp)=(sp)-2
        ((ss)*16+(sp))=(ax)
(8)pop ax      =>    
        (ax)=((ss)*16+(sp))
        (sp)=(sp)+2
(9)“(x)” 所表示的数据有两种各类型: 字节, 字。
       哪种类型有寄存器名或具体的运算决定。比如:
       (al)(bl)(cl)等得到的数据为字节型
       (ax)(bx)(cx)等得到的数据为字节型
       (al)=(20000H),则(20000H)得到的数据为字节型
       (ax)=(20000H),则(20000H)得到的数据为字型

5.1 [BX]

mov ax,[bx]      =>    (ax) = ((ds)*16+(bx))
mov [bx],ax      =>     ((ds)*16+(bx)) = (ax)
mov bx,1
inc bx
// 执行后,(bx) = 2

5.2 Loop 指令
(1)格式: loop 标号

CPU在执行loop 的时候要进行两部操作:
(1)(cx)=(cx)-1
(2)判断 cx 中的值,不为0则转至 标号 处执行程序,如果为 0 则乡下执行。
注意:
     cx 中的值影响着 loop 指令的执行结果,通常(注意,说的是通常)我们用loop指令来实现循环功能,cx中存放循环次数。
assume cs:code
code segment
    mov ax,2
    .... //重复累计做11次 add ax,ax

    mov ax,4c00h
    int 21h
code ends
end
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
/**
* (1) 标号: 汇编语言中,标号代表一个地址,程序中有一个标号 s, 它实际上标识了一个地址,这个地址处有一条指令:add ax,ax
* (2) loop s : CPU 执行 loop s 的时候,需要进行两步操作:
        第一步: (cx)=(cx)-1
        第二步:判断 cx 中的值,不为 0,则转至标号 s 所标识的地址处执行(程序中的指令是 add ax,ax),如果为 0 则执行下一条指令(下一条指令是 mov ax,4c00h)
*/
(1)在 cx 中存放循环次数
(2)loop 指令中的标号所标识的地址要在前面
(3)要循环执行的程序段,要写在 标号 和 loop 指令的中间
    mov cx,循环次数
s:  
    循环执行的程序段
    loop s

5.3 DEBUG中 跟踪 loop 指令实现循环程序

5.4 Debug 和 汇编编译器 masm 对指令的不同处理


89D5AE61-5605-4C5F-BA87-AAD7563A04BD.png
E60D272C-E906-4175-944F-DD044D68DE03.png
汇编源程序中一下指令的含义:
mov al,[0]  =>  (al)=0 ,将常量0送入al中 等同于 mov al,0
mov al,ds:[0]  =>  (al)=((ds)*16+0) ,将内存单元中的数据送入al中
mov al,[bx]  =>  (al)=((ds)*16+bx)  ,将内存单元中的数据送入al中
mov al,ds:[bx]  =>  等同于 mov al,[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 段前缀 : 出现在访问内存单元的指令中,用于显式的指明内存单元的段地址。

(1)mov ax,ds:[bx]  //将一个内存单元的内容送入 ax,这个内存单元的长度为 2字节(字单元),存放一个字, 偏移地址在 bx 中,段地址在 ds 中。
(2)mov ax,cs:[bx]  //将一个内存单元的内容送入 ax,这个内存单元的长度为 2字节(字单元),存放一个字, 偏移地址在 bx 中,段地址在 cs 中。
(3)mov ax,ss:[bx]  //将一个内存单元的内容送入 ax,这个内存单元的长度为 2字节(字单元),存放一个字, 偏移地址在 bx 中,段地址在 ss 中。
(4)mov ax,es:[bx]  //将一个内存单元的内容送入 ax,这个内存单元的长度为 2字节(字单元),存放一个字, 偏移地址在 bx 中,段地址在 es 中。
(5)mov ax,ss:[0]  //将一个内存单元的内容送入 ax,这个内存单元的长度为 2字节(字单元),存放一个字, 偏移地址 0,段地址在 ss 中。
(6)mov ax,cs:[0]  //将一个内存单元的内容送入 ax,这个内存单元的长度为 2字节(字单元),存放一个字, 偏移地址 0,段地址在 cs 中。

5.7 一段安全的空间:
0:200 ~ 0:2FF

5.7 段前缀的使用:
将 内存 ffff:0 ~ ffff:b 单元中的数据复制到 0:200 ~ 0:20B 单元中

assume cs:code
code segment
    mov bx,0
    mov cx,12

s:  mov ax,0ffffh
    mov ds,ax
    mov dl,[bx]

    mov ax,0020h
    mov ds,ax
    mov [bx],dl

    inc bx
    loops

    mov ax,4c00h
    int 21h
code ends
end
assume cs:code
code segment
    mov ax,0020h
    mov ds,ax
    mov bx,0
    mov cx,64

s:  mov [bx],bx
    inc bx
    loop s

    mov ax,4c00h
    int 21h
code ends
end

(2)下面的程序的功能是将“mov ax,4c00h”之前的指令复制到内存0:200处,补全程序。上机调试,跟踪运行结果。

assume cs:code
code segment
    mov ax,code
    mov ds,ax
    mov ax,0020h
    mov es,ax
    mov bx,0
    mov cx,17h

s:  mov al,[bx]
    mov es:[bx]:al
    inc bx
    loop s

    mov ax,4c00h
    int 21h
code ends
end
B82070D5-D1F5-413B-B891-9445AAD63755.png
上一篇 下一篇

猜你喜欢

热点阅读