王爽「汇编语言」学习笔记(五)
6 min
数据处理的两个基本问题
bx、si、di、bp
- 只有这 4 个寄存器可以在
[...]中进行内存单元的寻址 - 它们只能单个出现或者以 bx 和 si、bx 和 di、bp 和 si、bp 和 di 的组合出现
- bp 的段地址默认在 ss 中
机器指令处理的数据所在位置
- 指令在执行前,所要处理的数据可以在:CPU 内部、内存、端口
汇编语言中数据位置的表达
- 立即数(idata):执行前在 CPU 指令缓冲器中
- SA 和 EA:指令要处理的数据在内存中
寻址方式

记一下名字即可
指令要处理的数据有多长?
push 指令只进行字操作
寻址方式的综合应用
用 bx 定位整个结构体,用 idata 定位结构体中的某一个数据项,用 si 定位数组项中的每个元素
div 指令
- 除数:8 位和 16 位两种
- 被除数:位数是除数的两倍,存放在 ax 、dx 寄存器
- dx 存放高 16 位,ax 存放低 16 位
- 结果
- 除数为 8 位:al 存商,ah 存余数
- 除数为 16 位:ax 存商,dx 存余数
伪指令 dd
dd:dword (double word)
dup
使用格式:db 重复次数 dup (重复的字节型数据)
Lab 7
assume cs:code
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
;以上是表示21年的21个字符串
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;以上是表示21年公司总收入的21个dword型数据
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
;以上是表示21年公司雇员人数的21个word型数据
data ends
table segment
db 21 dup('year summ ne ?? ')
table ends
code segment
start: mov ax, table
mov ds, ax
mov ax, data
mov es, ax
mov bx, 0
mov di, 0
mov cx, 21
s0: mov si, 0
push di
mov ax, di
add di, ax
mov ax, es:[di+0]
mov [bx].0[si], ax
add si, 2
add di, 2
mov ax, es:[di+0]
mov [bx].0[si], ax
pop di
; year
mov si, 0
push di
mov ax, di
add di, ax
mov ax, es:[di+84]
mov [bx].5[si], ax
add si, 2
add di, 2
mov ax, es:[di+84]
mov [bx].5[si], ax
pop di
; summ
mov si, 0
mov ax, es:[di+168]
mov [bx].10[si], ax
; ne
add bx, 16
add di, 2
loop s0
mov ax, 4c00h
int 21h
code ends
end start转移指令的原理
依据位移进行转移的 jmp 指令
- 段内短转移:
jmp short 标号- IP 修改范围:-128 ~ 127
- (IP) = (IP) + 8 位位移
- 对应机器码中不包含转移的目的地址,包含的是下一条指令到标号地址到位移差
- 位移用补码表示
- 段内近转移:
jmp near ptr 标号- IP 修改范围:-32768 ~ 32767
- (IP) = (IP) + 16 位位移
转移到目的地址在指令中的 jmp 指令
- 段间转移:
jmp far ptr 标号
转移地址在 16 位寄存器中的 jmp 指令
jmp 16位寄存器
转移地址在内存中的 jmp 指令
jmp word ptr 内存单元地址(段内转移)jmp dword ptr 内存单元地址(段间转移)
jcxz 指令
jcxz 标号- 若 cx = 0,(IP) = (IP) + 8 位位移
loop 指令
所有循环指令都是短指令
Lab 8
assume cs:codesg
codesg segment
mov ax, 4c00h
int 21h
start: mov ax, 0
s: nop
nop
mov di, offset s
mov si, offset s2
mov ax, cs:[si]
mov cs:[di], ax
s1: mov ax, 0
int 21h
mov ax, 0
s2: jmp short s1
nop
codesg ends
end start运行前:不能正确返回
使用 debug 加载程序,一步步执行指令发现
mov di, offset s
mov si, offset s2
mov ax, cs:[si]
mov cs:[di], ax将 s 处的指令修改为了 s2 处的指令,即
s: nop
nop变成了 jmp short s1 ,但是由于机器码记录的是位移差,因此执行 jmp short s 之后再次执行 s 处的 jmp short s1 会跳转到奇怪的指令处,从而不能正确返回
Lab 9
assume cs:code
; 绿色 00000010B
; 绿底红色 00100100B
; 白底蓝色 01110001B
; starts from B87A0H
code segment
mov ax, 0B87AH
mov ds, ax
mov bx, 0
mov ah, 'w'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, 'e'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, 'l'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, 'c'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, 'o'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, 'm'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, 'e'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, ' '
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, 't'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, 'o'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, ' '
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, 'm'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, 'a'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, 's'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, 'm'
mov al, 00000010B
mov word ptr [bx], ax
add bx, 2
mov ah, '!'
mov al, 00000010B
mov word ptr [bx], ax
mov ax, 4c00h
int 21h
code ends
end