💾 Archived View for home.tobot.dev › cgi › env.c captured on 2022-03-01 at 15:12:56.
-=-=-=-=-=-=-
typedef unsigned int size_t; #define noreturn _Noreturn #define SYS_exit 1 #define SYS_write 4 #define STDOUT 1 noreturn void exit(int error_code) { asm("mov r0, %0\n\t" "mov r7, %1\n\t" "swi 0\n\t" : : "r" (error_code), "r" (SYS_exit) : "r0", "r7"); while(1); } #define writel(fd, buf) write(fd, buf, strlen(buf)) inline int write(unsigned int fd, const char* buf, size_t count) { asm("mov r0, %0\n\t" "mov r1, %1\n\t" "mov r2, %2\n\t" "mov r7, %3\n\t" "swi 0\n\t" : : "r" (fd), "r" (buf), "r" (count), "r" (SYS_write) : "r0", "r1", "r2", "r7"); } inline size_t strlen(char const* const str) { size_t len = 0; while(str[len++] != 0); return len; } int main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; writel(STDOUT, "20 text/gemini\r\n# Hello, C!\r\nThis page was generated from C code (without any libraries like glibc!)"); if(argc > 0) { writel(STDOUT, "\r\n## argv:"); for(int i = 0; i < argc; i++) { writel(STDOUT, "\r\n"); writel(STDOUT, argv[i]); } } if(envp[0] != 0) { writel(STDOUT, "\r\n## envp:"); unsigned char i = 0; while(envp[i] != 0 && i < 254) { writel(STDOUT, "\r\n"); writel(STDOUT, envp[i]); i++; } } return 0; } asm( ".global _start\n" "_start:\n" // Clear frame pointer and link register because there's no outer scope "mov fp, #0\n" "mov lr, #0\n" // ---- // set up argc, argv, and envp // in r0, r1, and r2 respectively "ldr r0, [sp]\n" // argc = *sp "mov r1, #4\n" // argv = 4 "add r1, sp\n" // argv += sp // => argv = sp+4 "mov r2, #8\n" // envp = 8 "mul r2, r2, r0\n" // envp *= argc "add r2, sp\n" // envp += sp "add r2, #8\n" // envp += 8 // => envp = sp + 8 + (8 * argc) "bl main\n" // main(argc, argv, envp) "bl exit\n" // exit($?) );