汇编语言 —— 数据处理的两个基本问题

本章对前面的所有内容是具有总结性的。

计算机是进行数据处理、运算的机器,那么有两个基本的问题就包含在其中:

  1. 处理的数据在什么地方?
  2. 要处理的数据有多长?

对这四个寄存器进行一个总结:

  1. 在 8086CPU 中,只有这 4 个寄存器可以用在 “[…]” 中来进行内存单元的寻址;
  2. 在 “[…]” 中,这 4 个寄存器可以单个出现,或只能以 4 种组合出现:
    • bx 和 si
    • bx 和 di
    • bp 和 si
    • bp 和 di
  3. 只要在 “[…]” 中使用寄存器 bp,而指令中没有显性地给出段地址,段地址就默认在 ss 中。

汇编语言中用 3 个概念来表达数据的位置:

  1. 立即数(idata):直接包含在机器指令中的数据(执行前在 CPU 的指令缓冲器中);
  2. 寄存器:指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名;
  3. 段地址(SA)和偏移地址(EA):指令要处理的数据在内存中,在汇编指令中可用 “[X]” 的格式给出 EA,SA 在某个段寄存器中。

当数据存放在内存中的时候,我们可以用多种方式来给定这个内存单元的偏移地址:

寻址方式小结
寻址方式小结

8086CPU 的指令,可以处理两种尺寸的数据,byte 和 word。所以在机器指令中要指明,指令进行的是字操作还是字节操作。汇编语言中用以下方法处理:

下面的指令中,寄存器指明了指令进行的是字操作。

text

mov ax, 1
mov bx, ds:[0]
mov ds, ax
mov ds:[0], ax
inc ax
add ax, 1000

下面的指令中,寄存器指明了指令进行的是字节操作。

text

mov al, 1
mov al, b1
mov al, ds:[0]
mov ds:[0], al
inc al
add al, 100

在没有寄存器名存在的情况下,用操作符 X ptr 指明内存单元的长度,在汇编指令中可以为 word 或 byte。

下面的指令中,用 word ptr 指明了指令访问的内存单元是一个字单元。

text

mov word ptr ds:[0], 1
inc word ptr [bx]
inc word ptr ds:[0]
add word ptr [bx],2

下面的指令中,用 byte ptr 指明了指令访问的内存单元是一个字节单元。

text

mov byte ptr ds:[0], 1
inc byte ptr [bx]
inc byte ptr ds:[0]
add byte ptr [bx], 2

有些指令默认了访问的是字单元还是字节单元,比如,push [1000H] 就不用指明访问的是字单元还是字节单元,因为 push 指令只进行字操作。


div 是除法指令,使用 div 做除法的时候应注意以下问题:

  1. 除数:有 8 位和 16 位两种, 在一个 reg 或内存单元中;
  2. 被除数:默认放在 AX 或 (DX 和 AX) 中:
    • 若除数 8 位,被除数则为 16 位,默认在 AX 中存放;
    • 若除数为 16 位,被除数则为 32 位,在 DX 和 AX 中存放,DX 存放高 16 位,AX 存放低 16 位。
  3. 结果:
    • 若除数 8 位,则 AL 存储除法操作的商,AH 存储除法操作的余数;
    • 若除数为 16 位,则 AX 存储除法操作的商,DX 存储除法操作的余数。

格式如下:

text

div reg
div 内存单元
16 位除法编程练习

编程,利用除法指令计算 100001 / 100:

首先分析一下,被除数 100001 大于 65535,不能用 ax 寄存器存放,所以只能用 dx 和 ax 两个寄存器联合存放 100001,也就是说要进行 16 位的除法。除数 100 小于 255, 可以在一个 8 位寄存器中存放,但是,因为被除数是 32 位的,除数应为 16 位,所以要用一个 16 位寄存器来存放除数 100。

text

mov dx, 1
mov ax, 86A1H ; (dx) * 10000H + (ax) = 100001

mov bx, 100

div bx
8 位除法编程练习

编程,利用除法指令计算 1001 / 100:

首先分析一下,被除数 1001 可用 ax 寄存器存放,除数 100 可用 8 位寄存器存放,也就是说,要进行 8 位的除法。

text

mov ax, 1001
mov bl,100
div bl

前面我们用 db 和 dw 定义字节型数据和字型数据。dd 是用来定义 dword (double word,双字) 型数据的。比如:

text

data segment
db 1                ; 数据为 01H,在 data:0 处,占 1 个字节
dw 1                ; 数据为 0001H,在 data:1 处,占 1 个字
dd 1                ; 数据为 00000001H,在 data:3 处,占 2 个字
data ends

dup 是一个操作符,在汇编语言中同 db、dw、dd 等一样,也是由编译器识别处理的符号。它是和 db、dw、dd 等数据定义伪指令配合使用的,用来进行数据的重复。

text

db 3 dup (0)                ; 定义了 3 个字节,它们的值都是 0,相当于 db 0,0,0

db 3 dup (0,1,2)            ; 定义了 9 个字节,相当于db 0,1,2,0,1,2,0,1,2

db 3 dup ('abc', 'ABC')     ; 定义了 18 个字节,相当于 db 'abcABCabcABCabcABC'