8.5 ~ 8.9
《汇编语言(第3版)》8.5 ~ 8.9、《零基础入门学习汇编语言》P39 ~ 41
8.5 指令要处理的数据有多长
8086 CPU 的指令,可以处理两种尺寸的数据,byte 和 word。所以在机器指令中要指明,指令进行的是字操作还是字节操作。对于这个问题,汇编语言中用以下方法处理
通过寄存器名指明要处理的数据的尺寸
# 下面的指令中,寄存器指明了指令进行的是字操作 mov ax,1 mov bx,ds:[0] mov ds,ax mov ds:[0],ax inc ax add ax,1000 # 下面的指令中,寄存器指明了指令进行的是字节操作 mov al,1 mov al,bl mov al,ds:[0] mov ds:[0],al inc al add al,100
在没有寄存器名存在的情况下,用操作符 X ptr 指明内存单元的长度,X 在汇编指令中可以为 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
其他方法(有些指令默认了访问的是字单元还是字节单元) 比如:push [1000H] 就不用指明访问的是字单元还是字节单元,因为 push 指令只进行字操作。
8.7 div 指令
div 是除法指令(division),使用 div 作除法的时候
- 除数:8 位或 16 位,在寄存器或内存单元种
- 被除数:(默认)放在 AX 或 DX 和 AX 中
除数 | 被除数 |
---|---|
8 位 | 16 位 (AX) |
16 位 | 32 位 (DX+AX) |
结果放在
除数 | 8 位 | 16 位 |
---|---|---|
商 | AL | AX |
余数 | AH | DX |
div 指令格式
- div reg
- div 内存单元
div 指令示例与含义
- div byte ptr ds:[0]
- (al)=(ax)/((ds)×16+0) 的商;
- (ah)=(ax)/((ds)×16+0) 的余数
- div word ptr es:[0]
- (ax)=[(dx)×10000H+(ax)]/((ds)×16+0) 的商;
- (dx)=[(dx)×10000H+(ax)]/((ds)×16+0) 的余数
- div byte ptr [bx+si+8]
- (al)=(ax)/((ds)×16+(bx)+(si)+8) 的商;
- (ah)=(ax)/((ds)×16+(bx)+(si)+8) 的余数
- div word ptr [bx+si+8]
- (ax)=[(dx)+10000H+(ax)]/((ds)×16+(bx)+(si)+8) 的商;
- (dx)=[(dx)+10000H+(ax)]/((ds)×16+(bx)+(si)+8) 的余数
编程:利用除法指令计算 100001/100。
我们首先分析一下,被除数 100001 大于 65535,不能用 ax 寄存器存放,所以我们要用 dx 和 ax 两个寄存器联合存放 100001,也就是说要进行 16 位的除法。
除数 100 小于 255,可以在一个 8 位寄存器中存放,但是,因为被除数是 32 位的,除数应为 16 位,所以要用一个 16 位寄存器来存放除数 100。
因为要分别为 dx 和 ax 赋 100001 的高 16 位值和低 16 位值,所以应先将 100001 表示为十六进制形式:186A1H。
编程实现
mov dx,1
mov ax,86A1H # (dx)×10000H+(ax)=100001
mov bx,100
div bx
程序执行后,(ax)=03E8H(即 1000),(dx)=1(余数为 1)。
8.8 伪指令 dd
我们用 db 和 dw 定义字节型数据和字型数据。
dd 是用来定义 dword(double word 双字)型数据的。
示例
data segment
db 1
dw 1
dd 1
data ends
在 data 段中定义了三个数据
- 第一个数据为 01H,在 data:0 处,占 1 个字节;
- 第二个数据为 0001H,在 data:1 处,占 1 个字;
- 第三个数据为 00000001H,在 data:3 处,占 2 个字;
8.9 dup
dup 是一个操作符,在汇编语言中同 db、dw、dd 等一样,也是由编译器识别处理的符号。
它是和 db、dw、dd 等数据定义伪指令配合使用的,用来进行数据的重复。
dup 示例
db 3 dup (0) # 定义了 3 个字节,它们的值都是 0,相当于 db 0,0,0
db 3 dup (0,1,2) # 定义了 9 个字节,它们是 0、1、2、0、1、2、0、1、2,相当于 db 0,1,2,0,1,2,0,1,2
db 3 dup ('abc','ABC') # 定义了 18 个字节,它们是 'abcABCabcABCabcABC',相当于 db'abcABCabcABCabcABC'
可见,dup 的使用格式如下
- db 重复的次数 dup (重复的字节型数据)
- dw 重复的次数 dup (重复的字型数据)
- dd 重复的次数 dup (重复的双字数据)