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

Windows x64汇编中获取字符串输入的存储问题求助

Windows x64汇编中使用scanf读取字符串的解决方案

你当前的代码缺少两个关键部分:为输入字符串分配存储缓冲区,以及正确传递scanf的参数。以下是修复后的完整实现:

核心改动说明

  1. 分配输入缓冲区:在.bss段定义一块内存区域,用于存储用户输入的字符串(也可以在栈上分配,但.bss更适合存放不确定长度的输入,避免栈溢出风险)。
  2. 修正函数调用参数:
    • Windows x64调用约定中,printf/scanf这类可变参数函数,需将rax置0(因为没有传递浮点数参数)。
    • scanf的第二个参数是存储输入的缓冲区地址,需通过rdx寄存器传递(前四个参数依次用rcx、rdx、r8、r9)。

修复后的完整代码

bits 64
default rel

segment .data
    grs db "name: ", 0  ; 补充0终止符,确保printf能正确识别字符串
    inpt db "%s", 0     ; 同样补充0终止符

segment .bss
    input_buf resb 256  ; 分配256字节的缓冲区,可根据需求调整大小

segment .text
    global main

extern printf
extern scanf
extern _CRT_INIT
extern ExitProcess

exit:
    xor rax, rax
    call ExitProcess

main:
    push rbp
    mov rbp, rsp
    sub rsp, 32  ; 预留栈空间,保证16字节对齐

    ; 打印提示信息
    lea rcx, [grs]
    xor rax, rax  ; 可变参数函数,无浮点数参数时rax置0
    call printf

    ; 读取用户输入
    lea rcx, [inpt]  ; 第一个参数:格式串地址
    lea rdx, [input_buf]  ; 第二个参数:缓冲区地址
    xor rax, rax
    call scanf

    ; 可选:验证输入,打印读取到的内容
    lea rcx, [inpt]
    lea rdx, [input_buf]
    xor rax, rax
    call printf

    jmp exit

关键细节补充

  • 字符串必须以0结尾:.data段中的grs和inpt要补充0,否则printf/scanf会读取到内存中多余的垃圾数据。
  • 栈对齐:Windows x64要求调用函数前栈指针是16字节的倍数,sub rsp,32已经满足这个要求。
  • 缓冲区大小:resb 256定义的256字节可以根据实际需求调整,若需更安全的输入,建议使用fgets替代scanf以避免缓冲区溢出。

编译链接命令(保持你的原有命令即可)

  • 编译:nasm -f win64 -o "main.obj" "main.asm"
  • 链接:link "C:\Users\xx\Desktop\assembly_x64\get_input\main.obj" /subsystem:console /entry:main /defaultlib:ucrt.lib /defaultlib:msvcrt.lib /defaultlib:legacy_stdio_definitions.lib /defaultlib:Kernel32.lib /nologo /incremental:no /opt:ref /out:"main.exe"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:35:30