LAB5
INTRODUCTION
This lab is about exploring assembly language on x86_64 and AArch64 architectures. We will start by running "Hello World" programs written in C and assembly, then use tools like objdump and gcc -S to examine machine code and compiler-generated assembly. The main task is to modify an AArch64 assembly loop to print numbers, first from 0 to 5, then extending it to 00-32 with two-digit formatting, and finally converting it to hexadecimal. After that, we will repeat similar steps for x86_64 assembly. The goal is to understand how low-level programming works, compare different architectures, and gain experience with assembly instructions, system calls, and debugging.
Extracting the Archive
First, we need to unpack the tar archive on x86_64 and AArch64 using the command:tar xvf /public/spo600-assembler-lab-examples.tgz
(AArch64)
Building and Running the C Program on x86_64 and AArch64
Building and running the C program using make command.
Then we use the objdump -d hello | less command to disassemble the compiled binaries and inspect their machine code(<main> section).
(AArch64)
And Compare the disassembled output from previous step with the assembly language output of the C compiler, produced by running gcc with the -S option.
Compile the C program into assembly language using gcc -S hello.c command:
Modify an AArch64 assembly loop
Provided Code:
.text
.globl _start
min = 0 /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
max = 6 /* loop exits when the index hits this number (loop condition is i<max) */
_start:
mov x19, min
loop:
/* ... body of the loop ... do something useful here ... */
add x19, x19, 1 /* increment the loop counter */
cmp x19, max /* see if we've hit the max */
b.ne loop /* if not, then continue the loop */
mov x0, 0 /* set exit status to 0 */
mov x8, 93 /* exit is syscall #93 */
svc 0 /* invoke syscall */
Step 1: Modify the code above to print "loop" 6 times:
Modified code:
.text
.globl _start
min = 0 /* starting value for the loop index; **note that this is a symbol (constant)**, not>
max = 6 /* loop exits when the index hits this number (loop condition is i<max) */
_start:
mov x19, min
loop:
mov x0, 1 /* File descriptor 1 is stdout */
adr x1, loop_msg /* Load the address of the string "loop" */
mov x2, 5 /* Length of the string "loop" */
mov x8, 64 /* syscall number for write */
svc 0 /* invoke syscall to print the string */
add x19, x19, 1 /* increment the loop counter */
cmp x19, max /* see if we've hit the max */
b.ne loop /* if not, then continue the loop */
mov x0, 0 /* set exit status to 0 */
mov x8, 93 /* exit is syscall #93 */
svc 0 /* invoke syscall */
.data
loop_msg:
.asciz "Loop\n" /* String */
Output:
Step 2: Modify the message with the loop index values:
Modified code:
.text
.globl _start
min = 0 /* starting value for the loop index */
max = 6 /* loop exits when the index hits this number */
_start:
mov x19, min /* initialize loop counter */
loop:
mov x0, 1 /* File descriptor 1 is stdout */
adr x1, loop_msg /* Load the address of the string "Loop: " */
mov x2, 6 /* Length of the string "Loop: " */
mov x8, 64 /* syscall number for write */
svc 0 /* invoke syscall to print the string */
mov w20, w19 /* Move the loop index to w20 */
add w20, w20, 48 /* Convert integer to ASCII by adding '0' */
mov x0, 1 /* File descriptor 1 is stdout */
adr x1, int_str /* Address of the string "0 \n" */
mov x2, 4 /* Length of the string (since it's "0 \n", length is 4) */
mov x8, 64 /* syscall number for write */
strb w20, [x1] /* Store the ASCII character in the string */
svc 0 /* invoke syscall to print the string */
add x19, x19, 1 /* increment the loop counter */
cmp x19, max /* see if we've hit the max */
b.ne loop /* if not, then continue the loop */
mov x0, 0 /* set exit status to 0 */
mov x8, 93 /* exit is syscall #93 */
svc 0 /* invoke syscall */
.data
loop_msg:
.asciz "Loop: " /* String */
int_str:
.ascii "0 \n" /* String "0 \n" that will be printed for each loop iteration */
Output:
Step 3:Extend the AArch64 code to loop from 00-32, printing each value as a 2-digit decimal number.
Modified code:
.text
.globl _start
min = 0 /* starting value for the loop index */
max = 32 /* loop exits when the index hits 32 */
_start:
mov x19, min /* initialize loop counter */
loop:
mov x0, 1 /* File descriptor 1 is stdout */
adr x1, loop_msg /* Load the address of the string "Loop: " */
mov x2, 6 /* Length of the string "Loop: " */
mov x8, 64 /* syscall number for write */
svc 0 /* invoke syscall to print the string */
/* Divide the index by 10 to get the tens place */
mov w20, w19 /* Copy loop counter to w20 */
mov w24, 10 /* Load the value 10 into w24 */
sdiv w21, w20, w24 /* Divide by 10: w21 gets the tens place */
mov w22, w19 /* Copy loop counter again to w22 */
mul w23, w21, w24 /* Multiply quotient by 10 to get the base for subtraction */
sub w23, w22, w23 /* Subtract the product from the original number to get the ones place */
/* Convert tens place to ASCII */
add w21, w21, '0' /* Convert to ASCII by adding '0' */
adr x2, int_str /* Address for tens place */
strb w21, [x2] /* Store the tens digit */
/* Convert ones place to ASCII */
add w23, w23, '0' /* Convert to ASCII by adding '0' */
adr x2, int_str + 1 /* Address for ones place */
strb w23, [x2] /* Store the ones digit */
/* Print the result */
mov x0, 1 /* File descriptor 1 is stdout */
adr x1, int_str /* Address of the string with 2 digits */
mov x2, 3 /* Length of the string (2 digits + newline) */
mov x8, 64 /* syscall number for write */
svc 0 /* invoke syscall to print the string */
add x19, x19, 1 /* increment the loop counter */
cmp x19, max /* see if we've hit the max */
b.le loop /* if not, then continue the loop */
mov x0, 0 /* set exit status to 0 */
mov x8, 93 /* exit is syscall #93 */
svc 0 /* invoke syscall */
.data
loop_msg:
.asciz "Loop: " /* String */
int_str:
.ascii "00\n" /* Space for storing the 2-digit string */
Output:
Modified Code:
.text
.globl _start
min = 1 /* starting value for the loop index */
max = 32 /* loop exits when the index hits 32 */
_start:
mov x19, min /* initialize loop counter */
loop:
mov x0, 1 /* File descriptor 1 is stdout */
adr x1, loop_msg /* Load the address of the string "Loop: " */
mov x2, 6 /* Length of the string "Loop: " */
mov x8, 64 /* syscall number for write */
svc 0 /* invoke syscall to print the string */
/* Check if the number is less than 10 */
cmp x19, 10 /* compare loop counter with 10 */
b.lt single_digit /* if less than 10, handle as single digit */
/* Handle double-digit numbers (>= 10) */
mov w20, w19 /* Copy loop counter to w20 */
mov w24, 10 /* Load the value 10 into w24 */
sdiv w21, w20, w24 /* Divide by 10: w21 gets the tens place */
mul w23, w21, w24 /* Multiply quotient by 10 to get the base for subtraction */
sub w23, w20, w23 /* Subtract the product from the original number to get the ones place */
/* Convert tens place to ASCII */
add w21, w21, '0' /* Convert to ASCII by adding '0' */
adr x2, int_str /* Address for tens place */
strb w21, [x2] /* Store the tens digit */
/* Convert ones place to ASCII */
add w23, w23, '0' /* Convert to ASCII by adding '0' */
adr x2, int_str + 1 /* Address for ones place */
strb w23, [x2] /* Store the ones digit */
/* Add newline character */
mov w25, '\n' /* Load newline character */
adr x2, int_str + 2 /* Address for newline */
strb w25, [x2] /* Store the newline character */
/* Print the result */
mov x0, 1 /* File descriptor 1 is stdout */
adr x1, int_str /* Address of the string with 2 digits and newline */
mov x2, 3 /* Length of the string (2 digits + newline) */
mov x8, 64 /* syscall number for write */
svc 0 /* invoke syscall to print the string */
b next_iteration /* skip single-digit handling */
single_digit:
/* Handle single-digit numbers (< 10) */
add w20, w19, '0' /* Convert the loop counter to ASCII by adding '0' */
adr x2, int_str /* Address for the single-digit string */
strb w20, [x2] /* Store the ASCII character */
/* Add newline character */
mov w25, '\n' /* Load newline character */
adr x2, int_str + 1 /* Address for newline */
strb w25, [x2] /* Store the newline character */
/* Print the result */
mov x0, 1 /* File descriptor 1 is stdout */
adr x1, int_str /* Address of the string with the single digit and newline */
mov x2, 2 /* Length of the string (1 digit + newline) */
mov x8, 64 /* syscall number for write */
svc 0 /* invoke syscall to print the string */
next_iteration:
add x19, x19, 1 /* increment the loop counter */
cmp x19, max /* see if we've hit the max */
b.le loop /* if not, then continue the loop */
mov x0, 0 /* set exit status to 0 */
mov x8, 93 /* exit is syscall #93 */
svc 0 /* invoke syscall */
.data
loop_msg:
.asciz "Loop: " /* String to print */
int_str:
.ascii " \n" /* Space for storing the 2-digit string and newline */
Output:
Step 5: Change output in hexadecimal (0-20) instead of decimal (0-32).
Modified Code:
.text
.globl _start
min = 1 /* starting value for the loop index */
max = 0x20 /* loop exits when the index hits 0x20 (32 in decimal) */
_start:
mov x19, min /* initialize loop counter */
loop:
mov x0, 1 /* File descriptor 1 is stdout */
adr x1, loop_msg /* Load the address of the string "Loop: " */
mov x2, 6 /* Length of the string "Loop: " */
mov x8, 64 /* syscall number for write */
svc 0 /* invoke syscall to print the string */
/* Convert the loop counter to hexadecimal */
mov w20, w19 /* Copy loop counter to w20 */
mov w24, 16 /* Load the value 16 into w24 (base for hexadecimal) */
udiv w21, w20, w24 /* Divide by 16: w21 gets the high digit */
msub w23, w21, w24, w20 /* Get the low digit: w23 = w20 - (w21 * 16) */
/* Convert high digit to ASCII */
cmp w21, 9 /* Compare high digit with 9 */
b.le high_digit_digit /* If less than or equal to 9, handle as digit */
add w21, w21, 'A' - 10 /* Otherwise, convert to 'A'-'F' */
b store_high_digit
high_digit_digit:
add w21, w21, '0' /* Convert to ASCII by adding '0' */
store_high_digit:
adr x2, hex_str /* Address for high digit */
strb w21, [x2] /* Store the high digit */
/* Convert low digit to ASCII */
cmp w23, 9 /* Compare low digit with 9 */
b.le low_digit_digit /* If less than or equal to 9, handle as digit */
add w23, w23, 'A' - 10 /* Otherwise, convert to 'A'-'F' */
b store_low_digit
low_digit_digit:
add w23, w23, '0' /* Convert to ASCII by adding '0' */
store_low_digit:
adr x2, hex_str + 1 /* Address for low digit */
strb w23, [x2] /* Store the low digit */
/* Add newline character */
mov w25, '\n' /* Load newline character */
adr x2, hex_str + 2 /* Address for newline */
strb w25, [x2] /* Store the newline character */
/* Print the result */
mov x0, 1 /* File descriptor 1 is stdout */
adr x1, hex_str /* Address of the string with 2 hexadecimal digits and newline */
mov x2, 3 /* Length of the string (2 digits + newline) */
mov x8, 64 /* syscall number for write */
svc 0 /* invoke syscall to print the string */
next_iteration:
add x19, x19, 1 /* increment the loop counter */
cmp x19, max /* see if we've hit the max */
b.le loop /* if not, then continue the loop */
mov x0, 0 /* set exit status to 0 */
mov x8, 93 /* exit is syscall #93 */
svc 0 /* invoke syscall */
.data
loop_msg:
.asciz "Loop: " /* String to print */
hex_str:
.ascii " \n" /* Space for storing the 2-digit hexadecimal string and newline */
Output:
Modify an x86_64 assembly loop
Provided 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 the code above to print "loop" 6 times:
Modified 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:
Modified 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.
Modified 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
Modified 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).
Modified 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:
Challenge:
Code:
.global _start
_start:
// Load the address of the row_table into x0
ldr x0, =row_table
mov x4, 0 // Initialize counter
print_loop:
// Load the address of the current row into x1
ldr x1, [x0, x4, lsl 3] // x4 is the index, lsl 3 to multiply by 8 (size of pointer)
cbz x1, exit // If x1 is zero (end of table), exit
// Call the print_string subroutine
mov x0, x1 // Move the string address to x0 (expected by print_string)
bl print_string
// Increment the counter and repeat
add x4, x4, 1
b print_loop
exit:
mov x0, 0 // Exit status 0
mov x8, 93 // syscall: exit
svc 0 // Make system call
// Subroutine to print a string
print_string:
mov x1, x0 // Address of string (x0 is the input)
mov x2, 0 // Initialize length counter
1:
ldrb w3, [x1, x2] // Load byte from string
cbz w3, 2f // If null terminator, exit loop
add x2, x2, 1 // Increment length counter
b 1b // Repeat loop
2:
mov x0, 1 // File descriptor 1 (stdout)
mov x8, 64 // syscall: write
svc 0 // Make system call
ret // Return from subroutine
.data
row1: .asciz " 1 x 1 = 1\n"
row2: .asciz " 2 x 1 = 2\n"
row3: .asciz " 3 x 1 = 3\n"
row4: .asciz " 4 x 1 = 4\n"
row5: .asciz " 5 x 1 = 5\n"
row6: .asciz " 6 x 1 = 6\n"
row7: .asciz " 7 x 1 = 7\n"
row8: .asciz " 8 x 1 = 8\n"
row9: .asciz " 9 x 1 = 9\n"
row10: .asciz " 10 x 1 = 10\n"
row11: .asciz " 11 x 1 = 11\n"
row12: .asciz " 12 x 1 = 12\n"
spacer: .asciz "-------------\n"
// Table of row addresses
row_table:
.quad row1, row2, row3, row4, row5, row6, row7, row8, row9, row10, row11, row12, 0
Output:
Explain:
Comments
Post a Comment