Lab 3

 In this lab, I learned how to write a basic for loop and create if else conditions and I found a lot of fun. 

During a previous class, professor taught me how the syntaxes of 2 architectures: x86_64 and aarch64. He showed me how to create a basic program that prints out the iteration index 10 times. My responsibility is to update the program and let it runs 30 times.

At first I thought it was easy (in JavaScript it takes only 3 lines to do so) and then I realized that this was Assembly and I still have PTSD about the time I worked on lab 1 and 2. However, I think because I worked with 6502 before, this was not as difficult as I think. Or maybe because I didn't have to work with a screen, I don't really know.

Anyways, here is the code:

Aarch64:

 .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) */

 divider = 10

 _start:

        mov     x19, min

        mov     x20, divider

 loop:

     /*convert loop counter to char*/

        udiv    x15, x19, x20   /* divide x19 by x20, store the result in x15 */

        msub    x9, x15, x20, x19 /* Calculate x19-(x15*x20) to get the remainder and store it in x9 */

        adr     x14, msg+6      /*Store the location of tens character in x14*/

        adr     x10, msg+7      /*Store the location ones character in x10*/

        add     x9, x9, 0x30    /* add 48 to convert to char */

        strb    w9, [x10]       /*Update the value of in x10 with the value in w9*/

        cmp     x15, 0          /* Check if the value in tens is 0 */

        b.eq    changeToSpace           /* Jump to setup if that's the case */

        add     x15, x15, 0x30 /* add 48 to convert to char */

        cmp     x15, 0

        b.ne    updateTens      /*jump to another branch to update the tens*/

changeToSpace:

        mov     x15, 0x20       /*change 0 to space*/

updateTens:

        strb    w15, [x14]      /*Update the value of in x13 with the value in w15*/




setup:

        /* set up the 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 */


        /* Continue the loop */

        add     x19, x19, 1

        cmp     x19, max

        b.ne    loop


        /* exit the loop */

        mov     x0, 0           /* status -> 0 */

        mov     x8, 93          /* exit is syscall #93 */

        svc     0               /* invoke syscall */


.data

msg:    .ascii      "Loop: ##\n"

len=    . - msg



x86_64:

 .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) */
 divider = 10
 _start:
        mov     $min, %r15
        mov     $divider, %r12          /* assign divider to r12 */
 loop:
        /*set up rdx and rax*/
        mov     $0, %rdx                /* set rdx to be 0 */
        mov     %r15, %rax              /* load rax with the index value in r15 */

        div     %r12                    /* divide the counter by 10 */
        mov     %rax, %r10              /* assign the quotient to r10 */
        mov     %rdx, %r9               /* assign the remainder to r9 */



        add     $'0', %r9               /* convert to number */
        mov     %r9b, msg+7             /* assign r9 value to the ones */
        cmp     $0, %r10                /* compare r10 value with 0 */
        jne     addNumber               /* if not then add '0' to update ascii */
        mov     $' ', %r10              /* else change it to space */
        jmp     updateTens              /* jump to assignment */
addNumber:
        add     $'0', %r10              /* convert to number */
updateTens:
        mov     %r10b, msg+6            /* assign r10 value to the tens */

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

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

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

.section .data

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



Before we can run this code, we first need to compile it. To save us sometimes, we should create a script (a Makefile) that would run this for use when we call make. Here is the content of the file that my professor showed me:

Makefile:

loop:           loop.s
                as -g loop.s -o loop.o
                ld -g loop.o -o loop


After we run this Makefile, we should have an executable file called loop. When we call the file, here is the result I have in both programs:

Result:

Loop:  0
Loop:  1
Loop:  2
Loop:  3
Loop:  4
Loop:  5
Loop:  6
Loop:  7
Loop:  8
Loop:  9
Loop: 10
Loop: 11
Loop: 12
Loop: 13
Loop: 14
Loop: 15
Loop: 16
Loop: 17
Loop: 18
Loop: 19
Loop: 20
Loop: 21
Loop: 22
Loop: 23
Loop: 24
Loop: 25
Loop: 26
Loop: 27
Loop: 28
Loop: 29
Loop: 30

Lookback:

I found both architectures interesting, I like some syntaxes in both and hate some as well. For example, in aarch64, I don't like the fact that we don't have to ability to do branch without condition, I tried br label but it would requires me to assign the address of the label to another register to do so, which means I have to write another line, and I'm quite lazy. For x86_64 though, I'm not a big fan of their divide syntax. Since we have to share/use rax/rdx to access the quotient and remainder, I think that this could make someone who are new like make accidentally overwrite some existing values. I would have to transfer those values to some other register first, which means I would have to write another 2 lines if I have a bigger program.

Conclusion:

This lab is really fun, I find it interesting. Hopefully with this excitement, I can make some meaning contribution to the coming project. I really want to see how far I can go and how much I can contribute.

Comments

Popular posts from this blog

Project update 1.2

How to get multiple inputs from the emulator

Lab 2 - Letter guessing game