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.
``````

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

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
``````

Complete Source Code in Aarch64:

``````.text
.globl _start

_start:

mov     x19, 0
mov     x17, 10

loop:
mov     x0, 1           /* file descriptor: 1 is stdout */
mov     x2, len         /* message length (bytes) */

mov     x18, x19
udiv    x9, x18, x17
msub    x10, x9, x17, x18
strb    w13, [x15, 7]

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

cmp     x19, 31
b.ne    loop

.data

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

Result:

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.