01_syscall_write.c (1811B)
1 /* Tier 1: pure syscall, no libc functions. main() returns 0. We invoke 2 * the write(2) syscall by inline asm so the only thing musl provides is 3 * crt1's _start, _start_c, and __libc_start_main + the static linkage of 4 * unused libc.a archive members (none should be pulled in). */ 5 6 #include <unistd.h> 7 8 static const char msg[] = "hello-syscall\n"; 9 10 int main(void) { 11 /* sys_write(1, msg, sizeof(msg) - 1) via the raw kernel-entry insn. 12 * Per-arch because the syscall ABI (register set + entry insn + the 13 * SYS_write number itself) is wholly arch-specific. */ 14 #if defined(__aarch64__) 15 register long x8 __asm__("x8") = 64; /* SYS_write */ 16 register long x0 __asm__("x0") = 1; /* fd */ 17 register long x1 __asm__("x1") = (long)msg; 18 register long x2 __asm__("x2") = sizeof(msg) - 1; 19 __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1), "r"(x2) : "memory"); 20 #elif defined(__riscv) && __riscv_xlen == 64 21 register long a7 __asm__("a7") = 64; /* SYS_write */ 22 register long a0 __asm__("a0") = 1; /* fd */ 23 register long a1 __asm__("a1") = (long)msg; 24 register long a2 __asm__("a2") = sizeof(msg) - 1; 25 __asm__ volatile("ecall" : "+r"(a0) : "r"(a7), "r"(a1), "r"(a2) : "memory"); 26 #elif defined(__x86_64__) 27 /* SysV x86_64 syscall ABI: nr in %rax, args in %rdi/%rsi/%rdx, 28 * %rcx and %r11 clobbered by the `syscall` instruction itself. */ 29 register long rax __asm__("rax") = 1; /* SYS_write */ 30 register long rdi __asm__("rdi") = 1; /* fd */ 31 register long rsi __asm__("rsi") = (long)msg; 32 register long rdx __asm__("rdx") = sizeof(msg) - 1; 33 __asm__ volatile("syscall" 34 : "+r"(rax) 35 : "r"(rdi), "r"(rsi), "r"(rdx) 36 : "rcx", "r11", "memory"); 37 #else 38 #error "01_syscall_write: no syscall sequence for this arch" 39 #endif 40 return 0; 41 }