Spo600 Lab 4
Published: 2022-03-07 00:42:25

## Lab 04 is here
In this lab we were supposed to:
- Login into Portugal and Israel servers.

- Unpack a tarball, which for a windows user like me can be a new experience.
- Explore the files inside the spo600 folder and use the `makefiles` and `make` command to build the code.
- Use `objdump -d` to inspect what was inside the binary file.
- Modify the Hello World! In AArch64 and x82_64 to make it loop.
- Modify the loop to run until 30 iterations (which took hours for me)

I started by the AArch64 as described in the lab, the professors lecture gave us the bread and the butter for this lab, which without it probably it was going to be impossible for me.

---

## AArch64

Here is my final AArch64 code looping from 00 to 29:
 

![result first loop](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/raaz7c08vg93l0onokcf.png)


Aarch64 Final code:
```
.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     x15, 10 // for division
        mov     x19, min // value of the counter
        add     x18, x19, '0' //counter
        adr 	x17, msg+6
        adr     x20, msg+7
        
loop:
        cmp x19, x15

        b.lt inside //start from smallest decimals

        udiv x12, x19, x15 // divide x19/x15 and store in x12 // udiv r0,r1,r2     // unsigned - divide r1 by r2, places quotient into r0 - remainder is not calculated (use msub)
        add x14, x12, '0'
        strb w14,[x17]

inside:
		
        msub x10,x15,x12,x19 //msub r0,r1,r2,r3  // load r0 with r3-(r1*r2) (useful for calculating remainders)
        add x10, x10, '0'
        strb w10,[x20]

        //Printing msg

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


        // call syscall

        mov     x8, 64          /* write is syscall #64 */
        svc     0               /* invoke syscall */


        add x19, x19, 1 //counter +1
        cmp x19, max
        b.ne loop


        //return

        mov     x0, 0           /* status -> 0 */
        mov     x8, 93          /* exit is syscall #93 */
        svc     0               /* invoke syscall */

.data
msg:    .ascii      "Loop: #\n"
len=    . - msg

```

As mentioned by the professor in the lab requirements, we had to use `udiv` and calculate the reminder in order to get 2 decimal cases.
Problems I have encountered:
-	Assembly is hard, all these registers can get messy, so I started taking notes on what register means what. This way is easier for me to control how many I used and for what I have used them for.

-	The [cheat sheet]( https://wiki.cdot.senecacollege.ca/wiki/AArch64_Register_and_Instruction_Quick_Start) is essential, and even with it still confusing to understand sometimes how it works.


-	Infinite loops and characters, these two were my most common results when trying to make it work. My code was going over the ACII `:` many times and sometimes the loop never ended.

---

## x86_64

The x86_64 proved harder than the AArch64.
As the professor said, we need more steps to make the division work which makes the code longer and harder to make it work.
I could not make the code work, it compiles and run but there is no output printed.

```
.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     $min,%r15           /* loop index */
        mov     $10, %r14
	mov     $10, %r13
        mov     %r15,%r13 		/* move 15 to 13 */
        mov     %r15,%r14       /* move 15 to 14 */
      
        mov 	$10,%r8
        movq    $len,%rdx                       /* message length */


loop:

		mov     $0, %r11
    		mov     %r9, %r12

   	    	div     %r8    

		add     $'0',%12

		movb    %r14b,msg+6      /* Put r14 into msg+6 first #*/


inner: 

		add 	$'0', %11
		movb    %r13b,msg+7 

        
		
       		 movq    $msg,%rsi                       /* message location */
        	movq    $1,%rdi                         /* file descriptor stdout */
        movq    $1,%rax                         /* syscall sys_write */
        syscall


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



        movq    $0,%rdi                         /* exit status */
        movq    $60,%rax                        /* syscall sys_exit */
        syscall

.section .data

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

```

---

## Finally

It is hard. To learn assembly language is hard, and to learn two different systems at the same time makes it even harder.
Its clear that my preference is the AArch64, I think its easier for me and the registers are easier to remember.
Im pretty sure im close to make the x86-64 version of the loop to work, just need to figure out how to understand and work with the registers a little more.
I will certainly go back to it.

Thank you for reading.