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

汇编程序终端持续重复输出内容,无法正常接收输入问题排查

问题:x86-64汇编程序重复输出菜单,无法等待用户输入

我编写了一段x86-64汇编程序,预期显示菜单后等待用户输入选择,但运行时终端持续重复输出菜单内容,无法正常停留在输入环节。

程序代码

section .bss
    choice resb 4         ; Buffer for storing user choice
    ans resb 32


section .text    
global _start

_start:



loop:
    ;welcome msg
    mov rax, 1
    mov rdi, 1
    mov rsi, text1 
    mov rdx, text1_len
    syscall

    ;menu
    mov rax, 1
    mov rdi, 1
    mov rsi, c1
    mov rdx, c1_len
    syscall

    mov rax, 1
    mov rdi, 1
    mov rsi, c2
    mov rdx, c2_len
    syscall

    mov rax, 1
    mov rdi, 1
    mov rsi, c3
    mov rdx, c3_len
    syscall

    mov rax, 1
    mov rdi, 1
    mov rsi, c4
    mov rdx, c4_len
    syscall

    mov rax, 1
    mov rdi, 1
    mov rsi, c5
    mov rdx, c5_len
    syscall

    mov rax, 1
    mov rdi, 1
    mov rsi, text2
    mov rdx, text2_len
    syscall

    ;gets choice
    mov rax, 0 
    mov rdi, 0 
    mov rsi, choice 
    mov rdx, 4
    syscall

    ;ends code there (i just wanted to test if it worked before i move on)
    mov rax, 60
    mov rdi, 0
    syscall



section .data
    text1 db "Hello welcome to math help", 0xA
    c1 db "(1) Add", 0xA
    c2 db "(2) Subtract", 0xA
    c3 db "(3) Multiply", 0xA
    c4 db "(4) Divide", 0xA
    c5 db "(0) Exit", 0xA
    text2 db "Please enter your choice below", 0xA
    text1_len equ $ - text1
    c1_len equ $ - c1
    c2_len equ $ - c2
    c3_len equ $ - c3
    c4_len equ $ - c4
    c5_len equ $ - c5
    text2_len equ $ - text2

终端输出

Hello welcome to math help
(1) Add
(2) Subtract
(3) Multiply
(4) Divide
(0) Exit
Please enter your choice below
(1) Add
(2) Subtract
(3) Multiply
(4) Divide
(0) Exit
Please enter your choice below
(2) Subtract
(3) Multiply
(4) Divide
(0) Exit
Please enter your choice below
(3) Multiply
(4) Divide
(0) Exit
Please enter your choice below
(4) Divide
(0) Exit
Please enter your choice below
(0) Exit
Please enter your choice below
Please enter your choice below

问题原因及解决方法

核心原因

你大概率使用了错误的编译格式,将程序编译成了**flat binary(纯二进制文件)**而非标准ELF64可执行文件。flat binary格式下,代码段(.text)和数据段(.data)会连续存储在内存中,且整个文件被标记为可执行。当程序执行完exit系统调用后,若退出逻辑出现异常,程序计数器会继续执行.data段的字符串内容,将其当作机器指令运行,最终导致重复输出菜单等异常行为。

同时,代码中section的顺序不符合常规规范,也会加剧这类问题的出现。

解决步骤

  1. 正确编译为ELF64格式
    使用以下命令编译链接程序:

    nasm -f elf64 your_program.asm -o your_program.o
    ld your_program.o -o your_program
    

    ELF格式会将代码段、数据段、未初始化数据段(.bss)分隔到独立的内存区域,数据段会被标记为不可执行,从根源避免字符串被当作指令执行的问题。

  2. 调整section顺序(可选但推荐)
    将section顺序调整为.data → .bss → .text,符合汇编代码的常规结构,减少潜在的内存布局问题:

    section .data
        ; 所有数据定义放在这里
    
    section .bss
        ; 所有未初始化数据定义放在这里
    
    section .text
        global _start
    _start:
        ; 代码逻辑放在这里
    
  3. 优化输入读取(可选)
    你只需要读取用户的单个选择字符,因此可以将read系统调用的缓冲区长度从4改为1,避免不必要的内存占用和潜在的缓冲区溢出:

    ;gets choice
    mov rax, 0 
    mov rdi, 0 
    mov rsi, choice 
    mov rdx, 1  ; 只读取1个字节
    syscall
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 22:42:01