1176 字
6 分钟
王爽「汇编语言」学习笔记(五)
数据处理的两个基本问题
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 segmentstart: 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 21hcode endsend 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 21hstart: mov ax, 0s: 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 nopcodesg endsend start运行前:不能正确返回
使用 debug 加载程序,一步步执行指令发现
mov di, offset smov si, offset s2mov 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 21hcode endsend