汇编语言字符串对比程序间歇性失效问题排查求助
汇编字符串对比程序的奇偶次输入异常问题
我编写了一款用于对比用户输入字符串与指定字符串的汇编程序。首次输入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:
- 首次输入
ping后,si指向reserved+4(输入了4个字符),匹配成功后直接跳回key_press,si未被重置。 - 第二次输入
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,匹配失败,因此无输出。
- 第二次匹配失败后,
go_back_loop1会把si重置为reserved起始地址,所以第三次输入时又能正常匹配输出。 - 第三次匹配成功后
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
相关产品推荐
相关产品推荐

