RE-POST March: Lab 3

This post would be about the experiments that I have done with assembler using x86-64 and aarch64 platforms.

Experiment on x86-64 and aarch64

In both the AArch64 and x86_64 machine:

ll /public/spo600-assemble-lab-examples.tgz

The extension .tgz file means that it is a tar file created with the tar archiving program and it has been compressed.

To expand the archive:
tar xvf /public/spo600-assemble-lab-examples.tgz

Afterward, I created the lab3 dictionary that has loop.s and Makefile files:
mkdir lab3
cd lab3
touch loop.s Makefile

The following links are references used to do this lab:

Optional Investigation

These steps were done in the previous post

Lab Tasks

Steps 1-3 were done in the previous post.

To extend the code from 00-30 and print each value as a 2-digit decimal number:

In 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) */
 _start:
     mov     x19, min
 loop:
     /* Divide loop counter by 10 to separate the digits */
     mov     x10, x19

     /* Copy loop counter to x10 for division */
     mov     x9, 10
     udiv    x0, x10, x9
     msub    x1, x0, x9, x10

     /* Convert tens digit to char */
     add     x0, x0, 0x30
     adr     x14,msg+6
     strb    w0,[x14]

     /* Convert loop counter to char for the ones digit */
     add     x1, x1, 0x30       /* add 48 to convert to char */
     adr     x14, msg+7
     strb    w1, [x14]

     /* Print the message */
     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 program */
     mov     x0, 0           /* status -> 0 */
     mov     x8, 93          /* exit is syscall #93 */
     svc     0               /* invoke syscall */

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


To remove the leading 0's:
 .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) */
 _start:
     mov     x19, min
 loop:
     /* Divide loop counter by 10 to separate the digits */
     mov     x10, x19

     /* Copy loop counter to x10 for division */
     mov     x9, 10
     udiv    x0, x10, x9
     msub    x1, x0, x9, x10

     /* For numbers < 10, check for divsion == 0 */
     cmp     x0, 0
     b.eq    skipDoubleDigit

     /* Convert tens digit to char */
     add     x0, x0, 0x30
     adr     x14,msg+6
     strb    w0,[x14]
     b       storeSingleDigit

skipDoubleDigit:
     mov     x0, 0x20           /* Space */
     adr     x14, msg+6
     strb    w0,[x14]

storeSingleDigit:
     /* Convert loop counter to char for the ones digit */
     add     x1, x1, 0x30       /* add 48 to convert to char */
     adr     x14, msg+7
     strb    w1, [x14]

     /* Print the message */
     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 program */
     mov     x0, 0           /* status -> 0 */
     mov     x8, 93          /* exit is syscall #93 */
     svc     0               /* invoke syscall */

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

In x86

 .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) */
 _start:
     mov     $min,%r15           /* loop index */
 loop:
     /* Convert loop counter to 2-digit */
     mov     %r15, %rax
     mov     $10, %rbx
     xor     %rdx, %rdx
     div     %rbx

     /* Convert the double digits to char */
     add     $'0', %al
     mov     %al, msg+6

     /* Convert single digit to char */
     add     $'0', %dl
     mov     %dl, msg+7

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

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

.section .data

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


To remove the leading 0's:

    
 .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) */
 _start:
     mov     $min,%r15           /* loop index */
 loop:
     /* Convert loop counter to 2-digit */
     mov     %r15, %rax
     mov     $10, %rbx
     xor     %rdx, %rdx
     div     %rbx

     /* Check if division=0 for double digit */
     cmp     $0, %al
     je      singleDigit

     /* Convert the double digits to char */
     add     $'0', %al
     mov     %al, msg+6
     jmp     storeSingleDigit

singleDigit:
     /* Update double digit to Space */
     mov     $' ', %al
     mov     %al, msg+6

storeSingleDigit:
     /* Convert single digit to char */
     add     $'0', %dl
     mov     %dl, msg+7

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

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

.section .data

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


At the end of this lab, I found working with these two servers quite enjoyable. I like how I can practice Linux commands on the terminal which I didn't really have a lot of chance to do since my first semester in ULI101. Even though it took me more time to write in assembler using the vi command since I had forgotten how to navigate around with only the keyboard. However, I found that the debugger tool in the assembler is very convenient and tells me exactly which line is the problem.

When working with the AArch64 machine and then switching to the x86 machine, I got a bit confused when I was writing the code, since in AArch64 you state the memory location first and then the value you want to store in it, while x86 is the opposite ways.

Learning 6502 first and then going to the more modern system, actually helped me a lot in understanding the instructions and how to write them properly in a bigger system.

Comments

Popular posts from this blog