汇编 Memo

汇编 Memo

int 21h DOS 中断的核心功能集

在 8086 汇编的int 21h执行时,CPU 会自动暂停当前程序、保存 “现场” 到堆栈,压栈的顺序是固定的,从栈顶到栈底的顺序为:

  1. 标志寄存器(Flags)(2 字节):先把当前程序的状态标志(比如进位、溢出等)压入栈;
  2. 代码段寄存器(CS)(2 字节):再把当前程序的代码段地址压入栈;
  3. 指令指针寄存器(IP)(2 字节):最后把当前程序的指令偏移地址压入栈。

这个顺序是 8086 中断机制的固定逻辑(因为后续iret返回时,会按 “IP → CS → Flags” 的顺序弹出恢复现场)。

一、控制台输入 / 输出功能

AH 值 功能描述 参数要求 返回结果
01H 键盘输入字符(带屏幕回显) AL = 输入的 ASCII 字符
02H 屏幕输出单个字符 DL = 要输出的 ASCII 字符
07H 键盘输入字符(无回显) AL = 输入的 ASCII 字符
09H 屏幕输出字符串 DS:DX = 字符串首地址(字符串必须以$结尾)
0AH 键盘输入字符串到缓冲区 DS:DX = 缓冲区首地址(缓冲区第 1 字节 = 最大长度,第 2 字节 = 实际输入长度) 缓冲区第 3 字节开始存输入的字符串

二、文件操作功能

AH 值 功能描述 参数要求 返回结果
3CH 创建新文件 DS:DX = 文件名首地址;CX = 文件属性(0 = 普通文件) AX = 文件句柄(失败则 AX = 错误码)
3DH 打开已存在的文件 DS:DX = 文件名首地址;AL = 打开方式(0 = 读,1 = 写,2 = 读写) AX = 文件句柄(失败则 AX = 错误码)
3FH 从文件读数据 BX = 文件句柄;CX = 要读取的字节数;DS:DX = 数据缓冲区地址 AX = 实际读取的字节数(0 = 文件结束)
40H 向文件写数据 BX = 文件句柄;CX = 要写入的字节数;DS:DX = 数据缓冲区地址 AX = 实际写入的字节数
3EH 关闭文件 BX = 文件句柄 无(失败则 AX = 错误码)

三、程序控制 / 系统功能

AH 值 功能描述 参数要求 返回结果
25H 设置中断向量 AL = 中断号;DS:DX = 中断服务程序首地址
35H 获取中断向量 AL = 中断号 ES:BX = 中断服务程序首地址
4CH 程序退出并返回 DOS AL = 程序返回码

逻辑运算

  1. 乘法

  2. 除法

串处理指令

一、核心规则

  1. 固定寄存器/段关联
    1. 源串:DS:SI(数据段+源变址寄存器),仅 LODS 指令可单独使用 DS:SI
    2. 目标串:ES:DI(附加段+目的变址寄存器),MOVS/STOS/SCAS 强制依赖 ES:DI,不可替换;
    3. 计数器:CX(存储串长度,所有重复前缀均依赖 CX 控制循环次数);
    4. 方向标志:DF(控制 SI/DI 的增减方向:CLD 指令置 DF=0,正向递增;STD 指令置 DF=1,反向递减)。
  2. 段寄存器初始化要求
    1. ASSUME 伪指令仅声明段寄存器与段的关联关系,不实际给段寄存器赋值;
    2. 8086 架构不允许段寄存器直接接收立即数赋值(如 mov ds, data 非法),必须通过通用寄存器(如 AX)中转;
    3. 示例模板:mov ax, data → mov ds, ax(初始化数据段)、mov ax, extra → mov es, ax(初始化附加段)。
  3. 操作单位区分
    1. 字节操作(指令后缀 B):每次处理 1 字节,SI/DI 按 1 递增/递减;
    2. 字操作(指令后缀 W):每次处理 2 字节(1 个字),SI/DI 按 2 递增/递减。

二、核心串操作指令(按用途分类)

指令 功能说明 核心操作(DF=0 正向场景) 适用重复前缀
MOVSB 字节串复制 ES:[DI] = DS:[SI],随后 SI+1DI+1 REP
MOVSW 字串复制 ES:[DI] = DS:[SI],随后 SI+2DI+2 REP
CMPSB 字节串比较(判断是否相等) DS:[SI] - ES:[DI](仅影响标志位,不改变操作数),随后 SI+1DI+1 REPE/REPZREPNE/REPNZ
CMPSW 字串比较(判断是否相等) DS:[SI] - ES:[DI](仅影响标志位),随后 SI+2DI+2 REPE/REPZREPNE/REPNZ
SCASB 字节串查找(查找 AL 中的目标字符) AL - ES:[DI](仅影响标志位),随后 DI+1 REPE/REPZREPNE/REPNZ
SCASW 字串查找(查找 AX 中的目标字) AX - ES:[DI](仅影响标志位),随后 DI+2 REPE/REPZREPNE/REPNZ
LODSB 加载字节串到 AL AL = DS:[SI],随后 SI+1 极少使用(重复加载无实际意义)
LODSW 加载字串到 AX AX = DS:[SI],随后 SI+2 极少使用
STOSB AL 内容存储到字节串 ES:[DI] = AL,随后 DI+1 REP
STOSW AX 内容存储到字串 ES:[DI] = AX,随后 DI+2 REP

