LAB 05 PART 2

 SPO600 Lab5 64-Bit Assembly Language

In this lab I am going to explore the assembler on the following platform

@x86 SEVER


PROVIDED CODE

CODE==>

.text
.globl _start

min = 0                          /* starting value for the loop index */
 .text
 .globl    _start
 min = 0                         /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
 max = 5                        /* loop exits when the index hits this number (loop condition is i<max) */
 _start:
     mov     $min,%r15           /* loop index */
 loop:
     /* ... body of the loop ... do something useful here ... */
     inc     %r15                /* increment the loop index */
     cmp     $max,%r15           /* see if we've hit the max */
     jne     loop                /* if not, then continue the loop */
     
     mov     $0,%rdi             /* set exit status to 0 */
     mov     $60,%rax            /* exit is syscall #60  */
     syscall                     /* invoke syscall */
STEP 1: Modify an x86_64 assembly loop
CODE==>

.text
.globl _start
min = 0                          /* starting value for the loop index */
max = 6                          /* loop exits when the index hits this number (loop condition is i < max) */

_start:
    mov     $min, %r15           /* Initialize loop counter */

loop:
    /* Write the string "loop\n" */
    mov     $1, %rdi             /* File descriptor 1 is stdout */
    lea     loop_msg(%rip), %rsi /* Load the address of the string "loop\n" */
    mov     $5, %rdx             /* Length of the string "loop\n" (5 bytes, including newline) */
    mov     $1, %rax             /* syscall number for sys_write (1) */
    syscall                      /* invoke syscall to print the string */

    inc     %r15                 /* Increment the loop counter */
    cmp     $max, %r15           /* Compare the loop counter to max */
    jne     loop                 /* If not equal, continue the loop */

    mov     $0, %rdi             /* Set exit status to 0 */
    mov     $60, %rax            /* syscall number for exit (60) */
    syscall                      /* invoke syscall */

.data
loop_msg:
    .asciz "loop\n"               /* The message string*/

OUTPUT==>




Step 2: Modify the message with the loop index values:
CODE==>

.text
.globl _start

min = 0                          /* starting value for the loop index */
max = 6                          /* loop exits when the index hits this number (loop condition is i < max) */

_start:
    mov     $min, %r15           /* Initialize loop counter */

loop:
    /* Write the string "Loop: " */
    mov     $1, %rax             /* syscall number for sys_write (1) */
    mov     $1, %rdi             /* File descriptor 1 is stdout */
    lea     loop_msg(%rip), %rsi /* Load the address of the string "Loop: " */
    mov     $6, %rdx             /* Length of the string "Loop: " (6 bytes) */
    syscall                      /* invoke syscall to print the string */

    /* Convert the loop index to ASCII and store it in int_str */
    add     $48, %r15            /* Convert integer to ASCII by adding '0' (ASCII value of '0' is 48) */
    mov     %r15b, int_str       /* Store the ASCII value of the loop index in int_str */
    sub     $48, %r15            /* Restore the loop index to its original value */

    /* Write the int_str (loop index + newline) */
    mov     $1, %rax             /* syscall number for sys_write (1) */
    mov     $1, %rdi             /* File descriptor 1 is stdout */
    lea     int_str(%rip), %rsi  /* Load the address of int_str */
    mov     $3, %rdx             /* Length of the string (1 byte for the digit + 2 bytes for " \n") */
    syscall                      /* invoke syscall to print the string */

    inc     %r15                 /* Increment the loop counter */
    cmp     $max, %r15           /* Compare the loop counter to max */
    jne     loop                 /* If not equal, continue the loop */

    mov     $60, %rax            /* syscall number for exit (60) */
    xor     %rdi, %rdi           /* Set exit status to 0 */
    syscall                      /* invoke syscall */

.data
loop_msg:   .asciz "Loop: "        /* String to print before the loop index */
int_str:    .ascii "0 \n"          /* Space to store the loop index and newline */

OUTPUT==>

Step 3:Extend the code to loop from 00-32, printing each value as a 2-digit decimal number.
CODE==>
.text
.globl _start

min = 0                          /* starting value for the loop index */
max = 33                         /* loop exits when the index hits this number (loop condition is i < max) */

_start:
    mov     $min, %r15           /* Initialize loop counter */

