Skip to content

Instantly share code, notes, and snippets.

@suobset
Last active December 25, 2025 17:25
Show Gist options
  • Select an option

  • Save suobset/597fc6305dcc528de5588f80b6ef9465 to your computer and use it in GitHub Desktop.

Select an option

Save suobset/597fc6305dcc528de5588f80b6ef9465 to your computer and use it in GitHub Desktop.
A Merry Christmas Greeting, in ARM64 (AArch64) Asm
; festive.s - Christmas tree in memory dump
; Assemble: as -o festive.o festive.s
; Link: ld -o festive festive.o -l System -syslibroot `xcrun -sdk macosx --show-sdk-path` -e _main
;
; Created by Kush S.
;
; Read more: https://skushagra.com/posts/2025-12-25-aarch64-christmas/
;
; === BASIC WORKFLOW (tree in memory dump) ===
; lldb festive
; (lldb) b done
; (lldb) r
; (lldb) memory read $x20 $x20+160
;
; === CURSES GUI STORYTELLING MODE ===
; lldb festive
; (lldb) b main # Start of the show
; (lldb) b star # Watch the star appear
; (lldb) b tree # Tree takes shape
; (lldb) b trunk # Trunk grows
; (lldb) b message # The greeting appears
; (lldb) b done # Grand finale
; (lldb) r
; (lldb) gui
; - Press 'c' to continue to each breakpoint
; - Watch the code flow through each "act"
; - At 'done': press Esc, then type:
; memory read $x20 $x20+160
; register read x0 x1 x2 x3 x4 x5 x6 x7
; - Screenshot the tree + festive registers!
.global _main
.align 4
.data
canvas: .space 256
.text
_main:
adrp x20, canvas@PAGE
add x20, x20, canvas@PAGEOFF
star:
; Each row is 16 bytes = one line in memory dump
; The ASCII column on the right will show our art
; Row 0: " * " (16 chars, star centered)
mov w0, #0x2020
strh w0, [x20, #0]
strh w0, [x20, #2]
strh w0, [x20, #4]
mov w0, #0x2A ; *
strb w0, [x20, #6]
mov w0, #0x2020
strh w0, [x20, #7]
strh w0, [x20, #9]
strh w0, [x20, #11]
strh w0, [x20, #13]
mov w0, #0x20
strb w0, [x20, #15]
tree:
; Row 1: " /|\ "
mov w0, #0x2020
strh w0, [x20, #16]
strh w0, [x20, #18]
mov w0, #0x20
strb w0, [x20, #20]
mov w0, #0x2F ; /
strb w0, [x20, #21]
mov w0, #0x7C ; |
strb w0, [x20, #22]
mov w0, #0x5C ; backslash
strb w0, [x20, #23]
mov w0, #0x2020
strh w0, [x20, #24]
strh w0, [x20, #26]
strh w0, [x20, #28]
strh w0, [x20, #30]
; Row 2: " /|||\ "
mov w0, #0x2020
strh w0, [x20, #32]
strh w0, [x20, #34]
mov w0, #0x2F ; /
strb w0, [x20, #36]
mov w0, #0x7C ; |
strb w0, [x20, #37]
strb w0, [x20, #38]
strb w0, [x20, #39]
mov w0, #0x5C ; backslash
strb w0, [x20, #40]
mov w0, #0x2020
strh w0, [x20, #41]
strh w0, [x20, #43]
strh w0, [x20, #45]
mov w0, #0x20
strb w0, [x20, #47]
; Row 3: " /|||||\ "
mov w0, #0x2020
strh w0, [x20, #48]
mov w0, #0x20
strb w0, [x20, #50]
mov w0, #0x2F ; /
strb w0, [x20, #51]
mov w0, #0x7C ; |
strb w0, [x20, #52]
strb w0, [x20, #53]
strb w0, [x20, #54]
strb w0, [x20, #55]
strb w0, [x20, #56]
mov w0, #0x5C ; backslash
strb w0, [x20, #57]
mov w0, #0x2020
strh w0, [x20, #58]
strh w0, [x20, #60]
strh w0, [x20, #62]
; Row 4: " /|||||||\ "
mov w0, #0x2020
strh w0, [x20, #64]
mov w0, #0x2F ; /
strb w0, [x20, #66]
mov w0, #0x7C ; |
strb w0, [x20, #67]
strb w0, [x20, #68]
strb w0, [x20, #69]
strb w0, [x20, #70]
strb w0, [x20, #71]
strb w0, [x20, #72]
strb w0, [x20, #73]
mov w0, #0x5C ; backslash
strb w0, [x20, #74]
mov w0, #0x2020
strh w0, [x20, #75]
strh w0, [x20, #77]
mov w0, #0x20
strb w0, [x20, #79]
trunk:
; Row 5: " | " (trunk)
mov w0, #0x2020
strh w0, [x20, #80]
strh w0, [x20, #82]
strh w0, [x20, #84]
mov w0, #0x7C ; |
strb w0, [x20, #86]
mov w0, #0x2020
strh w0, [x20, #87]
strh w0, [x20, #89]
strh w0, [x20, #91]
strh w0, [x20, #93]
mov w0, #0x20
strb w0, [x20, #95]
; Row 6: " ||| " (trunk base)
mov w0, #0x2020
strh w0, [x20, #96]
strh w0, [x20, #98]
mov w0, #0x20
strb w0, [x20, #100]
mov w0, #0x7C ; |
strb w0, [x20, #101]
strb w0, [x20, #102]
strb w0, [x20, #103]
mov w0, #0x2020
strh w0, [x20, #104]
strh w0, [x20, #106]
strh w0, [x20, #108]
strh w0, [x20, #110]
; Row 7: " " (blank)
mov w0, #0x2020
strh w0, [x20, #112]
strh w0, [x20, #114]
strh w0, [x20, #116]
strh w0, [x20, #118]
strh w0, [x20, #120]
strh w0, [x20, #122]
strh w0, [x20, #124]
strh w0, [x20, #126]
message:
; Row 8: " MERRY CHRISTMAS" (16 chars exactly)
mov w0, #0x20
strb w0, [x20, #128]
mov w0, #0x4D ; M
strb w0, [x20, #129]
mov w0, #0x45 ; E
strb w0, [x20, #130]
mov w0, #0x52 ; R
strb w0, [x20, #131]
strb w0, [x20, #132]
mov w0, #0x59 ; Y
strb w0, [x20, #133]
mov w0, #0x20
strb w0, [x20, #134]
mov w0, #0x43 ; C
strb w0, [x20, #135]
mov w0, #0x48 ; H
strb w0, [x20, #136]
mov w0, #0x52 ; R
strb w0, [x20, #137]
mov w0, #0x49 ; I
strb w0, [x20, #138]
mov w0, #0x53 ; S
strb w0, [x20, #139]
mov w0, #0x54 ; T
strb w0, [x20, #140]
mov w0, #0x4D ; M
strb w0, [x20, #141]
mov w0, #0x41 ; A
strb w0, [x20, #142]
mov w0, #0x53 ; S
strb w0, [x20, #143]
; Row 9: " DEC 25 2025 "
mov w0, #0x2020
strh w0, [x20, #144]
mov w0, #0x20
strb w0, [x20, #146]
mov w0, #0x44 ; D
strb w0, [x20, #147]
mov w0, #0x45 ; E
strb w0, [x20, #148]
mov w0, #0x43 ; C
strb w0, [x20, #149]
mov w0, #0x20
strb w0, [x20, #150]
mov w0, #0x32 ; 2
strb w0, [x20, #151]
mov w0, #0x35 ; 5
strb w0, [x20, #152]
mov w0, #0x20
strb w0, [x20, #153]
mov w0, #0x32 ; 2
strb w0, [x20, #154]
mov w0, #0x30 ; 0
strb w0, [x20, #155]
mov w0, #0x32 ; 2
strb w0, [x20, #156]
mov w0, #0x35 ; 5
strb w0, [x20, #157]
mov w0, #0x2020
strh w0, [x20, #158]
; Festive registers for bonus screenshot
mov x0, #0xDEC
mov x1, #0x25
mov x2, #0x2025
mov x3, #0xCAFE
mov x4, #0xF00D
mov x5, #0xBEEF
mov x6, #0x1CE
mov x7, #0xC01D
done:
mov x0, #0
mov x16, #1
svc #0x80
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment