DEV Community

Tecca Yu
Tecca Yu

Posted on

LAB4 - Continued

In the previous post, the code was able to loop and print from 0 to 9 onto the screen with both Aarch64 and x84_64.

In order to print numbers beyond that meaning two digit numbers, modifications to the code needs to be made.

Expected result:

Loop: 00
Loop: 01
Loop: 02
Loop: 03
Loop: 04
...
Loop: 30
etc.
Enter fullscreen mode Exit fullscreen mode

The strategy is to store both the quotient and remainder of the number when it is divided by 10. This allows to also display the number that goes beyond 10 when we display the quotient and remainder side by side onto the screen.

partial code in x84_64

loop:
        movq     $0, %rdx                        /* clearing reminder for division */
        movq     %r15, %rax                      /* set rax to be divide */
        movq     $10, %r10                       /* set divisor 10 */
        div      %r10                            /* perform division */
        movq     %rax, %r14                      /* store quotient to the register*/
        movq     %rdx, %r13                      /* store remainder to the register*/

        add      $0x30, %r14                     /* converting quotient to ASCII */
        add      $0x30, %r13                     /* converting remainder to ASCII */
        mov      %r13b, msg+8                    /* Extra byte in msg with remainder than quotient */
Enter fullscreen mode Exit fullscreen mode

The code above takes care of performing the division of the number by 10. Stores the quotient and remainder to the register, converting both of them into ASCII code and later to be set to the position of msg.
Complete Source Code in x84_64:

.text
.globl  _start


_start:

        movq     $0, %r15                        /* Loop counter */
        movq     $0x30, %r12                     /* value of 0 in Ascii */

loop:
        movq     $0, %rdx                        /* clearing reminder for division */
        movq     %r15, %rax                      /* set rax to be divide */
        movq     $10, %r10                       /* set divisor 10 */
        div      %r10                            /* perform division */
        movq     %rax, %r14                      /* store quotient to the register*/
        movq     %rdx, %r13                      /* store remainder to the register*/

        add      $0x30, %r14                     /* converting quotient to ascii */
        add      $0x30, %r13                     /* converting remainder to ascii */
        mov      %r13b, msg+8                    /* Modify 1 byte inmsg with remainder */

        cmp      %r12, %r14
        mov      %r14b, msg+7                    /* Modify 1 byte in msg with quotient */

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

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

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

.section .data

        msg:    .ascii   "Loop :   \n"
        len = . - msg
Enter fullscreen mode Exit fullscreen mode

Complete Source Code in Aarch64:

.text
.globl _start


_start:

        mov     x19, 0
        mov     x17, 10

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        
        udiv    x9, x18, x17
        add     x13, x9, 0x30
        msub    x10, x9, x17, x18   
        add     x14, x10, 0x30
        adr     x15, msg
        strb    w13, [x15, 7]

        strb    w14, [x15, 8]
        mov     x8, 64          /* write is syscall #64 */
        svc     0               /* invoke syscall */

        add     x19, x19, 1
        cmp     x19, 31
        b.ne    loop

.data

msg:    .ascii      "Loop : #\n"
len=    . - msg
Enter fullscreen mode Exit fullscreen mode

Result:
Image description

Conclusion:
Personally the biggest challenge I found in this lab was to figure out how to perform the division and store the values from the division into two registers and placing then into the msg.

Top comments (0)