x86-64 Windows下NASM汇编调用putchar时test2无输出原因排查
64位Windows下NASM汇编调用putchar时test2无输出的问题
我是汇编新手,正在64位Windows 11系统上用NASM语法编写汇编代码,尝试调用C标准库函数。我写了三个调用putchar并传入ASCII码77(对应大写字母M)的汇编文件:test1.asm、test2.asm和test3.asm,其中test1和test3运行后能正常输出M,但test2运行后没有任何输出。
三个汇编文件代码
test1.asm
bits 64 default rel extern ExitProcess extern putchar global main section .text main: ; sub 32 to allocate shadow space sub rsp, 32 ; call putchar with ASCII character M mov rcx, 77 call putchar ; call ExitProcess with exit code 0 xor rcx, rcx call ExitProcess
test2.asm
bits 64 default rel extern ExitProcess extern putchar global main section .text main: ; sub 8 to allocate memory for a qword ; sub 32 to allocate shadow space sub rsp, 40 ; copy 77 into rbx ; copy rbx (77) into [rbp-08] mov rbx, 77 mov [rbp-08], rbx ; call putchar passing the value at [rbp-08] (77) mov rcx, [rbp-08] call putchar ; call ExitProcess with exit code 0 xor rcx, rcx call ExitProcess
test3.asm
bits 64 default rel extern ExitProcess extern putchar global main section .text main: ; sub 32 to allocate shadow space sub rsp, 32 call secondary ; zero rcx to call ExitProcess xor rcx, rcx call ExitProcess secondary: push rbp mov rbp, rsp ; sub 8 to allocate memory for a qword ; sub 8 so that the final total is 16-byte aligned ; sub 32 to allocate shadow space sub rsp, 48 ; save rbx because its volatile ; (although technically this shouldn't be needed because main doesn't use rbx) push rbx ; copy 77 into rbx ; copy rbx (77) into [rbp-08] mov rbx, 77 mov [rbp-08], rbx ; call putchar passing the value at [rbp-08] (77) mov rcx, [rbp-08] call putchar ; restore rbx pop rbx add rsp, 48 pop rbp ret
汇编链接命令
我在CMD中使用以下命令进行汇编和链接:
D:\Desktop\temp>nasm -fwin64 test1.asm D:\Desktop\temp>nasm -fwin64 test2.asm D:\Desktop\temp>nasm -fwin64 test3.asm D:\Desktop\temp>ld C:\Windows\System32\kernel32.dll C:\Windows\System32\msvcrt.dll test1.obj -o a1.exe D:\Desktop\temp>ld C:\Windows\System32\kernel32.dll C:\Windows\System32\msvcrt.dll test2.obj -o a2.exe D:\Desktop\temp>ld C:\Windows\System32\kernel32.dll C:\Windows\System32\msvcrt.dll test3.obj -o a3.exe
运行结果
D:\Desktop\temp>a1.exe M D:\Desktop\temp>a2.exe D:\Desktop\temp>a3.exe M D:\Desktop\temp>
疑问
我无法理解为什么test2无法输出M。在我看来,test1只是直接将77移入RCX,步骤更少;test3只是在独立函数中执行与test2相同的操作。test1和test3都能正常工作,为什么test2不行?
我参考过类似问题,有人说是因为C标准库IO采用缓冲IO,程序终止前未刷新stdout缓冲区,但这个解释说不通——test1和test3同样没有手动刷新缓冲区,却能正常输出M。
内容的提问来源于stack exchange,提问作者resoinaut
相关产品推荐
相关产品推荐

