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

NASM仿Akinator游戏问题修复:首个答案复用至所有问题

NASM猜谜游戏答案复用问题修复

问题原因

  1. 输入缓冲区过小:原代码中answer resb 2仅分配2字节空间,但用户输入"yes"/"no"加上回车符需要至少3字节,未读取的残留字符会留在输入流中,被后续sys_read直接读取,导致答案复用。
  2. 读取长度设置错误:每次调用sys_read时edx设为2,仅读取2字节,无法完整读取用户输入(包括回车),残留数据会干扰后续输入。
  3. 字符串比较逻辑错误:
    • cmp byte [answer], 'yes'是单字节比较,仅判断第一个字符是否为'y',并非完整匹配"yes"。
    • cmp word [answer], 'no'是双字节比较,但未考虑回车符,实际输入的"no"后会跟回车,导致比较逻辑失效,错误复用之前的输入判断。

修复后的代码

section .data
; questions
    q1 db 'Is your character real? (yes/no)', 0xA, 0  ; 添加换行符优化显示
    q2 db 'Is your character human? (yes/no)', 0xA, 0
    q3 db 'Is your character male? (yes/no)', 0xA, 0
    q4 db 'Is your character fictional? (yes/no)', 0xA, 0
    q5 db 'Is your object/animal living? (yes/no)', 0xA, 0

; answers
    a1 db 'red', 0xA, 0
    a2 db 'jabol', 0xA, 0
    a3 db 'kuromi', 0xA, 0
    a4 db 'pencil', 0xA, 0

; 比较用的字符串
    yes_str db 'yes'
    no_str db 'no'

section .bss
    answer resb 10  ; 扩大缓冲区,足够容纳输入和回车

section .text
    global _start

_start:
    ; 处理问题1
    call print_q1
    call read_answer
    call check_yes
    je human
    call check_no
    je object_animal
    jmp _start  ; 输入无效时重新提问

human:
    ; 处理问题3(原代码中误写为q3,对应性别问题)
    call print_q3
    call read_answer
    call check_yes
    je male
    call check_no
    je female
    jmp human  ; 输入无效时重新提问

male:
    call print_a1
    jmp exit

female:
    call print_a2
    jmp exit

object_animal:
    ; 处理问题5
    call print_q5
    call read_answer
    call check_yes
    je living
    call check_no
    je non_living
    jmp object_animal  ; 输入无效时重新提问

living:
    call print_a3
    jmp exit

non_living:
    call print_a4
    jmp exit

; 打印问题1
print_q1:
    mov eax, 4
    mov ebx, 1
    mov ecx, q1
    mov edx, 26  ; 包含换行符的长度
    int 0x80
    ret

; 打印问题3
print_q3:
    mov eax, 4
    mov ebx, 1
    mov ecx, q3
    mov edx, 32  ; 包含换行符的长度
    int 0x80
    ret

; 打印问题5
print_q5:
    mov eax, 4
    mov ebx, 1
    mov ecx, q5
    mov edx, 32  ; 包含换行符的长度
    int 0x80
    ret

; 打印答案a1
print_a1:
    mov eax, 4
    mov ebx, 1
    mov ecx, a1
    mov edx, 5  ; 包含换行符的长度
    int 0x80
    ret

; 打印答案a2
print_a2:
    mov eax, 4
    mov ebx, 1
    mov ecx, a2
    mov edx, 6  ; 包含换行符的长度
    int 0x80
    ret

; 打印答案a3
print_a3:
    mov eax, 4
    mov ebx, 1
    mov ecx, a3
    mov edx, 7  ; 包含换行符的长度
    int 0x80
    ret

; 打印答案a4
print_a4:
    mov eax, 4
    mov ebx, 1
    mov ecx, a4
    mov edx, 8  ; 包含换行符的长度
    int 0x80
    ret

; 读取用户输入
read_answer:
    mov eax, 3
    mov ebx, 0
    mov ecx, answer
    mov edx, 10  ; 读取足够长度,覆盖缓冲区
    int 0x80
    ; 清理缓冲区中回车后的内容,确保下次输入不受干扰
    mov esi, answer
clean_buffer:
    cmp byte [esi], 0xA  ; 找到回车符
    je clean_done
    inc esi
    cmp esi, answer+10
    jb clean_buffer
clean_done:
    mov byte [esi], 0  ; 用0截断字符串
    ret

; 检查输入是否为yes
check_yes:
    mov esi, answer
    mov edi, yes_str
    cmpsb
    jne check_yes_fail
    cmpsb
    jne check_yes_fail
    cmpsb
    jne check_yes_fail
    mov eax, 1
    ret
check_yes_fail:
    mov eax, 0
    ret

; 检查输入是否为no
check_no:
    mov esi, answer
    mov edi, no_str
    cmpsb
    jne check_no_fail
    cmpsb
    jne check_no_fail
    mov eax, 1
    ret
check_no_fail:
    mov eax, 0
    ret

exit:
    mov eax, 1
    xor ebx, ebx
    int 0x80

修复说明

  1. 扩大缓冲区:将answer的大小改为10字节,足够容纳用户输入及回车符,避免残留数据。
  2. 完整读取输入:sys_read的edx设为10,每次读取足够长度,并用截断操作清理回车后的内容,确保缓冲区干净。
  3. 添加字符串比较函数:通过check_yes和check_no函数实现完整的字符串匹配,避免单/双字节比较的逻辑错误。
  4. 优化显示:给问题和答案添加换行符,提升交互体验。
  5. 输入校验:添加无效输入时重新提问的逻辑,增强程序健壮性。

内容的提问来源于stack exchange,提问作者Duncan Red Benedict De Guzman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 20:03:20