Windows x64汇编中获取字符串输入的存储问题求助
Windows x64汇编中使用scanf读取字符串的解决方案
你当前的代码缺少两个关键部分:为输入字符串分配存储缓冲区,以及正确传递scanf的参数。以下是修复后的完整实现:
核心改动说明
- 分配输入缓冲区:在
.bss段定义一块内存区域,用于存储用户输入的字符串(也可以在栈上分配,但.bss更适合存放不确定长度的输入,避免栈溢出风险)。 - 修正函数调用参数:
- Windows x64调用约定中,
printf/scanf这类可变参数函数,需将rax置0(因为没有传递浮点数参数)。 scanf的第二个参数是存储输入的缓冲区地址,需通过rdx寄存器传递(前四个参数依次用rcx、rdx、r8、r9)。
- Windows x64调用约定中,
修复后的完整代码
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
相关产品推荐
相关产品推荐

