Lab 4 - 64 bit Assembly Language Lab - Part 1

 I am writing lab 4 for my course SPO600. This lab is based on introduction to 64 bit Assembly language for aarch64 and x86_64.

This lab is Divided into 5 tasks. In these tasks, I have to work with assembly language for the both x86_64 and aarch64 platforms. To access these platforms, we have to connect with SSH servers to two servers provided by professor. First server is Israel server, which operates on aarch64 system, second server is Portugal server - that operates on x86_64 system.

Task 1. Build and run aarch64 programs.

First tasks is to build and run aarch64 programs. I connected to the Israel server and configured some setting for it. Then, I was provided with some examples to work with. To access these examples, I had to unpack a .tgz file, which was new to me. I researched on the web and found this link. Following command on linux can be used to unpack tar Tar Gnu Zip(tgz) files. 

tar zxvf fileNameHere.tgz


After unpacking the tar, I received very basic assembler files for printing "hello world!" on screen. I used following commands to build the file:

as      -g      -o hello.o              hello.s
ld              -o hello                hello.o

After running the file, I disassembled it to review the source code. I used the following command to disassemble:

objdump -d hello | less


Here is the screen shot of the disassembled source code:


Task 2. Simple loop with loop counter for aarch64

In this task, we have to create a loop from to 0 to 9, and print the word with each increment along with increment counter. We were given with sort of template for loop without the loop body. 


.text
.globl _start

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

_start:

    mov     x19, min

loop:

    /* ... body of the loop ... do something useful here ... */

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

First of all, I added the code to print the loop # in each increment in the body of the loop. Now my program was able to successfully print loop # 10 times. I used write syscall for doing so. In aarch64 value 64 is used to call write method. In the second step in order to add counter in the loop, I copied the value from r19 to a new register and added it with '0' to convert into ascii, then I moved that value to the location of # in the text. By doing this, I was able to print the loop increment with text in each iteration. Here is my code:


.text
.globl _start

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

_start:

        mov     x19, min

loop:

        /*Start of loop*/

        mov     x20, x19
        add     x20, x20, '0'
        adr     x21, msg + 5
        strb    w20, [x21]

        mov     x0, 1
        adr     x1, msg
        mov     x2, len

        mov     x8, 64
        svc     0

        /*End of loop*/

        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  "Loop #\n"
len=    . - msg

After building the above code and running the program, I received the following output:


Task 3. Simple loop with loop counter for x86_64

In this task, I have to write the same program but for x86_64 platform. This was little bit challenging for me, because I found aarch64 syntax more simpler and easier than x86_64. Similar to tasks 2 we were given with template to work on. 

.text
.globl    _start

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

_start:
    mov     $min,%r15           /* loop index */

loop:
    /* ... body of the loop ... do something useful here ... */

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

I followed similar procedure while writing the code for x86_64. Initially,  I printed loop for 10 times without printing loop counter. I tested it and it was successful in the first try. However, implementing loop counter was little bit complex. I was able to implement it, but when I was storing the count in the location #, instead of single byte it was storing qword which was overwriting \n and output was in the single line. Then I suffixed the command and registered with b to fix this problem. Here is my code for x86_60:


.text
.globl    _start

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

_start:
        mov     $min,%r15           /* loop index */

loop:
        /*Start*/

        movq    %r15, %r10
        addq    $'0', %r10
        movq    $msg + 5, %r11
        movb    %r10b, (%r11)

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

        /*End*/

        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

Here is the output for the above code:



This was great experience for me. I learned many things from writing this lab. I liked writing code for aarch64 more than x86_64, because it was more simpler and straightforward. Moreover, aarch64 has more registers which makes it more flexible than x86_64. I will cover the Task 4 and 5 in second part of the blog

Comments

Popular posts from this blog

Review of 2 Open Source Softwares

Final Implementation of SPO600 Project - Stage III

Testing for Stage II for Project