三、重复前缀(控制指令循环逻辑)

重复前缀 含义 循环终止条件 典型应用场景
REP 无条件重复 CX = 0 时终止 串复制(MOVS)、串填充(STOS
REPE/REPZ 相等/结果为零则重复 CX = 0;② ZF = 0(比较结果不相等),满足任一即终止 串比较(验证两串是否完全相等,找第一个不相等字符)
REPNE/REPNZ 不相等/结果非零则重复 CX = 0;② ZF = 1(比较结果相等),满足任一即终止 串查找(找第一个匹配目标字符/字的位置)

四、典型实用示例(可直接复用)

1. 字节串复制(MOVSB + REP)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.8086
data segment
src_db 'asd$' ; 源字节串(4字节:a、s、d、$)
data ends
extra segment
dst_db 4 dup(?) ; 目标字节串(预留4字节空间)
extra ends
code segment
assume cs:code, ds:data, es:extra
main:
; 初始化数据段寄存器DS
mov ax, data
mov ds, ax
; 初始化附加段寄存器ES(目标串依赖ES:DI,必须初始化)
mov ax, extra
mov es, ax

lea si, src_db ; SI指向源串偏移地址(DS:SI定位源串)
lea di, dst_db ; DI指向目标串偏移地址(ES:DI定位目标串)
mov cx, 4 ; 复制长度=4字节(与源串长度一致)
cld ; 置DF=0,正向递增复制
rep movsb ; 重复复制:直到CX=0

; 程序正常退出
mov ah, 4Ch
int 21h
code ends
end main

2. 字节串填充(STOSB + REP)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.8086
extra segment
buf_db 10 dup(?) ; 预留10字节缓冲区
extra ends
code segment
assume cs:code, es:extra
main:
mov ax, extra
mov es, ax ; 初始化ES指向目标段(填充操作依赖ES:DI)

lea di, buf_db ; DI指向缓冲区偏移地址
mov al, 0 ; 填充值:0(可改为任意字节值,如'A'、0FFh等)
mov cx, 10 ; 填充长度=10字节
cld ; 正向填充
rep stosb ; 重复填充:ES:[DI] = AL,DI递增,直到CX=0

mov ah, 4Ch
int 21h
code ends
end main

3. 字节串查找(SCASB + REPNE)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.8086
extra segment
str_db 'hello8086$' ; 待查找的字节串(长度=7字节)
extra ends
code segment
assume cs:code, es:extra
main:
mov ax, extra
mov es, ax ; 初始化ES指向待查找串所在段

lea di, str_db ; DI指向串偏移地址
mov al, '8' ; 目标查找字符(存储在AL中)
mov cx, 7 ; 查找范围:前7字节
cld ; 正向查找
repne scasb ; 不相等则继续,找到则ZF=1,终止循环

; 查找结果判断
jz find_ok ; ZF=1 → 找到目标字符
jmp find_fail ; ZF=0 → 未找到

find_ok:
; 此处可添加找到后的处理逻辑(如记录位置)
jmp exit
find_fail:
; 此处可添加未找到的处理逻辑
exit:
mov ah, 4Ch
int 21h
code ends
end main

4. 字节串比较(CMPSB + REPE)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.8086
data segment
str1_db 'abc$' ; 第一个比较串(长度=3字节)
data ends
extra segment
str2_db 'abd$' ; 第二个比较串(长度=3字节)
extra ends
code segment
assume cs:code, ds:data, es:extra
main:
; 初始化DS和ES,分别指向两个比较串所在段
mov ax, data
mov ds, ax
mov ax, extra
mov es, ax

lea si, str1_db ; SI指向str1偏移(DS:SI)
lea di, str2_db ; DI指向str2偏移(ES:DI)
mov cx, 3 ; 比较长度=3字节
cld ; 正向比较
repe cmpsb ; 相等则继续,直到CX=0或找到不相等字符

; 比较结果判断
jz str_equal ; ZF=1且CX=0 → 两串完全相等
jmp str_not_equal ; 否则 → 不相等

str_equal:
; 两串相等的处理逻辑
jmp exit
str_not_equal:
; 两串不相等的处理逻辑
exit:
mov ah, 4Ch
int 21h
code ends
end main

五、易错点速记

  1. 遗漏 ES 初始化:MOVS/STOS/SCAS 指令强制依赖 ES:DI,未初始化ES 会导致访问非法内存,程序崩溃;
  2. 方向标志未显式设置:默认 DF 状态不确定,务必用 CLD(正向)或 STD(反向)显式指定,避免 SI/DI 增减方向错误;
  3. 串长度与 CX 不匹配:CX 值大于串实际长度会导致内存越界,小于则复制/比较/查找不完整;
  4. 混淆重复前缀适用场景:REP 不可用于 CMPS/SCASREPE/REPNE 不可用于 MOVS/STOS,否则逻辑错误;
  5. DOS 中断 09h 地址限制:该中断输出字符串要求地址为 DS:DX,若需输出 ES段的串,需临时将 DS 切换为 ES 对应的段基址。

ASCII码表

二进制 十进制 十六进制 字符/缩写 解释
00000000 0 00 NUL (NULL) 空字符
00000001 1 01 SOH (Start Of Headling) 标题开始
00000010 2 02 STX (Start Of Text) 正文开始
00000011 3 03 ETX (End Of Text) 正文结束
00000100 4 04 EOT (End Of Transmission) 传输结束
00000101 5 05 ENQ (Enquiry) 请求
00000110 6 06 ACK (Acknowledge) 回应/响应/收到通知
00000111 7 07 BEL (Bell) 响铃
00001000 8 08 BS (Backspace) 退格
00001001 9 09 HT (Horizontal Tab) 水平制表符
00001010 10 0A LF/NL (Line Feed/New Line) 换行键
00001011 11 0B VT (Vertical Tab) 垂直制表符
00001100 12 0C FF/NP (Form Feed/New Page) 换页键
00001101 13 0D CR (Carriage Return) 回车键
00001110 14 0E SO (Shift Out) 不用切换
00001111 15 0F SI (Shift In) 启用切换
00010000 16 10 DLE (Data Link Escape) 数据链路转义
00010001 17 11 DC1/XON (Device Control 1/Transmission On) 设备控制1/传输开始
00010010 18 12 DC2 (Device Control 2) 设备控制2
00010011 19 13 DC3/XOFF (Device Control 3/Transmission Off) 设备控制3/传输中断
00010100 20 14 DC4 (Device Control 4) 设备控制4
00010101 21 15 NAK (Negative Acknowledge) 无响应/非正常响应/拒绝接收
00010110 22 16 SYN (Synchronous Idle) 同步空闲
00010111 23 17 ETB (End of Transmission Block) 传输块结束/块传输终止
00011000 24 18 CAN (Cancel) 取消
00011001 25 19 EM (End of Medium) 已到介质末端/介质存储已满/介质中断
00011010 26 1A SUB (Substitute) 替补/替换
00011011 27 1B ESC (Escape) 逃离/取消
00011100 28 1C FS (File Separator) 文件分割符
00011101 29 1D GS (Group Separator) 组分隔符/分组符
00011110 30 1E RS (Record Separator) 记录分离符
00011111 31 1F US (Unit Separator) 单元分隔符
00100000 32 20 (Space) 空格
00100001 33 21 !
00100010 34 22 "
00100011 35 23 #
00100100 36 24 $
00100101 37 25 %
00100110 38 26 &
00100111 39 27
00101000 40 28 (
00101001 41 29 )
00101010 42 2A *
00101011 43 2B +
00101100 44 2C ,
00101101 45 2D -
00101110 46 2E .
00101111 47 2F /
00110000 48 30 0
00110001 49 31 1
00110010 50 32 2
00110011 51 33 3
00110100 52 34 4
00110101 53 35 5
00110110 54 36 6
00110111 55 37 7
00111000 56 38 8
00111001 57 39 9
00111010 58 3A :
00111011 59 3B ;
00111100 60 3C <
00111101 61 3D =
00111110 62 3E >
00111111 63 3F ?
01000000 64 40 @
01000001 65 41 A
01000010 66 42 B
01000011 67 43 C
01000100 68 44 D
01000101 69 45 E
01000110 70 46 F
01000111 71 47 G
01001000 72 48 H
01001001 73 49 I
01001010 74 4A J
01001011 75 4B K
01001100 76 4C L
01001101 77 4D M
01001110 78 4E N
01001111 79 4F O
01010000 80 50 P
01010001 81 51 Q
01010010 82 52 R
01010011 83 53 S
01010100 84 54 T
01010101 85 55 U
01010110 86 56 V
01010111 87 57 W
01011000 88 58 X
01011001 89 59 Y
01011010 90 5A Z
01011011 91 5B [
01011100 92 5C \
01011101 93 5D ]
01011110 94 5E ^
01011111 95 5F _
01100000 96 60 `
01100001 97 61 a
01100010 98 62 b
01100011 99 63 c
01100100 100 64 d
01100101 101 65 e
01100110 102 66 f
01100111 103 67 g
01101000 104 68 h
01101001 105 69 i
01101010 106 6A j
01101011 107 6B k
01101100 108 6C l
01101101 109 6D m
01101110 110 6E n
01101111 111 6F o
01110000 112 70 p
01110001 113 71 q
01110010 114 72 r
01110011 115 73 s
01110100 116 74 t
01110101 117 75 u
01110110 118 76 v
01110111 119 77 w
01111000 120 78 x
01111001 121 79 y
01111010 122 7A z
01111011 123 7B {
01111100 124 7C
01111101 125 7D }
01111110 126 7E ~
01111111 127 7F DEL (Delete) 删除