Lab 5 - SPO600
Published: 2021-11-27 19:44:50

## Introduction
Hello everyone, my name is Dustin. Today I'd like to talk about my experience of working with Loops in AArch64 and x86_64 Assembly. Stay tuned!

## Progress
For previous weeks, I got a chance to work with 6502 Assembly language which is quite not my interest but when moving to aarch64 and x86_64, I found it a little bit easier to understand! However, this is still difficult to our group. It requires a lot of thinking and we were struggling so hard to get it running correctly.

Lab 5 instruction can be found [here](https://wiki.cdot.senecacollege.ca/wiki/SPO600_64-bit_Assembler_Lab).

For this lab, we're asked to extend the assembler program (both x86_64 and aarch64) to suppress the high digit when it is 0. In other words, the printed values should progress from 0-30 instead of from 00-30. It is ok to output a space in place of the suppressed digit (this will cause the numbers to be aligned vertically in the output)

For this lab, instead of using an emulator that we've been using for the last couple weeks, we're now using Linux to build and run the program. 

In order to compile an assembly file, we had to run two commands. In this case, we have a file name `helloWorld.s` so we have to use this command `as -g -o helloWorld.o helloWorld.s` to compile it. And then we have to take our helloWorld.o file and link it using this command `ld -o helloWorld helloWorld.o` and then we can actually run our program using this command `./helloWorld`. This is quite a heavy step but it is what it is. Normally this is we have to do under the hood but visual studio or other IDMs have taken care for us. If you're trying hardcore and using command line completely, you may feel like using this.

After taking a look at files supplied, we started to start writing some codes to see what's going to happen. The professor gave us two code files including a file for loop and a file for printing out `hello world` string. So we did some experiment and we got this:

```

.text
.globl _start

min = 0                          /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 30                         /* loop exits when the index hits this number (loop condition is i<max) */

_start:
    	mov     x19, min
        mov     x0, 0           /* status -> 0 */

loop:
      	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
    	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      "Hello, world!!!\n"
        len=    . - msg
```

The next task is that we have to use loop in order to print a given string N times. So we're thinking about storing the value of 0 (the min value) into x19 and 0 into x0. Then, we added the file descriptor to x0, memory address of the message to x1, and the length of message to x2.

This is the final code:

```
.text
.globl _start

min = 0                          /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 31                         /* loop exits when the index hits this number (loop condition is i<max) */
ten = 10
_start:

        mov     x19, min
        mov     x17, ten
        mov     x0, 0           /* status -> 0 */

loop:
        mov     x0, 1           /* file descriptor: 1 is stdout */
        adr     x1, msg         /* message location (memory address) */
        mov     x2, len         /* message length (bytes) */

        mov     x18, x19        /*mov x19 into x18 */
        udiv    x9, x18, x17
        add     x13, x9, 0x30   /*convert quotient into char*/

        msub    x10, x9, x17, x18 /*get remainder*/
        add     x14, x10, 0x30  /* add value at x10 and 0x30, and store in x14 */
        adr     x15, msg        /* put address of msg into x15 */
        strb    w13, [x15, 8]   /* storing the byte that is at 14 into x15, 8 spaces over, which is 8 spaces over from the msg string */

        strb    w14, [x15, 9]   /* storing the byte that is at 14 into x15, 9 spaces over, which is 9 spaces over from the msg string */
        mov     x8, 64          /* write is syscall #64 */
        svc     0               /* invoke syscall */

        add     x19, x19, 1
        cmp     x19, max
        b.ne    loop
```

## Wrap up
The actual work took us a lot of time and effort as nobody is familiar with this before, so it means we have to learn everything from scratch. 

Thank you for reading.