.global main .align 2 /* Walkies - a silly animation using four characters on the Linux console. This program demonstrates low level IO (write()) and is written in the form of an infinite loop (i.e. ^C or kill will be required to halt the program). */ counter .req w20 delta .req w21 .equ MAX_COLUMN, 60 .equ NUM_CHARS, 4 .section .rodata CHARS: .asciz "|/_\\" TRM: .asciz " \r" .text main: stp x29, x30, [sp, -16]! stp x20, x21, [sp, -16]! mov counter, wzr mov w0, wzr mov delta, 1 0: bl Pad bl Emit bl Terminator add counter, counter, delta mov w0, MAX_COLUMN cmp w0, counter bne 1f neg delta, delta b 2f 1: cbnz counter, 2f neg delta, delta 2: ldr x0, =usec ldr w0, [x0] bl usleep b 0b ldp x20, x21, [sp], 16 ldp x29, x30, [sp], 16 mov w0, wzr ret /* Terminator - outputs "\r " - notice the space after the carriage return. */ Terminator: stp x29, x30, [sp, -16]! mov w0, 1 // 1 is stdout ldr x1, =TRM // Pointer to string mov w2, 2 // 2 characters being printed bl write ldp x29, x30, [sp], 16 ret /* Emit - puts out the symbol derived from counter. */ Emit: stp x29, x30, [sp, -16]! mov w0, counter mov w1, NUM_CHARS bl mod ldr x1, =CHARS add x1, x1, x0 mov w0, 1 mov w2, 1 bl write ldp x29, x30, [sp], 16 ret /* Pad - prints w0 spaces to the console. */ Pad: stp x29, x30, [sp, -16]! str delta, [sp, -16]! mov w21, wzr 1: ldr x1, =buff mov w2, ' ' strb w2, [x1] // ' ' is pointed to by x1 mov w0, 1 // 1 is stdout mov w2, 1 // emitting 1 byte bl write add w21, w21, 1 cmp w21, counter blt 1b ldr delta, [sp], 16 ldp x29, x30, [sp], 16 ret /* mod(a, b) - implements a % b - AARCH64 lacks a mod instruction. A strange place to economize, but there you have it. a comes to us in x0 b comes to us in x1 method: * integer divide a by b for example - 5 % 3 would need 5 // 3 yielding 1 * multiply result by b 1 * 3 is 3 * subtract result from a 5 - 3 is 2 and that's our return value. */ mod: sdiv x2, x0, x1 // x2 gets a // b msub x0, x2, x1, x0 // x0 gets a - a // b * b ret .data buff: .space 4 usec: .int 75000