AArch64 and x86_64 assembler code

 AArch64

 .text
 .globl _start
 min = 0                          /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
 max = 30                         /* loop exits when the index hits this number (loop condition is i<max) * _start:
     mov     x19, min
 loop:
     /* Convert loop counter to char */
     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]

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

     /* Print the message */
     mov        X0, 1
     adr        x1, msg
     mov        x2, len
     mov        x8, 64
     svc        0

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

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

The code begins by defining constants `min` and `max`, setting the stage for a loop that will iterate from 0 to 29. It then jumps into the `_start` function to kick off the execution.

Within the loop labeled `loop`, the magic unfolds. Each iteration, the loop counter (`x19`) undergoes a transformation into characters, eventually forming a sequence from '0' to '29'. Alongside this conversion, a message "Loop: #" is constructed, where '#' represents the current iteration count.

But there's a twist. The code also checks if the character is a '1', appending an additional character if it is.

After each iteration, the constructed message is printed, showcasing the progress of the loop. With each number incrementing by one, the loop advances until it reaches the predefined `max` value.

Once the loop completes its cycle, the program gracefully exits, leaving behind a trail of numbers and messages that were meticulously crafted through the assembly instructions.

In conclusion, this humble assembly code snippet serves as a window into the fascinating world of AArch64 programming. It's a reminder of the beauty that lies in the intricate dance of instructions and data, shaping the behavior of our digital devices.



x86_64

 _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


In this code, I've initialized constants `min` and `max`, setting the stage for a loop that counts from 1 to 30. The `_start` function marks the beginning of our journey.

Within the loop labeled `loop`, each iteration involves converting the loop counter to characters and storing them in memory. If the character is '0', an additional character is appended.

Once the loop completes its cycle, the message, showcasing the progress of the loop, is printed. With each number incrementing by one, the loop advances until it reaches the predefined `max` value.

Reflecting on this code, I'm struck by its elegance and efficiency. It's a testament to the power and versatility of x86_64 assembly language, where even simple tasks are executed with precision.

In conclusion, this humble assembly code snippet offers a glimpse into the fascinating realm of low-level programming. It's a reminder of the beauty that lies in the intricate dance of instructions and data, shaping the behavior of our digital systems.

As I continue to explore the depths of assembly language programming, I eagerly anticipate unraveling more mysteries and uncovering new insights along the way.


Optional Challenge (tables in AArch64)

 .text
 .globl _start
 min = 1                          /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
 max = 13                         /* loop exits when the index hits this number (loop condition is i<max) */
 table = 1
 _start:
     mov     x19, min
     mov     x20, table
 loop:
     /* Convert loop counter to char */
     add        x15, x19, 0x30
     adr        x14, msg
     mov        x12, 10
     udiv       x13, x19, x12
     add        x16, x13, 0x30
     cmp        x16, 0x30
     b.eq       ones
     strb       w16, [x14]

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

 tensTable:
     add        x15, x20, 0x30
     adr        x14, msg+5
     mov        x12, 10
     udiv       x13, x20, x12
     add        x16, x13, 0x30
     cmp        x16, 0x30
     b.eq       onesTable
     strb       w16, [x14]
 onesTable:
     adr        x14, msg+6
     msub       x13, x13, x12, x20
     add        x13, x13, 0x30
     strb       w13, [x14]

 hundredres:
     mul        x21, x19, x20
     adr        x14, msg+10
     mov        x12, 100
     udiv       x15, x21, x12
     add        x13, x15, 0x30
     cmp        x13, 0x30
     b.eq       tensres
     strb       w13, [x14]
 tensres:
     msub       x15, x15, x12, x21
     mul        x21, x19, x20
     adr        x14, msg+11
     mov        x12, 10
     udiv       x17, x15, x12
     add        x13, x17, 0x30
     cmp        x13, 0x30
     b.eq       onesres
     strb       w13, [x14]
 onesres:
     adr        x14, msg+12
     msub       x17, x17, x12, x15
     add        x17, x17, 0x30
     strb       w17, [x14]

     /* Print the message */
     mov        X0, 1
     adr        x1, msg
     mov        x2, len

     mov        x8, 64
     svc        0

     /* ... body of the loop ... do something useful here ... */
     add     x19, x19, 1
     cmp     x19, max
     b.ne    loop

     mov     x19, min
     mov     x13, ' '
     adr     x14, msg
     strb    w13, [x14]
     adr     x14, msg+10
     strb    w13, [x14]
     adr     x14, msg+11
     strb    w13, [x14]
     add     x20, x20, 1
     cmp     x20, max
     b.ne    loop

     mov     x0, 0           /* status -> 0 */
     mov     x8, 93          /* exit is syscall #93 */
     svc     0               /* invoke syscall */

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


In this code, I've set up a loop to calculate and print a series of results following a specific format. The code calculates the multiplication results of numbers from 1 to 12 with another fixed number (in this case, 1), and prints them in a formatted manner.

This code showcases the power and versatility of AArch64 assembly language, where complex operations can be executed with precision and efficiency.




Comments

Popular posts from this blog

Project stage 2

Project Stage 1 Inspection