assemblyfasmraylib

How to load raylib font in assembly?


Problem:

I have computer science classes, we learn assembly using fasm, classes rely on win api, but i use linux so i've got approval to use external libraries. I've chose Raylib.

Problem is that I can't call LoadFont(Ex) without program segfaulting.

I tried to store structure in font by reserving 64 bytes, and tried to store pointer to the data before that, but no luck.

Progress:

format ELF64

section ".data" writeable
    screenWidth:    dd 800
    screenHeight:   dd 600
    windowTitle:    db "raylib [text] example - font loading", 0
    codepoints:     times 512 dd 0
    fontFile:       db "km.ttf", 0
    text1:          db "Окей, Okay!", 0
    text2:          db "С Новым Годом!", 0

section ".bss"
    font: rb 64

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 ; rcx is codepoints count
init_ascii_loop:
    mov [codepoints + rcx - 0x20], rcx


    inc rcx
    cmp rcx, 127
    jne init_ascii_loop

init_cyrillic:
    mov rcx, 0x400 ; rcx is codepoints count
init_cyrillic_loop:
    mov [codepoints + rcx - 0x400], rcx

    inc rcx
    cmp rcx, 0x6c1
    jne init_cyrillic_loop

    ; Load the font
    mov rdi, fontFile           ; font file
    mov rsi, 32                 ; font size
    mov rdx, codepoints         ; codepoints
    mov rcx, 211                ; codepoints count
    call LoadFontEx
    mov [font], rax

.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

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

    call EndDrawing
    jmp .again

.over:
    call CloseWindow
    mov rdi, 0
    call _exit

Solution

  • I've figured it using this

    Basically, function LoadFont stores new font on the stack instead of returning it as a value, that's why we pass rsp (register (for) stack pointer) into rdi

    Later to call DrawTextEx we should have font structure loaded into rsp as the last data on stack, so that function can safely reference it (i think thats what happens on lines 68-73, if im wrong correct me please)

    format ELF64
    
    section ".data" writeable
        screenWidth:    dd 850
        screenHeight:   dd 300
        windowTitle:    db "Моя программа.", 0
        fontFile:       db '../assets/km.ttf', 0
        text:          
            .message:   db "Программировать наАссемблер на FASM — это классно!", 0
            .xy:        dd 100.0, 100.0
            .fontSize:  dd 30.0
            .spacing:   dd 0.0
                            ; unicode    
        codepoints:     dd  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 0, \
                        \   ; cyrillic
                        1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138
    
    section ".bss" writeable
        font:           rb 48
    
    section '.text' executable
        public _start
        extrn printf
        extrn _exit
        extrn InitWindow
        extrn WindowShouldClose
        extrn CloseWindow
        extrn BeginDrawing
        extrn EndDrawing
        extrn ClearBackground
        extrn DrawTextEx
        extrn LoadFontEx
        extrn UnloadFont
    
    _start:
        mov rdi, [screenWidth]
        mov rsi, [screenHeight]
        mov rdx, windowTitle
        call InitWindow
    
    ; load font
        mov rdi, font
        mov esi, fontFile ; move offset of "km.ttf" into esi
        mov edx, 32 ; move 32 into edx
        mov rcx, codepoints ; move address of codepoints into rcx
        mov r8d, 211 ; move 211 into r8d
        call LoadFontEx
    
    .again:
        call WindowShouldClose
        test rax, rax
        jnz .over
        call BeginDrawing
    
        mov rdi, 0xfffafafa ; a g b r
        call ClearBackground
    
        sub rsp, 48
        movdqa  xmm3, [font]  ; tmp136, f
        movups  [rsp], xmm3     ; tmp136
        movdqa  xmm4, [font+16]  ; tmp137, f
        movups  [rsp+16], xmm4  ; tmp137
        movdqa  xmm5, [font+32]  ; tmp138, f
        movups  [rsp+32], xmm5  ; tmp138
        mov edi, text.message
        movq xmm0, [text.xy]
        movss xmm1, [text.fontSize]
        movss xmm2, [text.spacing]
        mov esi, 0xff181818
        call DrawTextEx
        add rsp, 48
    
        call EndDrawing
        jmp .again
    
    .over:
        ; unload font
        sub rsp, 48
        movdqa  xmm3, [font]
        movups  [rsp], xmm3
        movdqa  xmm4, [font+16]
        movups  [rsp+16], xmm4
        movdqa  xmm5, [font+32]
        movups  [rsp+32], xmm5
        call    UnloadFont      
        add     rsp, 48   
    
        ; close window
        call CloseWindow
        mov rdi, 0
        call _exit