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

如何在FASM汇编中加载Raylib字体?调用LoadFontEx时程序崩溃

问题解决:FASM调用Raylib LoadFontEx段错误

核心错误点分析

  1. Codepoints数组偏移计算错误
    你填充codepoints时直接使用字节偏移,但codepoints是dd(4字节)类型的数组,每个元素占4字节,直接用rcx - 0x20作为字节偏移会导致数据写入错误的内存位置,LoadFontEx读取到乱码的codepoints后会触发非法内存访问。

  2. Codepoints数组容量与计数不匹配

    • ASCII部分(0x20到0x7F)共95个字符,西里尔文部分(0x400到0x6C0)共705个字符,总计800个,但你定义的codepoints仅预留512个dd元素,容量不足会导致越界写入。
    • 调用LoadFontEx时传入的计数是211,和实际需要的800完全不符,会让函数读取超出数组范围的内存。
  3. Font变量定义冗余(非直接错误但不规范)
    64位系统下Raylib的LoadFontEx返回的是Font结构体指针(8字节),你预留64字节完全没必要,定义为8字节的qword足够。

修复后的代码

format ELF64

section ".data" writeable
    screenWidth:    dd 800
    screenHeight:   dd 600
    windowTitle:    db "raylib [text] example - font loading", 0
    ; 预留足够容量存储ASCII+西里尔文共800个codepoints
    codepoints:     times 800 dd 0
    fontFile:       db "km.ttf", 0
    text1:          db "Окей, Okay!", 0
    text2:          db "С Новым Годом!", 0
    ; 若启用DrawTextEx,需定义坐标向量
    ; textPos: dd 100.0, 150.0

section ".bss"
    ; 存储Font结构体指针,64位系统下占8字节
    font: rq 1

section '.text' executable
    public _start
    extrn printf
    extrn _exit
    extrn InitWindow
    extrn WindowShouldClose
    extrn CloseWindow
    extrn BeginDrawing
    extrn EndDrawing
    extrn ClearBackground
    extrn DrawText
    extrn DrawTextEx
    extrn LoadFontEx
    extrn UnloadFont

_start:
    mov rdi, 400
    mov rsi, 300
    mov rdx, windowTitle
    call InitWindow

init_ascii:
    mov rcx, 0x20 ; 起始ASCII码
init_ascii_loop:
    ; 计算当前字符在数组中的索引,乘以4得到字节偏移
    lea rbx, [rcx - 0x20]
    mov [codepoints + rbx*4], ecx ; 存入32位codepoint值

    inc rcx
    cmp rcx, 0x7F ; 到0x7F结束(包含0x7E)
    jne init_ascii_loop

init_cyrillic:
    mov rcx, 0x400 ; 起始西里尔文码
init_cyrillic_loop:
    ; 西里尔文从数组第95个元素开始(ASCII占了95个)
    lea rbx, [rcx - 0x400]
    mov [codepoints + 95*4 + rbx*4], ecx

    inc rcx
    cmp rcx, 0x6C1 ; 到0x6C1结束(包含0x6C0)
    jne init_cyrillic_loop

    ; Load the font
    mov rdi, fontFile           ; font file path
    mov rsi, 32                 ; font size
    mov rdx, codepoints         ; codepoints array
    mov rcx, 800                ; 总codepoints数量(95+705)
    call LoadFontEx
    mov [font], rax ; 存储返回的Font指针

.again:
    call WindowShouldClose
    test rax, rax
    jnz .over
    call BeginDrawing

    mov rdi, 0xFF181818
    call ClearBackground

    mov rdi, text1
    mov rsi, 100
    mov rdx, 100
    mov rcx, 20
    mov r8, 0xFFFFFFFF
    call DrawText

    ; 启用DrawTextEx的示例(需取消注释textPos定义)
    ; mov rdi, [font]
    ; mov rsi, text1
    ; mov rdx, textPos
    ; mov rcx, 32.0
    ; mov r8, 0xFFFFFFFF
    ; call DrawTextEx

    call EndDrawing
    jmp .again

.over:
    ; 卸载字体避免内存泄漏
    mov rdi, [font]
    call UnloadFont
    call CloseWindow
    mov rdi, 0
    call _exit

额外注意事项

  • 确保km.ttf文件存在于程序运行目录,否则LoadFontEx会返回空指针,后续操作也会触发段错误。
  • 程序退出前调用UnloadFont释放字体资源,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 16:40:54