汇编语言 —— 数据处理的两个基本问题
本章对前面的所有内容是具有总结性的。
计算机是进行数据处理、运算的机器,那么有两个基本的问题就包含在其中:
- 处理的数据在什么地方?
- 要处理的数据有多长?
1 定位处理的数据
1.1 bx, si, di 和 bp
对这四个寄存器进行一个总结:
- 在 8086CPU 中,只有这 4 个寄存器可以用在 “[…]” 中来进行内存单元的寻址;
- 在 “[…]” 中,这 4 个寄存器可以单个出现,或只能以 4 种组合出现:
- bx 和 si
- bx 和 di
- bp 和 si
- bp 和 di
- 只要在 “[…]” 中使用寄存器 bp,而指令中没有显性地给出段地址,段地址就默认在 ss 中。
1.2 汇编语言中数据位置的表达
汇编语言中用 3 个概念来表达数据的位置:
- 立即数(idata):直接包含在机器指令中的数据(执行前在 CPU 的指令缓冲器中);
- 寄存器:指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名;
- 段地址(SA)和偏移地址(EA):指令要处理的数据在内存中,在汇编指令中可用 “[X]” 的格式给出 EA,SA 在某个段寄存器中。
1.3 寻址方式
当数据存放在内存中的时候,我们可以用多种方式来给定这个内存单元的偏移地址:

2 确定数据的长度
8086CPU 的指令,可以处理两种尺寸的数据,byte 和 word。所以在机器指令中要指明,指令进行的是字操作还是字节操作。汇编语言中用以下方法处理:
2.1 通过寄存器名指明要处理的数据的尺寸
下面的指令中,寄存器指明了指令进行的是字操作。
mov ax, 1
mov bx, ds:[0]
mov ds, ax
mov ds:[0], ax
inc ax
add ax, 1000
下面的指令中,寄存器指明了指令进行的是字节操作。
mov al, 1
mov al, b1
mov al, ds:[0]
mov ds:[0], al
inc al
add al, 100
2.2 用操作符指明内存单元的长度
在没有寄存器名存在的情况下,用操作符 X ptr 指明内存单元的长度,在汇编指令中可以为 word 或 byte。
下面的指令中,用 word ptr 指明了指令访问的内存单元是一个字单元。
mov word ptr ds:[0], 1
inc word ptr [bx]
inc word ptr ds:[0]
add word ptr [bx],2
下面的指令中,用 byte ptr 指明了指令访问的内存单元是一个字节单元。
mov byte ptr ds:[0], 1
inc byte ptr [bx]
inc byte ptr ds:[0]
add byte ptr [bx], 2
2.3 其他方法
有些指令默认了访问的是字单元还是字节单元,比如,push [1000H]
就不用指明访问的是字单元还是字节单元,因为 push 指令只进行字操作。
3 学习三个指令
3.1 div 指令
div 是除法指令,使用 div 做除法的时候应注意以下问题:
- 除数:有 8 位和 16 位两种, 在一个 reg 或内存单元中;
- 被除数:默认放在 AX 或 (DX 和 AX) 中:
- 若除数 8 位,被除数则为 16 位,默认在 AX 中存放;
- 若除数为 16 位,被除数则为 32 位,在 DX 和 AX 中存放,DX 存放高 16 位,AX 存放低 16 位。
- 结果:
- 若除数 8 位,则 AL 存储除法操作的商,AH 存储除法操作的余数;
- 若除数为 16 位,则 AX 存储除法操作的商,DX 存储除法操作的余数。
格式如下:
div reg
div 内存单元
编程,利用除法指令计算 100001 / 100:
首先分析一下,被除数 100001 大于 65535,不能用 ax 寄存器存放,所以只能用 dx 和 ax 两个寄存器联合存放 100001,也就是说要进行 16 位的除法。除数 100 小于 255, 可以在一个 8 位寄存器中存放,但是,因为被除数是 32 位的,除数应为 16 位,所以要用一个 16 位寄存器来存放除数 100。
mov dx, 1
mov ax, 86A1H ; (dx) * 10000H + (ax) = 100001
mov bx, 100
div bx
编程,利用除法指令计算 1001 / 100:
首先分析一下,被除数 1001 可用 ax 寄存器存放,除数 100 可用 8 位寄存器存放,也就是说,要进行 8 位的除法。
mov ax, 1001
mov bl,100
div bl
3.2 伪指令 dd
前面我们用 db 和 dw 定义字节型数据和字型数据。dd 是用来定义 dword (double word,双字) 型数据的。比如:
data segment
db 1 ; 数据为 01H,在 data:0 处,占 1 个字节
dw 1 ; 数据为 0001H,在 data:1 处,占 1 个字
dd 1 ; 数据为 00000001H,在 data:3 处,占 2 个字
data ends
3.3 dup 操作符
dup 是一个操作符,在汇编语言中同 db、dw、dd 等一样,也是由编译器识别处理的符号。它是和 db、dw、dd 等数据定义伪指令配合使用的,用来进行数据的重复。
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'