; ARM assembly tutorial for Asmonite, example 16: ways to load a constant (Raspberry Pi Pico 2, Arm Cortex-M33).
; Adapted from the ARM-ASM-Tutorial by Niklas Guertler (section "Literal loads"); see LICENSE.txt.
;
; An instruction is 2 or 4 bytes long, so a 32-bit constant does not fit into it. Four ways:
;   1. "mov"/"movs" with a small number, or a number of the form "8 bits, shifted" (0x00ab0000,
;      0xab00ab00, 0xabababab ...): one instruction
;   2. "movw" (the low 16 bits) and "movt" (the high 16 bits): two instructions, any number
;   3. "ldr r0, name": the word at the label name, relative to the pc; the constant stands behind the code
;      (GNU as writes this for "ldr r0, =value" and collects the constants itself; in Asmonite they are
;      written out)
;   4. "adr r0, name": not a value but the address of a label, relative to the pc
.target pico2
.arch thumb
.imagebase 0x20000000

_start:
    movs r0, #200               ; 1. 0 .. 255
    mov  r1, #0x00ab0000        ; 1. 8 bits, shifted
    mov  r2, #0xab00ab00        ; 1. a pattern of bytes
    movw r3, #0x5678            ; 2. low half, the high half becomes 0
    movt r3, #0x1234            ; 2. high half: r3 = 0x12345678
    ldr  r4, lit_big            ; 3. from the word behind the code
    adr  r5, lit_big            ; 4. the address of that word
    b    $

    align 4
lit_big: dd 0xdeadbeef
