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

汇编编写SDL2窗口编译后无显示问题求助

汇编SDL2窗口程序无反应问题排查

我尝试用汇编语言开发游戏,调研后通过导入SDL动态库编写了一个SDL2窗口程序,但编译运行后无任何反应。程序逻辑为初始化SDL、创建窗口、延迟5秒后销毁窗口并退出SDL,在Windows系统(使用GoLink链接器,入口点为Start)和Linux(WSL)环境中测试结果一致。

汇编代码

extern SDL_Init
extern SDL_CreateWindow
extern SDL_Delay
extern SDL_DestroyWindow
extern SDL_Quit

section .bss
    window resb 8

section .text
    global Start
Start:
    push 32 ; This is SDL_INIT_VIDEO
    call SDL_Init
    push 0
    push 800 ; Height
    push 800 ; Width
    push 500 ; y pos
    push 500 ; x pos
    push title ; title
    call SDL_CreateWindow
    mov [window], rax

    push 5000
    call SDL_Delay

    push window
    call SDL_DestroyWindow

    call SDL_Quit

    mov eax, 1
    mov ebx, 1
    int 0x80
    
section .data
    title db "ASM SDL2", 0x0A, 0x00

Makefile配置

LIBS = kernel32.dll ntdll.dll kernelbase.dll msvcrt.dll SDL2.dll

all:
    nasm main.asm -f win64 -o main.obj
    GoLink /files /console main.obj $(LIBS)

问题原因与修复方案

1. Win64调用约定错误

Win64平台下标准调用约定为fastcall,前4个参数通过寄存器(RCX、RDX、R8、R9)传递,剩余参数从右往左压栈。原代码完全使用32位栈传递方式,且参数顺序完全颠倒,导致SDL函数无法正确接收参数,窗口创建失败。

2. 缺少错误检查

未检查SDL_Init和SDL_CreateWindow的返回值,初始化或窗口创建失败后仍继续执行后续无效逻辑。

3. 退出方式错误

Win64下不能使用int 0x80这种32位Linux系统调用退出,需调用Windows系统的ExitProcess函数。

4. 标题字符串异常

标题中包含多余的换行符0x0A,可能导致窗口标题解析异常。

修复后的代码

extern SDL_Init
extern SDL_CreateWindow
extern SDL_Delay
extern SDL_DestroyWindow
extern SDL_Quit
extern ExitProcess

section .bss
    window resq 1 ; 明确声明64位变量

section .text
    global Start
Start:
    ; 初始化SDL_VIDEO
    mov rcx, 32 ; SDL_INIT_VIDEO
    call SDL_Init
    test eax, eax
    js ExitError ; 初始化失败则跳转至错误处理

    ; 创建窗口:SDL_CreateWindow(title, x, y, w, h, flags)
    mov rcx, title        ; 第1参数:窗口标题
    mov rdx, 500          ; 第2参数:x坐标
    mov r8, 500           ; 第3参数:y坐标
    mov r9, 800           ; 第4参数:窗口宽度
    push 0                ; 第6参数:窗口标志(SDL_WINDOW_SHOWN)
    push 800              ; 第5参数:窗口高度
    call SDL_CreateWindow
    test rax, rax
    jz ExitError          ; 窗口创建失败则跳转至错误处理
    mov [window], rax

    ; 延迟5秒
    mov rcx, 5000
    call SDL_Delay

    ; 销毁窗口
    mov rcx, [window]
    call SDL_DestroyWindow

    ; 退出SDL
    call SDL_Quit

    ; 正常退出,返回值0
    mov rcx, 0
    call ExitProcess

ExitError:
    call SDL_Quit
    mov rcx, 1
    call ExitProcess
    
section .data
    title db "ASM SDL2", 0x00 ; 移除多余换行符

修复后的Makefile

LIBS = kernel32.dll SDL2.dll

all:
    nasm main.asm -f win64 -o main.obj
    GoLink /entry Start /console main.obj $(LIBS)

额外注意事项

  • 确保SDL2.dll与程序同目录,或已加入系统PATH
  • WSL环境测试需改用Linux版本SDL2、System V调用约定(参数通过RDI、RSI、RDX、RCX、R8、R9传递)及对应链接工具(如gcc),不能直接复用Windows代码

内容的提问来源于stack exchange,提问作者Anirudh Yamunan Govindarajan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 07:54:09