From 3712c0af48b9cc68fe52729cb7aa24006e35cb5d Mon Sep 17 00:00:00 2001 From: Alexis Hovorka Date: Sat, 17 Aug 2024 19:32:33 -0600 Subject: [post] AArch64 Bootstrapping 1 --- static/20240817-aarch64-bootstrapping-1/hex.c | 32 +++++++++ static/20240817-aarch64-bootstrapping-1/hex.s | 95 +++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 static/20240817-aarch64-bootstrapping-1/hex.c create mode 100644 static/20240817-aarch64-bootstrapping-1/hex.s (limited to 'static/20240817-aarch64-bootstrapping-1') diff --git a/static/20240817-aarch64-bootstrapping-1/hex.c b/static/20240817-aarch64-bootstrapping-1/hex.c new file mode 100644 index 0000000..aca16e2 --- /dev/null +++ b/static/20240817-aarch64-bootstrapping-1/hex.c @@ -0,0 +1,32 @@ +#include + +int main(void) { + char c = 0; // Input character + int count = 0; // Hex digits parsed for this number + long long v = 0; // Current value + + while ((c = getchar()) != EOF) { + + // Skip comments + if (c == '\\') { while ((c = getchar()) != EOF && c != '\n') {} } + + // Process incoming digits and add to running value + else if (('0' <= c) && (c <= '9')) { v = (v << 4) + (c - '0'); count++; } + else if (('a' <= c) && (c <= 'f')) { v = (v << 4) + (c - 'a' + 10); count++; } + + // Send the finished number out the other end + else if (c == ' ') { + + // Turn the number of hex digits into a number of bytes + if (count & 1) count++; + count >>= 1; + + // Emit each byte, littlest first + for (; count>0; count--) { + c = v & 0xFF; + putchar(c); + v >>= 8; + } + } + } +} diff --git a/static/20240817-aarch64-bootstrapping-1/hex.s b/static/20240817-aarch64-bootstrapping-1/hex.s new file mode 100644 index 0000000..b120014 --- /dev/null +++ b/static/20240817-aarch64-bootstrapping-1/hex.s @@ -0,0 +1,95 @@ +.section .data +buf: + .byte 0 // input/output character buffer + +.section .text +.global _start +_start: + mov x19, #0 // value + mov x20, #0 // count + +loop: + mov x8, #63 // read + mov x0, #0 // stdin + adr x1, buf + mov x2, #1 + svc 0 + + cmp x0, #0 // count of bytes read; 0 means EOF + b.ne 1f + +exit: + mov x8, #93 // exit + mov x0, #0 // error code (no error) + svc 0 + +1: + adr x1, buf + ldurb w9, [x1] + + cmp w9, #92 // backslash; start of comment + b.ne 2f + +comment: + mov x8, #63 // read + mov x0, #0 // stdin + adr x1, buf + mov x2, #1 + svc 0 + + cmp x0, #0 + b.eq exit + + adr x1, buf + ldurb w9, [x1] + cmp w9, '\n' + b.ne comment + b loop + +2: + cmp w9, '0' + b.lt 3f + cmp w9, '9' + b.gt 3f + + sub w9, w9, '0' + b 4f + +3: + cmp w9, 'a' + b.lt 5f + cmp w9, 'f' + b.gt 5f + + sub w9, w9, ('a' - 10) + b 4f + +4: + lsl x19, x19, #4 + add x19, x19, w9, uxtb + add x20, x20, #1 + b loop + +5: + cmp w9, ' ' + b.ne loop + + tst x20, #1 + cinc x20, x20, ne + lsr x20, x20, #1 + +6: + cmp x20, #0 + b.eq loop + + mov x8, #64 // write + mov x0, #1 // stdout + adr x1, buf + sturb w19, [x1] + mov x2, #1 + svc 0 + + lsr x19, x19, #8 + + sub x20, x20, #1 + b 6b -- cgit v1.2.3-70-g09d2