You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

汇编语言字符串对比程序间歇性失效问题排查求助

汇编字符串对比程序的奇偶次输入异常问题

我编写了一款用于对比用户输入字符串与指定字符串的汇编程序。首次输入ping时,程序可成功响应pong;但第二次输入时无任何输出,第三次恢复正常,第四次又再次失效。请问该问题的原因可能是什么?

相关代码

key_press:
  mov ah, 0x00
  int 0x16
  cmp al, 0x21
  jge compare
  jl other_chars
  jmp key_press

compare:
  cmp al, 0x7e
  jl print

print:
  pusha
  mov ah, 0x0e
  int 0x10
  popa
  mov [si], al
  inc si
  jmp key_press

other_chars:
  cmp ah, 0x1C
  je enter
  cmp ah, 0x39
  je space
  cmp al, 0x8
  je backspace
  jmp key_press

enter:
  pusha
  mov ah, 0x0e
  mov al, 0x0a
  int 0x10
  mov al, 0x0d
  int 0x10
  popa
  mov di, reserved
  mov bx, ping_command
  jmp loop1

loop1:
  cmp di, si
  je middle_loop1
  cmp byte [bx], 0
  je go_back_loop1
  mov ch, [di]
  cmp ch, [bx]
  jne go_back_loop1
;  pusha
;  mov ah, 0x0e
;  mov al, [di]
;  int 0x10
;  popa
  inc di
  inc bx
  jmp loop1

go_back_loop1:
  mov si, reserved
  mov bx, ping_command
  jmp key_press

middle_loop1:
  mov bx, pong
  pusha
  jmp print_ping

print_ping:
  cmp byte [bx], 0
  je go_back_print_ping
  mov ah, 0x0e
  mov al, [bx]
  int 0x10
  inc bx
  jmp print_ping

go_back_print_ping:
  mov al, 0x0a
  int 0x10
  mov al, 0x0d
  int 0x10
  popa
  jmp key_press

完整代码

org 0x7c00
bits 16

init:
  mov ah, 0x0e
  mov bx, string
  mov si, reserved
  jmp loop

loop:
  mov al, [bx]
  cmp al, 0
  je key_press
  int 0x10
  inc bx
  jmp loop

key_press:
  mov ah, 0x00
  int 0x16
  cmp al, 0x21
  jge compare
  jl other_chars
  jmp key_press

compare:
  cmp al, 0x7e
  jl print

print:
  pusha
  mov ah, 0x0e
  int 0x10
  popa
  mov [si], al
  inc si
  jmp key_press

other_chars:
  cmp ah, 0x1C
  je enter
  cmp ah, 0x39
  je space
  cmp al, 0x8
  je backspace
  jmp key_press

enter:
  pusha
  mov ah, 0x0e
  mov al, 0x0a
  int 0x10
  mov al, 0x0d
  int 0x10
  popa
  mov di, reserved
  mov bx, ping_command
  jmp loop1

loop1:
  cmp di, si
  je middle_loop1
  cmp byte [bx], 0
  je go_back_loop1
  mov ch, [di]
  cmp ch, [bx]
  jne go_back_loop1
;  pusha
;  mov ah, 0x0e
;  mov al, [di]
;  int 0x10
;  popa
  inc di
  inc bx
  jmp loop1

go_back_loop1:
  mov si, reserved
  mov bx, ping_command
  jmp key_press

middle_loop1:
  mov bx, pong
  pusha
  jmp print_ping

print_ping:
  cmp byte [bx], 0
  je go_back_print_ping
  mov ah, 0x0e
  mov al, [bx]
  int 0x10
  inc bx
  jmp print_ping

go_back_print_ping:
  mov al, 0x0a
  int 0x10
  mov al, 0x0d
  int 0x10
  popa
  jmp key_press

space:
  pusha
  mov ah, 0x0e
  mov al, ' '
  int 0x10
  popa
  mov byte [si], ' '
  inc si
  jmp key_press

backspace:
  pusha
  mov ah, 0x0e
  int 0x10
  mov al, ' '
  int 0x10
  mov al, 0x8
  int 0x10
  popa
  dec si
  jmp key_press

halt:
  hlt
  jmp halt

reserved resb 256
ping_command db "ping", 0
pong db "pong", 0
string db "Hello, World!", 0
times 510-($-$$) db 0
dw 0xAA55

问题原因分析

核心问题是匹配成功后没有重置输入缓冲区指针si:

  1. 首次输入ping后,si指向reserved+4(输入了4个字符),匹配成功后直接跳回key_press,si未被重置。
  2. 第二次输入ping时,字符从reserved+4开始存储,最终si指向reserved+8。进入匹配逻辑后:
    • di从reserved起始地址开始,bx指向ping_command起始地址
    • 对比4次后,bx指向ping_command的结束符0,此时di仅走到reserved+4,远小于si(reserved+8)
    • 触发cmp byte [bx], 0判断,跳转到go_back_loop1,匹配失败,因此无输出。
  3. 第二次匹配失败后,go_back_loop1会把si重置为reserved起始地址,所以第三次输入时又能正常匹配输出。
  4. 第三次匹配成功后si再次未重置,第四次输入重复第二次的失败逻辑。

修复方案

在匹配成功后的go_back_print_ping段中,添加重置si的指令:

go_back_print_ping:
  mov al, 0x0a
  int 0x10
  mov al, 0x0d
  int 0x10
  popa
  mov si, reserved  ; 新增该行,重置输入缓冲区指针
  jmp key_press

内容的提问来源于stack exchange,提问作者RadoslavL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 07:35:10