Changing the Output in (ARM64) Assembly

When ever I write new console based code from scratch, I start with “Hello World.” Then I make one small change at a time, test it, and commit. Then I move on. While this slow process might seem tedious, it is based on years of wasting time debugging my own poorly written code in interim changes.

Once I had “Hello, World!” working in assembly, I want to make a single character change to message and see it in the console. Here’s my steps.

Let’s start with “Hello, World.” I got this out of Programming with 64-Bit ARM Assembly Language. The team there gets extra Kudos for using Git to put the book together in a public fashion.

/* Hello, World */
/* data segment: define our messag string and calculate its length. */
    .ascii        "Hello, World!\n"
len = . - msg
/*our application's entry point */
.globl _start
    /*syscall write(int fd, const void *buf, size_t count) */
    mov  x0, #1   /* fd := STDOUT_FILENO */
    ldr  x1, =msg  /* buf := msg */
    ldr  x2, =len  /* count = lent */
    mov  w8, #64   /* write is syscall #64 */
    svc  #0        /*invoke syscall */
    /* syscall exit (int status) */
    mov    x0, #0    /* status  := 0 */
    mov    w8,  #93  /* exit is syscall #1 */
    svc    #0

The first technique we need in order to change the message is the ability to put a value into a specified memory location. To store the value of the byte stored in the w3 register into the memory locations specified by the X4 register, we use the following command.

    strb w3, [X4]

I mentally pronounce that as “strib” but it should really be thought of as “store byte.”

The Message is already in the register X1. So, we can move this value into X4 (so we can modify it later)

    mov  X4, X1

and move the value we want to put into the buffer into the w3 register. #65 is ascii A.

   mov  w3, #65

Then Store that value in w3 in the memory location pointed to by X4 using the strb command above. The body of the code (minus the return at the end) looks like this:

    mov  x0, #1   /* fd := STDOUT_FILENO */
    ldr  x1, =msg  /* buf := msg */
    ldr  x2, =len  /* count = lent */
    mov  w3, #65
    mov  X4, X1
    strb w3, [X4]
    mov  w8, #64
    svc  #0

Looks like this:

$ make modified ; ./modified 
as -g -o modified.o modified.s
ld -o modified modified.o
Aello, World!

Next up is changing the whole message.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.