loop:
    /* Write the string "Loop: " */
    mov     $1, %rax             /* syscall number for sys_write (1) */
    mov     $1, %rdi             /* File descriptor 1 is stdout */
    lea     loop_msg(%rip), %rsi /* Load the address of the string "Loop: " */
    mov     $6, %rdx             /* Length of the string "Loop: " (6 bytes) */
    syscall                      /* invoke syscall to print the string */

    /* Convert the loop index to a 2-digit ASCII string */
    mov     %r15, %rax           /* Copy loop index to %rax */
    mov     $10, %rbx            /* Divisor for tens place */
    xor     %rdx, %rdx           /* Clear %rdx for division */
    div     %rbx                 /* Divide %rax by 10: quotient in %rax, remainder in %rdx */

    /* Convert tens digit to ASCII */
    add     $48, %al             /* Convert quotient (tens digit) to ASCII */
    mov     %al, int_str         /* Store tens digit in int_str */

    /* Convert ones digit to ASCII */
    add     $48, %dl             /* Convert remainder (ones digit) to ASCII */
    mov     %dl, int_str+1       /* Store ones digit in int_str+1 */

    /* Write the int_str (2-digit number + newline) */
    mov     $1, %rax             /* syscall number for sys_write (1) */
    mov     $1, %rdi             /* File descriptor 1 is stdout */
    lea     int_str(%rip), %rsi  /* Load the address of int_str */
    mov     $3, %rdx             /* Length of the string (2 bytes for digits + 1 byte for newline) */
    syscall                      /* invoke syscall to print the string */

    inc     %r15                 /* Increment the loop counter */
    cmp     $max, %r15           /* Compare the loop counter to max */
    jne     loop                 /* If not equal, continue the loop */

    mov     $60, %rax            /* syscall number for exit (60) */
    xor     %rdi, %rdi           /* Set exit status to 0 */
    syscall                      /* invoke syscall */

 .data
loop_msg:   .asciz "Loop: "     /* String to print before the loop index */
int_str:    .ascii "00\n"       /* Space to store the 2-digit number and newline */
OUTPUT==>

Step 4: Remove the leading 0
CODE==>
.text
.globl _start

min = 0                          /* starting value for the loop index */
max = 33                         /* loop exits when the index hits this number (loop condition is i < max) */

_start:
    mov     $min, %r15           /* Initialize loop counter */

loop:
    /* Write the string "Loop: " */
    mov     $1, %rax             /* syscall number for sys_write (1) */
    mov     $1, %rdi             /* File descriptor 1 is stdout */
    lea     loop_msg(%rip), %rsi /* Load the address of the string "Loop: " */
    mov     $6, %rdx             /* Length of the string "Loop: " (6 bytes) */
    syscall                      /* invoke syscall to print the string */

    /* Check if the number is less than 10 */
    cmp     $10, %r15            /* Compare loop index with 10 */
    jl      single_digit         /* If less than 10, handle as single digit */

    /* Handle double-digit numbers (>= 10) */
    mov     %r15, %rax           /* Copy loop index to %rax */
    mov     $10, %rbx            /* Divisor for tens place */
    xor     %rdx, %rdx           /* Clear %rdx for division */
    div     %rbx                 /* Divide %rax by 10: quotient in %rax, remainder in %rdx */

    /* Convert tens digit to ASCII */
    add     $48, %al             /* Convert quotient (tens digit) to ASCII */
    mov     %al, int_str         /* Store tens digit in int_str */

    /* Convert ones digit to ASCII */
    add     $48, %dl             /* Convert remainder (ones digit) to ASCII */
    mov     %dl, int_str+1       /* Store ones digit in int_str+1 */

    /* Write the int_str (2-digit number + newline) */
    mov     $1, %rax             /* syscall number for sys_write (1) */
    mov     $1, %rdi             /* File descriptor 1 is stdout */
    lea     int_str(%rip), %rsi  /* Load the address of int_str */
    mov     $3, %rdx             /* Length of the string (2 bytes for digits + 1 byte for newline) */
    syscall                      /* invoke syscall to print the string */

    jmp     next_iteration       /* Skip single-digit handling */

single_digit:
    /* Handle single-digit numbers (< 10) */
    mov     %r15, %rax           /* Copy loop index to %rax */
    add     $48, %al             /* Convert loop index to ASCII by adding '0' */
    mov     %al, int_str+1       /* Store the ASCII character in int_str+1 (skip leading zero) */

    /* Write the int_str (single-digit number + newline) */
    mov     $1, %rax             /* syscall number for sys_write (1) */
    mov     $1, %rdi             /* File descriptor 1 is stdout */
    lea     int_str+1(%rip), %rsi /* Load the address of int_str+1 (skip leading space) */
    mov     $2, %rdx             /* Length of the string (1 byte for digit + 1 byte for newline) */
    syscall                      /* invoke syscall to print the string */

