64-Bit Assembly Language Lab 3 part-3
Tags: assembly, loop
Published: 2024-05-27 22:58:08

Hiii!! Thank you for your patience, I truly appreciate it. If you have'nt already read my [last blog](https://dev.to/yuktimulani/64-bit-assembly-language-lab-3-part-2-f9p) go read it now!! so you get some context.
Lets get started before I get beaten up by my readers for keeping the walkthrough a suspense.

## Walk through for the loop program in aarch64 archietecture

1.Data Section (.data):

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

```

- msg is a string "Loop: #\n", where # is a placeholder for the loop counter.
- len is the length of the msg string, calculated as the difference between the current address and the address of msg.

2.Text Section (.text):

```
.text
.globl _start
min = 0
max = 30

_start:
     mov     x19, min

```

- .globl _start: Declares _start as a global symbol (entry point).
- min = 0 and max = 30: Constants for loop bounds.
- _start:: Label marking the entry point of the program.
- mov x19, min: Initializes x19 (loop index) to 0.

3.Loop and Message Preparation:

```
loop:
     add        x15, x19, 0x30
     adr        x14, msg+6
     mov        x12, 10
     udiv       x13, x19, x12
     add        x16, x13, 0x30
     cmp        x16, 0x30
     b.eq       ones
     strb       w16, [x14]

```

- add x15, x19, 0x30: Convert loop index (x19) to ASCII character.
- adr x14, msg+6: Address of the placeholder # in the msg string.
- mov x12, 10: Move 10 into x12 for division.
- udiv x13, x19, x12: Divide x19 by 10, quotient in x13.
- add x16, x13, 0x30: Convert quotient to ASCII.
- cmp x16, 0x30: Compare if the quotient is 0.
- b.eq ones: If the quotient is 0, branch to ones.
- strb w16, [x14]: Store the quotient character.

4.Handling Ones Place:

```
ones:
     adr        x14, msg+7
     msub       x13, x13, x12, x19
     add        x13, x13, 0x30
     strb       w13, [x14]

```

- adr x14, msg+7: Address of the next character after the placeholder #.
- msub x13, x13, x12, x19: Compute the remainder.
- add x13, x13, 0x30: Convert remainder to ASCII.
- strb w13, [x14]: Store the remainder character.

5. Print the Message:

```
     mov        X0, 1
     adr        x1, msg
     mov        x2, len
     mov        x8, 64
     svc        0

```

- mov X0, 1: Set stdout file descriptor.
- adr x1, msg: Address of the msg string.
- mov x2, len: Length of the msg string.
- mov x8, 64: Syscall number for write.
- svc 0: Make the syscall.

6.Increment and Check Loop:

```
     add     x19, x19, 1
     cmp     x19, max
     b.ne    loop
     mov     x0, 0
     mov     x8, 93
     svc     0

```

- add x19, x19, 1: Increment loop index.
- cmp x19, max: Compare loop index with max.
- b.ne loop: If loop index is not equal to max, repeat loop.
- mov x0, 0: Exit status code.
- mov x8, 93: Syscall number for exit.
- svc 0: Make the syscall to terminate the program.

Overall this program iterates from min (0) to max (30), converting the loop index to a string and printing it using a syscall. The program handles converting numbers to their ASCII representation and uses system calls to print the message and eventually exit the program. Each iteration prints "Loop: #\n" where # is the current loop index.

This could also be written in x86_64 archietecture. The code is as follows.

```
.text
.globl    _start
min = 0                         /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
max = 33
_start:
     mov     $min,%r15           /* loop index */
loop:
     mov     $0,%rdx
     mov     %r15,%rax
     mov     $10,%r12
     div     %r12
     mov     %rax,%r14
     add     $'0',%r14
     cmp     $'1',%r14
     je      loopOnes
     mov     %r14b,msg+6

loopOnes:
     mov     %rdx,%r14
     add     $'0',%r14
     mov     %r14b,msg+7

     movq    $len,%rdx
     movq    $msg,%rsi
     movq    $1,%rdi
     movq    $1,%rax
     syscall

     /* ... 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 */
     syscall
.section .data
msg:    .ascii  "Loop:  #\n"
len = . - msg

```
 

## The Output [I almost forgot]
The output for both the archietectures looks like this

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dw7ncsibbi9mg3c7ry3g.png)

So here it is the third part of the blog, but I dont like the number three. So, I'm excited to add one more part to my blog, the cherry on top to complete the series! and also to include some more experiments on the assembler.
Thank you for reading!

Untill then Happy Coding!!👋