字符串处理专题速查表(16位汇编,DOS中断风格)
1. 使用约定
- 环境:16位实模式(和课上
code segment/int 21h一致) - 结尾方式:默认使用 0 结尾字符串(C风格)
- 输出字符:
AH=2,DL=字符,int 21h - 程序退出:
AH=4Ch,AL=0,int 21h
2. 模板1:求字符串长度(0结尾)
用途:统计 str 的字符个数(不含结尾 0)。
asm
data segment
str db "Hello,asm", 0
len dw ?
data ends
code segment
assume cs:code, ds:data
main:
mov ax, data
mov ds, ax
mov bx, offset str
mov cx, 0
len_again:
mov al, ds:[bx]
cmp al, 0
je len_done
add cx, 1
add bx, 1
jmp len_again
len_done:
mov len, cx
mov ah, 4Ch
mov al, 0
int 21h
code ends
end main3. 模板2:逐字符输出字符串(0结尾)
用途:把 str 从头到尾打印出来。
asm
data segment
str db "Hello,asm", 0
data ends
code segment
assume cs:code, ds:data
main:
mov ax, data
mov ds, ax
mov bx, offset str
out_again:
mov dl, ds:[bx]
cmp dl, 0
je out_done
mov ah, 2
int 21h
add bx, 1
jmp out_again
out_done:
mov ah, 4Ch
mov al, 0
int 21h
code ends
end main4. 模板3:复制字符串(0结尾)
用途:src 复制到 dst,并把结尾 0 一起复制。
asm
data segment
src db "Hello,asm", 0
dst db 64 dup(0)
data ends
code segment
assume cs:code, ds:data
main:
mov ax, data
mov ds, ax
mov si, offset src
mov di, offset dst
copy_again:
mov al, ds:[si]
mov ds:[di], al
cmp al, 0
je copy_done
add si, 1
add di, 1
jmp copy_again
copy_done:
mov ah, 4Ch
mov al, 0
int 21h
code ends
end main5. 模板4:比较两个字符串(0结尾)
用途:比较 s1 和 s2。
结果约定:
CX=0表示相等CX=1表示不相等
asm
data segment
s1 db "abcde", 0
s2 db "abcde", 0
data ends
code segment
assume cs:code, ds:data
main:
mov ax, data
mov ds, ax
mov si, offset s1
mov di, offset s2
cmp_again:
mov al, ds:[si]
mov bl, ds:[di]
cmp al, bl
jne not_equal
cmp al, 0
je equal
add si, 1
add di, 1
jmp cmp_again
equal:
mov cx, 0
jmp cmp_done
not_equal:
mov cx, 1
cmp_done:
mov ah, 4Ch
mov al, 0
int 21h
code ends
end main6. 模板5:查找字符首次出现位置
用途:在 str 里找字符 target。
结果约定:
- 找到:
CX=下标(从0开始) - 未找到:
CX=0FFFFh
asm
data segment
str db "Hello,asm", 0
target db 'a'
data ends
code segment
assume cs:code, ds:data
main:
mov ax, data
mov ds, ax
mov bx, offset str
mov cx, 0
mov dl, target
find_again:
mov al, ds:[bx]
cmp al, 0
je not_found
cmp al, dl
je found
add bx, 1
add cx, 1
jmp find_again
found:
jmp find_done
not_found:
mov cx, 0FFFFh
find_done:
mov ah, 4Ch
mov al, 0
int 21h
code ends
end main7. 模板6:大小写转换(小写转大写)
用途:把字符串中 a~z 转成 A~Z,其他字符不变。
asm
data segment
str db "Hello,asm123", 0
data ends
code segment
assume cs:code, ds:data
main:
mov ax, data
mov ds, ax
mov bx, offset str
upper_again:
mov al, ds:[bx]
cmp al, 0
je upper_done
cmp al, 'a'
jb next_ch
cmp al, 'z'
ja next_ch
sub al, 20h
mov ds:[bx], al
next_ch:
add bx, 1
jmp upper_again
upper_done:
mov ah, 4Ch
mov al, 0
int 21h
code ends
end main8. 可选补充:字符串反转(原地)
思路:
- 先求长度
n - 左右双指针交换:
[left] <-> [right] - 做
n/2次即可
asm
; 这里只给关键循环骨架,前提是 SI=left, DI=right
rev_again:
cmp si, di
jae rev_done
mov al, ds:[si]
mov bl, ds:[di]
mov ds:[si], bl
mov ds:[di], al
add si, 1
sub di, 1
jmp rev_again
rev_done:9. 高频易错点
- 忘记
mov ax, data+mov ds, ax - 循环退出条件错,导致越界或死循环
- 复制时忘记把结尾 0 一并复制
- 比较字符串时只比较前缀就提前判等
- 转换大小写时未做范围判断,误改数字和符号
10. 复习顺序建议
- 先背模板1(求长度)和模板2(输出),这是所有字符串题的基础。
- 再练模板3(复制)和模板4(比较),掌握双指针思想。
- 然后做模板5(查找)和模板6(大小写转换),训练条件分支。
- 最后补模板8(反转),整合“求长度 + 双指针 + 交换”。