From 80f5fdc2a4cb55cfd52aca5eed0b8055d3aae61a Mon Sep 17 00:00:00 2001 From: itamar Date: Fri, 20 Mar 2026 18:37:13 +0000 Subject: [PATCH] push --- print.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 print.c diff --git a/print.c b/print.c new file mode 100644 index 0000000..c117b22 --- /dev/null +++ b/print.c @@ -0,0 +1,121 @@ +static long sys_write(int fd, const char *buf, long len) +{ + long ret; + __asm__ volatile ( + "syscall" + : "=a"(ret) + : "0"(1L), + "D"((long)fd), + "S"(buf), + "d"(len) + : "rcx", "r11", "memory" + ); + return ret; +} + +static void sys_exit(int code) +{ + __asm__ volatile ( + "syscall" + : + : "a"(60L), + "D"((long)code) + : + ); + __builtin_unreachable(); +} + +static long strlen(const char *s) +{ + long n = 0; + while (s[n]) n++; + return n; +} + +static void print_char(char c) +{ + sys_write(1, &c, 1); +} + +static void str(const char *s) +{ + long n = strlen(s); + if (n > 0) sys_write(1, s, n); +} + +static void uint(unsigned long v) +{ + char buf[20]; + int i = 19; + buf[i] = '\0'; + if (v == 0) { print_char('0'); return; } + while (v && i > 0) { + buf[--i] = '0' + (v % 10); + v /= 10; + } + str(buf + i); +} + +static void print_int(long v) +{ + if (v < 0) { print_char('-'); uint((unsigned long)-v); } + else uint((unsigned long)v); +} + +static void hex(unsigned long v) +{ + static const char *digits = "0123456789abcdef"; + char buf[17]; + int i = 16; + buf[i] = '\0'; + if (v == 0) { str("0x0"); return; } + while (v && i > 0) { + buf[--i] = digits[v & 0xf]; + v >>= 4; + } + buf[--i] = 'x'; + buf[--i] = '0'; + str(buf + i); +} + +typedef __builtin_va_list va_list; +#define va_start(ap, last) __builtin_va_start(ap, last) +#define va_arg(ap, T) __builtin_va_arg(ap, T) +#define va_end(ap) __builtin_va_end(ap) + +static void impl(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + for (const char *p = fmt; *p; p++) { + if (*p != '%') { print_char(*p); continue; } + p++; + switch (*p) { + case 'd': print_int(va_arg(ap, int)); break; + case 'l': p++; /* assume %ld */ + print_int(va_arg(ap, long)); break; + case 'u': uint(va_arg(ap, unsigned int)); break; + case 'x': hex(va_arg(ap, unsigned long)); break; + case 's': str(va_arg(ap, const char *)); break; + case 'c': print_char((char)va_arg(ap, int)); break; + case '%': print_char('%'); break; + default: print_char('%'); print_char(*p); break; + } + } + va_end(ap); +} + +#define print(fmt, ...) impl((fmt), ##__VA_ARGS__) + +void _start(void) +{ + print("Hello, world!\n"); + print("Integer: %d\n", -42); + print("Unsigned: %u\n", 1337u); + print("Hex: %x\n", (unsigned long)0xDEADBEEF); + print("String: %s\n", "no libc needed"); + print("Char: %c\n", 'Z'); + print("Long: %ld\n", (long)-9876543210L); + print("Two args: %d + %d = %d\n", 10, 20, 30); + sys_exit(0); +} \ No newline at end of file