Skip to content

Instantly share code, notes, and snippets.

@tilkinsc
Created June 11, 2026 01:50
Show Gist options
  • Select an option

  • Save tilkinsc/2dff96eeef2a4d254d944b0e2ab656ef to your computer and use it in GitHub Desktop.

Select an option

Save tilkinsc/2dff96eeef2a4d254d944b0e2ab656ef to your computer and use it in GitHub Desktop.
C3 function declarations for assembly
module std::core::builtin;
extern fn void cli() @builtin @inline;
extern fn void sti() @builtin @inline;
extern fn void hlt() @builtin @inline;
extern fn char inb(ushort port) @builtin;
extern fn void outb(ushort port, char value) @builtin @inline;
extern fn ushort inw(ushort port) @builtin;
extern fn void outw(ushort port, ushort value) @builtin @inline;
extern fn uint inl(ushort port) @builtin;
extern fn void outl(ushort port, uint value) @builtin @inline;
fn void* get_rsp() @builtin @inline
{
void* rsp;
asm { movq rsp, $rsp; }
return rsp;
}
extern fn void load_fs(void* fs) @builtin @inline;
extern fn void load_gdtr(void* gdtr) @builtin @inline;
extern fn void load_tss(ushort selector) @builtin @inline;
extern fn void load_cs(ulong selector) @builtin @inline;
extern fn void reload_segments(ushort selector) @builtin @inline;
extern fn void load_idtr(void* idtr) @builtin @inline;
extern fn void get_cr2(ulong* cr2) @builtin @inline;
extern fn void load_cr3(ulong cr3) @builtin @inline;
extern fn void invlpg(ulong address) @builtin @inline;
struct CpuidResult @packed
{
uint eax;
uint ebx;
uint ecx;
uint edx;
}
extern fn void cpuid(uint leaf, uint subleaf, CpuidResult* out) @builtin @inline;
extern fn ulong clz(ulong bitset) @builtin @inline;
@tilkinsc

Copy link
Copy Markdown
Author
bits 64
default rel

section .text

; void hlt(void)
global hlt
hlt:
    hlt
    ret

; void cli(void)
global cli
cli:
    cli
    ret

; void sti(void)
global sti
sti:
    sti
    ret

; char inb(short port)
global inb
inb:
    mov dx, di        ; port -> dx
    xor eax, eax
    in al, dx
    ret

; void outb(short port, char value)
global outb
outb:
    mov dx, di        ; port -> dx
    mov al, sil       ; value -> al
    out dx, al
    ret

; short inw(short port)
global inw
inw:
    mov dx, di
    xor eax, eax
    in ax, dx
    ret

; void outw(short port, short value)
global outw
outw:
    mov dx, di
    mov ax, si
    out dx, ax
    ret

; int inl(short port)
global inl
inl:
    mov dx, di
    in eax, dx
    ret

; void outl(short port, int value)
global outl
outl:
    mov dx, di
    mov eax, esi
    out dx, eax
    ret

; void load_fs(void* fs)
global load_fs
load_fs:
    wrfsbase rdi
    ret

; void load_tss(uint16_t tss)
global load_tss
load_tss:
    ltr di
    ret

; void load_gdtr(void* gdtr)
global load_gdtr
load_gdtr:
    lgdt [rdi]
    ret

; void load_cs(ulong selector)
global load_cs
load_cs:
    push rdi              ; push CS selector
    lea rax, [rel .after] ; load return address
    push rax              ; push return address
    retfq                 ; pop cs selector and return address
.after:                   ; return destination
    ret                   ; return to caller

; void reload_segments(ushort selector)
global reload_segments
reload_segments:
    push ax
    mov ax, di
    mov ds, ax
    mov es, ax
    xor ax, ax
    mov fs, ax
    mov gs, ax
    pop ax
    ret

; void load_idtr(void* idtr)
global load_idtr
load_idtr:
    lidt [rdi]
    ret

; void get_cr2(ulong* cr2)
global get_cr2
get_cr2:
    mov rax, cr2
    mov [rdi], rax
    ret

; ulong get_rbp(void)
global get_rbp
get_rbp:
    mov rax, rbp
    ret

; void load_cr3(void* cr3)
global load_cr3
load_cr3:
    mov cr3, rdi
    ret

; void invlpg(void* addr)
global invlpg
invlpg:
    invlpg [rdi]
    ret

; void cpuid(uint leaf, uint subleaf, void* out)
global cpuid
cpuid:
    push rbx
    mov eax, edi
    mov ecx, esi
    cpuid
    mov [rdx + 0], eax
    mov [rdx + 4], ebx
    mov [rdx + 8], ecx
    mov [edx + 12], edx
    pop rbx
    ret

; Count leading zeros
; int clz(ulong bitset)
global clz
clz:
    test    rdi, rdi
    jz      .zero    ; trick:
    bsr     rax, rdi ; where bsr(bitset) ∈ [0,63]
    xor     eax, 63  ; 2^6 - 1 == 63, 63 ^ bitset == 63 - bitset
    ret
.zero:
    mov     eax, 64 ; clz(0) == 64
    ret

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment