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

x86-64平台Windows与Linux下int 0x80系统调用汇编Hello World问题

解决Linux汇编代码在Windows下无法输出Hello World的问题

你的汇编代码是基于Linux x86系统调用编写的,依赖int 0x80触发内核服务完成输出和退出,但Windows完全不兼容这套机制——它没有int 0x80这类系统调用,所有用户态功能都需要通过Win32 API实现,这就是编译通过但运行无输出的根本原因。

解决方案:针对Windows平台重写代码

需要使用Win32 API完成控制台输出和程序退出,同时遵循Win64汇编的调用约定,以下提供两种实现方案:

方案1:纯Win32 API实现控制台输出

使用WriteConsoleA和ExitProcess系统API完成功能,代码如下:

section .data
    var_msg db 0xA, 'hello world', 0xA  ; 带换行的输出内容
    var_len equ $ - var_msg             ; 计算字符串长度

section .text
    global main                         ; 程序入口,对应Windows PE的mainCRTStartup
    extern GetStdHandle, WriteConsoleA, ExitProcess  ; 声明外部API

main:
    ; 获取标准输出句柄
    mov rcx, -11                        ; STD_OUTPUT_HANDLE的常量值为-11
    call GetStdHandle

    ; 调用WriteConsoleA输出字符串
    mov rcx, rax                        ; 参数1:标准输出句柄(GetStdHandle的返回值)
    mov rdx, var_msg                    ; 参数2:要输出的字符串指针
    mov r8, var_len                     ; 参数3:字符串长度
    sub rsp, 8                          ; 栈对齐(Win64要求栈始终保持16字节对齐)
    mov r9, rsp                         ; 参数4:接收实际写入字节数的指针(可忽略,但必须传递)
    mov qword [rsp+32], 0               ; 参数5:保留参数,设为0
    call WriteConsoleA
    add rsp, 8                          ; 恢复栈空间

    ; 退出程序
    mov rcx, 0                          ; 参数1:程序返回码(0表示正常退出)
    call ExitProcess

编译命令(Windows下)

编译后需要链接Windows的kernel32.dll库(提供上述API):

nasm -f win64 hello_win.asm -o hello_win.o
ld hello_win.o -lkernel32 -o hello_win.exe

或者用MinGW的GCC链接更简便:

nasm -f win64 hello_win.asm -o hello_win.o
gcc hello_win.o -o hello_win.exe

方案2:调用C标准库printf简化代码

如果不想直接写Win32 API,也可以调用C标准库的printf函数,代码更简洁:

section .data
    fmt_str db '%s', 0xA, 0             ; printf的格式字符串
    hello_str db 'hello world', 0xA, 0  ; 要输出的内容

section .text
    global main
    extern printf, exit                 ; 声明C库函数

main:
    ; 调用printf输出字符串
    mov rcx, fmt_str                    ; 参数1:格式字符串指针
    mov rdx, hello_str                  ; 参数2:要输出的字符串指针
    call printf

    ; 退出程序
    mov rcx, 0                          ; 返回码0
    call exit

编译命令

编译后链接C标准库(msvcrt.dll):

nasm -f win64 hello_printf.asm -o hello_printf.o
gcc hello_printf.o -o hello_printf.exe

关键注意点

  • 调用约定差异:Win64汇编使用FastCall约定,前4个参数依次放入RCX、RDX、R8、R9寄存器,且调用前必须保证栈是16字节对齐
  • 入口点差异:Windows PE程序的默认入口是mainCRTStartup,定义main函数后,链接器会自动处理C运行时的初始化工作
  • 依赖库:必须链接对应API所在的系统库(kernel32.dll或msvcrt.dll),否则会出现链接错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 02:20:32