DEV Community

gus
gus

Posted on

AArch64 Assembly Language Part I

Today I'm moving on from the 6502 processor and starting to work with 64 bit assembly language. My tasks this time are to build off of two assembly code examples, one for the AArch64 architecture and the other for x86_64, to first print 0-9 in a loop and then 0-30.

First off, I'll be working with the AArch64 program. The starting point given to us is as follows:

.text
.globl _start

min = 0                          /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 30                         /* loop exits when the index hits this number (loop condition is i<max) */

_start:

    mov     x19, min

loop:

    /* ... body of the loop ... do something useful here ... */

    add     x19, x19, 1
    cmp     x19, max
    b.ne    loop

    mov     x0, 0           /* status -> 0 */
    mov     x8, 93          /* exit is syscall #93 */
    svc     0               /* invoke syscall */
Enter fullscreen mode Exit fullscreen mode

This code loops until it reaches 30 but doesn't do anything within the loop yet. Our first task is to change this so it prints each time a loop iteration executes. By adding in some code provided to us for printing a message we get the following:

.text
.globl _start

min = 0                          /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 10                         /* loop exits when the index hits this number (loop condition is i<max) */

_start:

    mov     x19, min

loop:

    mov     x0, 1           /* file descriptor: 1 is stdout */
    adr     x1, msg         /* message location (memory address) */
    mov     x2, len         /* message length (bytes) */

    mov     x8, 64          /* write is syscall #64 */
    svc     0               /* invoke syscall */

    add     x19, x19, 1 
    cmp     x19, max
    b.ne    loop

    mov     x0, 0           /* status -> 0 */
    mov     x8, 93          /* exit is syscall #93 */
    svc     0               /* invoke syscall */

.data
msg:    .ascii      "Loop\n"
len=    . - msg
Enter fullscreen mode Exit fullscreen mode

And the output is:

Loop
Loop
Loop
Loop
Loop
Loop
Loop
Loop
Loop
Loop
Enter fullscreen mode Exit fullscreen mode

Next up is to get the loop to print a number that iterates each time the loop repeats. I modified the code like so:

.text
.globl _start

min = 0                          /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 10                         /* loop exits when the index hits this number (loop condition is i<max) */

_start:

    mov     x19, min

loop:

    add    x18, x19, '0'         
    adr    x17, msg+6            
    strb   w18, [x17]            

    mov     x0, 1                /* file descriptor: 1 is stdout */
    adr     x1, msg              /* message location (memory address) */
    mov     x2, len              /* message length (bytes) */

    mov     x8, 64               /* write is syscall #64 */
    svc     0                    /* invoke syscall */

    add     x19, x19, 1       
    cmp     x19, max
    b.ne    loop

    mov     x0, 0                /* status -> 0 */
    mov     x8, 93               /* exit is syscall #93 */
    svc     0                    /* invoke syscall */

.data
msg:    .ascii      "Loop: #\n"
len=    . - msg
Enter fullscreen mode Exit fullscreen mode

And got the appropriate output:

Loop: 0
Loop: 1
Loop: 2
Loop: 3
Loop: 4
Loop: 5
Loop: 6
Loop: 7
Loop: 8
Loop: 9
Enter fullscreen mode Exit fullscreen mode

Next time I'll implement iterating until 30, after which I'll tackle the same on an x86_64 architecture. More on that soon!

Top comments (0)