Moving to the Aarch64 architecture I found difficulties with adapting to the assemlby language at first.
Everything is reversed whereas on the x86 comp if we wanted to move the register we would use this command and please note the other differences as well here.
x86
mov %rax,%r15 // We are moving the value of %rax into -> %r15
Aarch64
mov x0,x15 // We are moving the value of x15 into -> x0
------------------------------
OTHER NOTES
-----------------------------
Note how on x86 we were going right to left while on ARM ( Aarch64 ) we went from right to left. It is also worth noting that while on the x86 gas assembly language we used % to identify a register while on the ARM we exclude this symbol.
On the ARM architecture a register can have 3 different preceding characters r,x,w whereas r is ambiguos, x is 64 bits and w is 32 bits.
-----------------------------
WRITING TO MEMORY
-----------------------------
Also on the ARM architecture which i discovered is that you cannot write to memory from an address, you need to move that memory first into a register using the adr command, make your changes then move it back once again versus the x86 where we could directly modify a piece of memory
If we have a piece of text in memory and want to add to it, it is not as simple as the x86 way of just calling a mov %register,msg+5 we must first move that memory into a register in ARM architecture
In order for us to write to memory we first need to use the adr command and move the block of memory into a register
adr x15,[msg+6] // msg is our block of memory and the +6 is location within that memory address
Next we need to store a value we wish to save into another register and add 48 to it so that it can be interpreted as text
mov x14,15
add x14,x14,48
Finally we need to store the value into the register that holds the memory location
strb w14,[x15] Note we are using w14 because we only want to store a single byte, if we used x14 we would override the register with too much data and get an error.
Because x15 has the memory location of msg stored in it, we do not need to do anything else. x15 is a pointer to msg now, and whatever we do to x15 we do to msg.
----------------------
PRINTING NUMBER 0-30 IN A LOOP
----------------------
Using the div command was a bit differnt on the Aarch64 compared to the X86 because the ARM architecture does not hold the remainder in a register like in x86. So in order for us to get the remainder we needed to use a separate command to extract it from the quotient as seen below.
udiv x0,x1,x2 // x0 is where the output of x1 the divident ( divided ) by x2 the diviser will be stored
msub x4,x0,x2,x1 // x4 will be where our remainder is stored. Basically x0 is the quotient from above and we subtract that from x2 * x1
Now we have our remainder and quotient we can print them both out 01,02,03...29,30
----------------------
SURPRESSING LEADING 0's
----------------------
This part was very similar to the x86 version of our program, basically we do a compare and a jump if statement
cmp x0,0 // x0 is the register that holds our quotient and we compare it to 0
b.eq $label // If the above compare is true that x0 == 0 we will branch to our label which will skip over any leading 0 characters
----------------------
FULL CODE
----------------------
.text
.globl _start
start = 0 // Global variables
max = 30
_start:
mov x19,start
loop:
mov x12,10 // These 3 lines find the quotient and the remainder
udiv x13,x19,x12
msub x14,x13,x12,x19
cmp x13,0 // Skip leading zero characters
b.eq print
adr x15,msg + 5 // Append the quotient to our string if it is not zero
add x13,x13,48
strb w13,[x15]
print:
adr x11,msg+6 // Append the remainder to our string
add x14,x14,48
strb w14,[x11]
// Print our message
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 // Loop if x19 is less than 30
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
Comments