SPO600 - Lab 5
Tags: opensource
Published: 2021-12-12 18:13:13

## Instruction
This blog post will describe the process and the finding of lab 5 - 64-bit Assembler Lab. In this lab, we will experiment with assembler on the x86_64 and Aarch64 platforms.

## Brief instruction about lab 5
   * Review, build, and run the aarch64 assembly language programs. Take a look at the code using `objdump -d objectfile` and compare it to the source code.
   * Take a basic loop in AArch64 assembler as an example. This loops from  `0` to `9`, using `r19` as the index counter.
   * Repeat the previous one with x86_64 server.
   * Extend the AArch64 code to loop from `00` to `30`, printing each value as a 2-digit decimal number.

## Process

In order to loop the message, it needs the loop index for the starting point and the ending point. It also needs a subroutine to execute looping.

As the code loops 30 times, there would include two cases of printing the digits, which is printing 1-digit and printing 2-digits. Therefore, it needs two subroutines for each case. To print the digit depends on the each loop, the blank spaces `' '` is added in the message `msg: .ascii "Loop: \n"`.

To be honest, our group was having difficulties with this lab because no one is familiar with assembly language, and we have to figure out some thing that we are not confident with. Even though we already have the example code, but it still takes us a couple of days to find out the answer. This is the code for **AArch64** architecture:
```
.text
.globl _start
_start:

mov x4, 0 /* file descriptor: 1 is stdout */
mov w10, 0x3 /* Value of 0 in ascii */

loop:
add w24, w4, 0x30 /* Converting iterator to ascii */
mov x11, 10 /* Using 10 as a divider */
udiv x12, x4, x11 /* Getting equitent */
msub x13, x11, x12, x4 /* Getting the remainder */

add w14, w12, 0x30 /* Ascii conversion */
add w15, w13, 0x30 /* Ascii conversion */

adr x16, msg /* Storing the message */
strb w15, [x16, 7] /* Storing remainder into msg at byte 7 */
cmp w14, w10 /* Is 0 */
strb w14, [x16, 6] /* Storing quotient in msg at byte 6 */

mov x0, 1 /* file descriptor */
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 x4, x4, 1
cmp x4, 31 /* Checks if the iterator equals 31 */
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
```

Once we make the code work on AArch64, it seems to be easier to apply the same concept on **x86_64** architecture. I got the code working from the code below: 
```
.text
.globl _start

_start:

mov $0, %r15 /* Loop counter */
mov $0x30, %r12 /* value of 0 in Ascii */

loop:
mov $0, %rdx /* clearing reminder for division */
mov %r15, %rax /* set rax to be divide */
mov $10, %r10 /* set divisor */
div %r10 /* divide */
mov %rax, %r14 /* store quotient */
mov %rdx, %r13 /* store remainder */

// Here we are adding quotient and remainder to message
add $0x30, %r14 /* quotient to ascii */
add $0x30, %r13 /* remainder to ascii */
mov %r13b, msg+7 /* Modify 1 byte inmsg with remainder */

// Here we check if the first digit is 0, if it is then we ship it
cmp %r12, %r14
je print
mov %r14b, msg+6 /* Modify 1 byte in msg with quotient */

print:
mov $len, %rdx /* message length */
mov $msg, %rsi /* message location */
mov $1, %rdi /* file descriptor stdout */
mov $1, %rax /* syscall sys_write */
syscall

inc %r15 /* increment counter */
cmp $31, %r15 /* see if we're done */
jne loop /* if not, loop */

// Here we are exiting the loop
mov $0, %rdi /* exit status */
mov $60, %rax /* syscall sys_exit */
syscall

.section .data

msg: .ascii "Loop: \n"
len = . - msg
```

And this is the result from the code in x86_64 platform ![x86_64 lab 5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4o6tl9w7d76l1csxkndm.png)
 
## Conclusion
In lab 5, I have learned how to implement code using **AArch64** and **x86_64** architecture. In addition, I gained a basic understanding of the differences between these two platforms and 6502 Assembler. Even though it is hard, but still doable, so I would further spend more time on this in the future.