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
Post a Comment