Skip to content

字符串处理专题速查表(16位汇编,DOS中断风格)

1. 使用约定

  • 环境:16位实模式(和课上 code segment/int 21h 一致)
  • 结尾方式:默认使用 0 结尾字符串(C风格)
  • 输出字符:AH=2DL=字符int 21h
  • 程序退出:AH=4ChAL=0int 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 main

3. 模板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 main

4. 模板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 main

5. 模板4:比较两个字符串(0结尾)

用途:比较 s1s2

结果约定:

  • 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 main

6. 模板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 main

7. 模板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 main

8. 可选补充:字符串反转(原地)

思路:

  • 先求长度 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. 先背模板1(求长度)和模板2(输出),这是所有字符串题的基础。
  2. 再练模板3(复制)和模板4(比较),掌握双指针思想。
  3. 然后做模板5(查找)和模板6(大小写转换),训练条件分支。
  4. 最后补模板8(反转),整合“求长度 + 双指针 + 交换”。