asm_book/section_1/walkies/main.s
2022-10-27 14:30:38 -05:00

122 lines
2.2 KiB
ArmAsm

.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