参考书籍:
王爽。汇编语言。北京:清华大学出版社, 2013:161-172
本人菜狗一枚,不敢咬文嚼字,只能站在巨人的肩膀上窥探一下未曾了解的世界。
计算机进行数据处理和运算的两个基本问题
描述性符号:reg 表示寄存器,sreg 表示段寄存器
数据处理指令:读取、写入、运算
指令执行前数据可能存储的位置:CPU 内部、内存、端口
机器码 | 汇编指令 | 指令执行前数据的位置 |
---|---|---|
8E1E0000 | mov bx, [0] | 内存,ds:0 单元 |
89C3 | mov bx, ax | CPU 内部,ax 寄存器 |
BB0100 | mov bx, 1 | CPU 内部,指令缓冲器 |
立即数(idata)
直接包含在机器指令中的数据(执行前在 CPU 指令缓冲器中)
mov ax, 1
or bx, 00010000b ;立即数(idata)在汇编指令中直接给出
mov al, 'a'
寄存器
指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名。
mov ax, bx
mov ds, ax
push bx
mov ds:[0], bx
push ds
mov ss, ax
mov sp, ax
段地址(SA)和偏移地址(EA)
指令要处理的数据在内存中,在汇编指令中可用 [X] 的格式给出 EA, SA 在某个段寄存器中
存放段地址的寄存器是默认的,也可以显性给出
; 段地址默认在 ds 中
mov ax, [0]
mov ax, [di]
mov ax, [bx+8]
mov ax, [bx+si]
mov ax, [bx+si+8]
; 段地址默认在 ss 中
mov ax, [bp]
mov ax, [bp+8]
mov ax, [bp+si]
mov ax, [bp+si+8]
; 显性给出段地址
mov ax, ds:[bp]
mov ax, es:[bx]
寄存器 bx 段地址默认在 ds
寄存器 bp 段地址默认在 ss
寻址地址 | 偏移地址 | 段地址 | 名称 | 常用格式举例 |
---|---|---|---|---|
idata | idata | (ds) | 直接寻址 | [idata] |
[bx] | bx | (ds) | 寄存器间接寻址 | [bx] |
[si] | (si) | (ds) | ||
[di] | (di) | (ds) | ||
[bp] | (bp) | (ss) | ||
[bx+idata] | (bx)+idata | (ds) | 寄存器相对寻址 | 用于结构体:[bx].idata 用于二维数组:[bx][idata] 用于数组:idata[si],idata[di] |
[si+idata] | (si)+idata | (ds) | ||
[di+idata] | (di)+idata | (ds) | ||
[bp+idata] | (bp)+idata | (ss) | ||
[bx+si] | (bx)+(si) | (ds) | 基址变址寻址 | 用于二维数组:[bx][si] |
[bx+di] | (bx)+(di) | (ds) | ||
[bp+si] | (bp)+(si) | (ss) | ||
[bp+di] | (bp)+(di) | (ss) | ||
[bx+si+idata] | (bx)+(si)+idata | (ds) | 相对基址变址寻址 | 用于二维数组:idata[bx][si] 用于表格(结构)中的数组项:[bx].idata[si] |
[bx+di+idata] | (bx)+(di)+idata | (ds) | ||
[bp+si+idata] | (bp)+(si)+idata | (ss) | ||
[bp+di+idata] | (bp)+(di)+idata | (ss) |
通过寄存器名指明要处理的数据的尺寸: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
在没有寄存器名存在的情况下,用操作符 byte / word ptr 指明内存单元的长度
mov word ptr ds:[0], 1
inc word ptr [bx]
inc word ptr ds:[0]
add word ptr [bx], 2
mov byte ptr ds:[0], 1
inc byte ptr [bx]
inc byte ptr ds:[0]
add byte ptr [bx], 2
其他方法
有些指明默认了访问的单元尺寸,如 push 指令只进行字操作
div 是除法指令,div 内存单元
汇编指令 | 商 | 余数 | 含义 |
---|---|---|---|
div type ptr ds:[0] | al | ah | (al) = (ax) / ((ds) * 16 + 0) 的商 (ah) = (ax) / ((ds) * 16 + 0) 的余数 |
div word ptr es:[0] | ax | dx | (ax) = [(ds) * 10000H + (ax)] / ((es) * 16 + 0) 的商 (dx) = [(ds) * 10000H + (ax)] / ((es) * 16 + 0) 的余数 |
div byte ptr [bx+si+8] | al | ah | (al) = (ax) / ((ds) * 16 + (bx) + (si) + 8) 的商 (ah) = (ax) / ((ds) * 16 + (bx) + (si) + 8) 的余数 |
div word ptr [bx+si+8] | ax | dx | (ax) = [(dx) * 10000H + (ax)] / ((ds) * 16 + (bx) + (si) + 8) 的商 (dx) = [(dx) * 10000H + (ax)] / ((ds) * 16 + (bx) + (si) + 8) 的余数 |
; 计算100001 / 100
; 被除数 100001 大于 65535, 进行 16 位除法
mov dx, 1
mov ax, 86AH ;(dx) * 10000H + (ax) = 100001
mov bx, 100
div bx
; 计算 1001 / 100
; 被除数 1001 可用 ax 寄存器存放, 进行 8 位除法
mov ax, 1001
mov bl, 100
div bl
dd 是用来定义 dword(double word,双字)型数据的
data segment
db 1 ; 在 data:0 处定义字节型数据 01H
dw 1 ; 在 data:1 处定义字型数据 0001H
dd 1 ; 在 data:3 处定义双字型数据 00000001H
data ends
dup 是一个操作符,同 db、dw、dd 等一样,也是由编译器处理识别的符号。它是和 db、dw、dd 等数据定义伪指令配合使用的,用来进行数据的重复
dup 的使用格式:
; 定义了 3 个字节, 它们的值都是 0
; 相当于 db 0, 0, 0
db 3 dup (0)
; 定义了 9 个字节, 它们是 0, 1, 2, 0, 1, 2, 0, 1, 2
; 相当于 db 0, 1, 2, 0, 1, 2, 0, 1, 2
db 3 dup (0, 1, 2)
; 定义了 18 个字符, 它们是 'abcABCabcABCabcABC'
; 相当于 db 'abcABCabcABCabcABC'
db 3 dup ('abc', 'ABC')