Start page1 page2 page3 page4 page5 page6 page7 page8 page9 page10
The main part of the print one hex-digit from last page is:
ror x0,x0,60
and x1,x0,0xF
add x1,x1,48
strb w1,[x2]
add x2,x2,1
And it printed the number "9" very nicely. We need 15 more
of the hex-digits. What to do? The maybe obvious way is just to
repeat the 5 lines above another 15 times. Yeah, it works, and you must
simply try it out. Notice that x2
pointing to the result string
is incremented in the last line above, ready for the next digit.
Well, actually it doesn't quite work, since the hex-digits A-F are printed as some math-symbols, that follow 0-9 in the ASCII table. We will fix that in a moment.
But first we might not like just repeating those 5 lines of
assembler code. We could perhaps make a loop, executing it 16 times.
Say welcome to register x3
which we will make count from 16 down to 0.
.text
.global _start
_start:
movz x0,0x9876,lsl #48
movk x0,0x5432,lsl #32
movk x0,0x10FE,lsl #16
movk x0,0xDCBA
/* x0 to hex begin */
movz x3,16
adr x2,result
again: ror x0,x0,60
and x1,x0,0xF
add x1,x1,48
strb w1,[x2]
add x2,x2,1
subs x3,x3,1
bne again
/* x0 to hex end */
mov x0,1
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
.data
result: .ascii "****************\n"
x3
start with the value 16, and is decremented in the subs
instruction. The extra s
is important as this will set the flags, N,
Z, C, V.
N is for a resulting negative value, Z for a zero value, C for carry, and V for overflow.
We want to stop the loop when we reach 0, so
we will use a bne
, branch not equal, understood as branch if
not equal to zero. Test it. It should work. Except for A-F.
The thing is that we should only add 48 if the value is 9 or less, and add 55 if the value is 10 or more. We must compare and jump around.
The code below replaces the code between the two comments
/* x0 to hex begin */
and
/* x0 to hex end */
.
In Arm64 we dont jump — we branch, as you have already seen, but at least we compare:
movz x3,16
adr x2,result
again: ror x0,x0,60
and x1,x0,0xF
cmp x1,10
bge isAtoF
add x1,x1,48
b done
isAtoF: add x1,x1,55
done: strb w1,[x2]
add x2,x2,1
subs x3,x3,1
bne again
So either we add 48, or we add 55. It's just an if/else.
cmp
obviously always sets the
flags, no need for an extra s
. It could be done differently, with
a table of the digits, and a lookup in that table based on the value. This
is left as an exercise for the reader.
We have some nice code now, but a bit hard to reuse. We will make it a function (or procedure or subroutine or method — call it what you like). This will happen on the next page.
Start page1 page2 page3 page4 page5 page6 page7 page8 page9 page10
2025-06-16