汇编编写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
相关产品推荐
相关产品推荐

