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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 00:27:07