next_iteration:
    inc     %r15                 /* Increment the loop counter */
    cmp     $max, %r15           /* Compare the loop counter to max */
    jne     loop                 /* If not equal, continue the loop */

    mov     $60, %rax            /* syscall number for exit (60) */
    xor     %rdi, %rdi           /* Set exit status to 0 */
    syscall                      /* invoke syscall */

.data
loop_msg:   .asciz "Loop: "     /* String to print before the loop index */
int_str:    .ascii "  \n"       /* Space to store the number and newline (2 digits + newline) */
OUTPUT==>


Step 5: Change output in hexadecimal (0-20) instead of decimal (0-32).
CODE==>
.text
.globl _start

min = 0                          /* starting value for the loop index */
max = 0x21                       /* loop exits when the index hits 0x21 (33 in decimal) */

_start:
    mov     $min, %r15           /* Initialize loop counter */

loop:
    /* Write the string "Loop: " */
    mov     $1, %rax             /* syscall number for sys_write (1) */
    mov     $1, %rdi             /* File descriptor 1 is stdout */
    lea     loop_msg(%rip), %rsi /* Load the address of the string "Loop: " */
    mov     $6, %rdx             /* Length of the string "Loop: " (6 bytes) */
    syscall                      /* invoke syscall to print the string */

    /* Convert the loop index to hexadecimal */
    mov     %r15, %rax           /* Copy loop index to %rax */
    mov     $16, %rbx            /* Divisor for hexadecimal conversion */
    xor     %rdx, %rdx           /* Clear %rdx for division */
    div     %rbx                 /* Divide %rax by 16: quotient in %rax, remainder in %rdx */

    /* Convert high digit to ASCII */
    cmp     $10, %al             /* Compare high digit with 10 */
    jl      high_digit_digit     /* If less than 10, handle as digit */
    add     $55, %al             /* Otherwise, convert to 'A'-'F' (55 = 'A' - 10) */
    jmp     store_high_digit

high_digit_digit:
    add     $48, %al             /* Convert to ASCII by adding '0' (48 = '0') */

store_high_digit:
    mov     %al, hex_str         /* Store high digit in hex_str */

    /* Convert low digit to ASCII */
    cmp     $10, %dl             /* Compare low digit with 10 */
    jl      low_digit_digit      /* If less than 10, handle as digit */
    add     $55, %dl             /* Otherwise, convert to 'A'-'F' (55 = 'A' - 10) */
    jmp     store_low_digit

low_digit_digit:
    add     $48, %dl             /* Convert to ASCII by adding '0' (48 = '0') */

store_low_digit:
    mov     %dl, hex_str+1       /* Store low digit in hex_str+1 */

    /* Determine the length of the hexadecimal string */
    cmp     $0, %al              /* Check if high digit is 0 */
    je      single_digit         /* If high digit is 0, print only the low digit */

    /* Write the hex_str (2-digit hexadecimal value + newline) */
    mov     $1, %rax             /* syscall number for sys_write (1) */
    mov     $1, %rdi             /* File descriptor 1 is stdout */
    lea     hex_str(%rip), %rsi  /* Load the address of hex_str */
    mov     $3, %rdx             /* Length of the string (2 bytes for digits + 1 byte for newline) */
    syscall                      /* invoke syscall to print the string */

    jmp     next_iteration       /* Skip single-digit handling */

single_digit:
    /* Write the hex_str (single-digit hexadecimal value + newline) */
    mov     $1, %rax             /* syscall number for sys_write (1) */
    mov     $1, %rdi             /* File descriptor 1 is stdout */
    lea     hex_str+1(%rip), %rsi /* Load the address of hex_str+1 (skip high digit) */
    mov     $2, %rdx             /* Length of the string (1 byte for digit + 1 byte for newline) */
    syscall                      /* invoke syscall to print the string */

next_iteration:
    inc     %r15                 /* Increment the loop counter */
    cmp     $max, %r15           /* Compare the loop counter to max */
    jne     loop                 /* If not equal, continue the loop */

    mov     $60, %rax            /* syscall number for exit (60) */
    xor     %rdi, %rdi           /* Set exit status to 0 */
    syscall                      /* invoke syscall */

.data
loop_msg:   .asciz "Loop: "     /* String to print before the loop index */
hex_str:    .ascii "  \n"       /* Space to store the hexadecimal value and newline *
OUTPUT==>

THE END








Comments

Popular posts from this blog

Project Stage 1: Create a GCC pass

LAB 03

Project Stage 2: Part 2( The End)