HomeAboutArticles

ARM64 — Print a number

Start page1 page2 page3 page4 page5 page6 page7 page8 page9 page10

A challenge: how to print a number. We need to convert it from a 64-bit value to a string. Let us just start with hexadecimal.

A 64-bit hex-value like this: 9876543210ABCDEF. Every hexadecimal digit represents 4 bit. We can use a 4-bit mask to get a value between 0 and 15, and then somehow convert it to the corresponding hex-value. The 4 bit mask in binary would be 1111 — which is F in hex,

Simple start: just print out the first hex-digit: 9. Well, it's not printed right away, but put first in a list of bytes in memory — let's call that result.

Often a simple drawing helps. This is what I am thinking:

Somehow there is no rotate left 4 operation in the Arm64 cpu. There are logical shifts both left and right, where bits fall off the ends, and similar arithmetic shifts which do things with the sign-bit. And there is a rotate right.

But ... after wasting 45 seconds of my life ... a rotate left by 4 bits is the same as a rotate right by 60 bits.

So essentially we get the following few lines. We note that most operations have a source and a destination register, but they can be equal. And there is no store byte from an X-register to memory, but the lower 32 bit of an X-register is also known as a W-register with the same number, and you can use strb on that. So without the "repeat 15 times" we get:

        .text
        .global _start
_start:

        movz x0,0x9876,lsl #48

        adr x2,result

        ror x0,x0,60
        and x1,x0,0xF
        add x1,x1,48
        strb w1,[x2]
        add x2,x2,1

        mov x0,1   /* print to stdout */
        adr x1,result
        mov x2,17
        mov x8,0x40
        svc 0
/* And exit the program */
        mov x0,0     /* status code */
        mov x8, 93
        svc 0

result: .ascii "****************\n"

Looks right — but gives an error when running. Turns out the result-string is read-only since it is located in the code-segment, designated as such by .text. We need to make a data-segment like this:

        .data
result: .ascii "****************\n"

Just add the .data line, and it should work fine. Yes, we only get the first hex-digit printed. And notice the little trick with all the asterixes — makes it easier to see what we do, and what might not work.

Next page we will print all 16 hex-digits, and do it in two different ways.

Start page1 page2 page3 page4 page5 page6 page7 page8 page9 page10

2025-06-16