-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
290 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,35 @@ | ||
#### 4.45 | ||
A. No, the code sequence given does not correctly describe the behavior of the instruction `pushq %rsp`. | ||
|
||
The pushq instruction is specifically designed to push the value of a register onto the stack, and it performs the necessary stack pointer adjustment automatically. When the source register is `%rsp`, the behavior of the `pushq %rsp` instruction is different from the general case. It does not decrement the stack pointer before storing the value of `%rsp` on the stack. | ||
|
||
B. | ||
``` | ||
movq REG -8(%rsp) | ||
subq $8, %rsp | ||
``` | ||
#### 4.46 | ||
A. No, the code sequence does not correctly describe the behavior of the instruction `popq %rsp`. | ||
|
||
The `popq` instruction is specifically designed to pop a value from the stack and store it in a register, and it performs the necessary stack pointer adjustment automatically. When the destination register is `%rsp`, the behavior of the `popq %rsp` instruction is different from the general case. It does not increment the stack pointer after copying the value from the stack to `%rsp`. | ||
|
||
B. | ||
``` | ||
addq $8, %rsp | ||
movq 8(%rsp), REG | ||
``` | ||
|
||
#### 4.47 | ||
See file `bubblesort.c` and `bubblesort.ys` | ||
|
||
#### 4.48 | ||
See file `bubblesort_nojump.ys` | ||
|
||
#### 4.49 | ||
See file `bubblesort_onlycmov.ys` | ||
|
||
#### 4.50 | ||
#### 4.51 | ||
#### 4.52 | ||
#### 4.53 | ||
#### 4.54 | ||
#### 4.55 | ||
#### 4.56 | ||
#### 4.57 | ||
#### 4.58 | ||
#### 4.59 | ||
See file `switchv.ys` | ||
|
||
#### 4.51 - 4.59 | ||
See the lab material |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* Bubble sort: Pointer version */ | ||
void bubble_p(long *data, long count) { | ||
long i, last; | ||
for (last = count - 1; last > 0; --last) { | ||
for (i = 0; i < last; ++i) { | ||
if (*(data + i + 1) < *(data + i)) { | ||
long t = *(data + i + 1); | ||
*(data + i + 1) = *(data + i); | ||
*(data + i) = t; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Y86-64 program to perform bubblesort | ||
|
||
# Function: bubble_p | ||
# Arguments: | ||
# %rdi: Pointer to the array | ||
# %rsi: Number of elements in the array | ||
bubble_p: | ||
irmovq $0, %r8 # Initialize outer loop counter | ||
|
||
outer_loop: | ||
irmovq $0, %r9 # Initialize inner loop counter | ||
irmovq -8(%rsi), %r10 # Initialize last | ||
|
||
inner_loop: | ||
addq $1, %r9 # Increment inner loop counter | ||
cmpq %r10, %r9 # Compare inner loop counter with last | ||
jg done_inner_loop # Exit inner loop if inner loop counter > last | ||
|
||
mrmovq (%rdi,%r9,8), %r11 # Load data[i+1] into %r11 | ||
mrmovq (%rdi,%r9), %r12 # Load data[i] into %r12 | ||
cmpq %r11, %r12 # Compare data[i+1] with data[i] | ||
jge next_iteration # Skip swapping if data[i+1] >= data[i] | ||
|
||
rrmovq %r11, %r13 # Move data[i+1] to %r13 | ||
rmmovq %r12, (%rdi,%r9,8) # Store data[i] into data[i+1] | ||
rmmovq %r13, (%rdi,%r9) # Store data[i+1] into data[i] | ||
|
||
next_iteration: | ||
jmp inner_loop # Jump to next iteration of inner loop | ||
|
||
done_inner_loop: | ||
addq $1, %r8 # Increment outer loop counter | ||
irmovq $8, %r14 # Initialize constant 8 | ||
subq %r14, %rsi # Decrement last by 1 | ||
|
||
cmpq $0, %r8 # Compare outer loop counter with 0 | ||
jg outer_loop # Jump to next iteration of outer loop if counter > 0 | ||
|
||
ret | ||
|
||
# Test code | ||
.pos 0 | ||
irmovq $arr, %rdi # Pass the array address as argument | ||
irmovq $5, %rsi # Pass the number of elements as argument | ||
call bubble_p # Call bubble_p function | ||
|
||
# Data | ||
.pos 0x100 | ||
arr: | ||
.quad 5, 4, 3, 2, 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Y86-64 program to perform bubblesort with no jumps and at most three conditional moves | ||
|
||
# Function: bubble_p | ||
# Arguments: | ||
# %rdi: Pointer to the array | ||
# %rsi: Number of elements in the array | ||
bubble_p: | ||
irmovq $0, %r8 # Initialize outer loop counter | ||
|
||
outer_loop: | ||
irmovq $0, %r9 # Initialize inner loop counter | ||
irmovq -8(%rsi), %r10 # Initialize last | ||
|
||
inner_loop: | ||
addq $1, %r9 # Increment inner loop counter | ||
cmpq %r10, %r9 # Compare inner loop counter with last | ||
jg done_inner_loop # Exit inner loop if inner loop counter > last | ||
|
||
mrmovq (%rdi,%r9,8), %r11 # Load data[i+1] into %r11 | ||
mrmovq (%rdi,%r9), %r12 # Load data[i] into %r12 | ||
cmpq %r11, %r12 # Compare data[i+1] with data[i] | ||
cmovl %r11, %r13 # Move data[i+1] to %r13 if less | ||
cmovl %r12, %r11 # Move data[i] to %r11 if less | ||
cmovl %r13, %r12 # Move data[i+1] to %r12 if less | ||
|
||
rmmovq %r11, (%rdi,%r9) # Store data[i] into data[i+1] | ||
rmmovq %r12, (%rdi,%r9,8) # Store data[i+1] into data[i] | ||
|
||
jmp inner_loop # Jump to next iteration of inner loop | ||
|
||
done_inner_loop: | ||
addq $1, %r8 # Increment outer loop counter | ||
irmovq $8, %r14 # Initialize constant 8 | ||
subq %r14, %rsi # Decrement last by 1 | ||
|
||
cmpq $0, %r8 # Compare outer loop counter with 0 | ||
jg outer_loop # Jump to next iteration of outer loop | ||
|
||
ret | ||
|
||
# Test code | ||
.pos 0 | ||
irmovq $arr, %rdi # Pass the array address as argument | ||
irmovq $5, %rsi # Pass the number of elements as argument | ||
call bubble_p # Call bubble_p function | ||
|
||
# Data | ||
.pos 0x100 | ||
arr: | ||
.quad 5, 4, 3, 2, 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Y86-64 program to perform bubblesort using no jumps and just one conditional move | ||
# In this modified version, the swapping of `data[i]` and `data[i+1]` is achieved | ||
# using three XOR operations, which effectively swaps the values in `%r13` and `%r14`. | ||
# This eliminates the need for jumps in the swapping logic. | ||
|
||
# Function: bubble_p | ||
# Arguments: | ||
# %rdi: Pointer to the array | ||
# %rsi: Number of elements in the array | ||
bubble_p: | ||
irmovq $0, %r8 # Initialize outer loop counter | ||
|
||
outer_loop: | ||
irmovq $0, %r9 # Initialize inner loop counter | ||
irmovq -8(%rsi), %r10 # Initialize last | ||
|
||
inner_loop: | ||
addq $1, %r9 # Increment inner loop counter | ||
cmpq %r10, %r9 # Compare inner loop counter with last | ||
jg done_inner_loop # Exit inner loop if inner loop counter > last | ||
|
||
mrmovq (%rdi,%r9,8), %r11 # Load data[i+1] into %r11 | ||
mrmovq (%rdi,%r9), %r12 # Load data[i] into %r12 | ||
cmpq %r11, %r12 # Compare data[i+1] with data[i] | ||
jge next_iteration # Skip swapping if data[i+1] >= data[i] | ||
|
||
xorq %r13, %r13 # Clear %r13 (temporary register) | ||
xorq %r14, %r14 # Clear %r14 (temporary register) | ||
|
||
# Swap data[i] and data[i+1] | ||
rrmovq %r12, %r13 # Move data[i] to %r13 | ||
rrmovq %r11, %r14 # Move data[i+1] to %r14 | ||
xorq %r12, %r13 # XOR swap: %r13 = %r13 XOR %r12 | ||
xorq %r11, %r14 # XOR swap: %r14 = %r14 XOR %r11 | ||
xorq %r12, %r13 # XOR swap: %r13 = %r13 XOR %r12 | ||
rmmovq %r13, (%rdi,%r9,8) # Store %r13 (data[i]) into data[i+1] | ||
rmmovq %r14, (%rdi,%r9) # Store %r14 (data[i+1]) into data[i] | ||
|
||
next_iteration: | ||
jmp inner_loop # Jump to next iteration of inner loop | ||
|
||
done_inner_loop: | ||
addq $1, %r8 # Increment outer loop counter | ||
irmovq $8, %r15 # Initialize constant 8 | ||
subq %r15, %rsi # Decrement last by 1 | ||
|
||
cmpq $0, %r8 # Compare outer loop counter with 0 | ||
jg outer_loop # Jump to next iteration of outer loop if counter > 0 | ||
|
||
ret | ||
|
||
# Test code | ||
.pos 0 | ||
irmovq $arr, %rdi # Pass the array address as argument | ||
irmovq $5, %rsi # Pass the number of elements as argument | ||
call bubble_p # Call bubble_p function | ||
|
||
# Data | ||
.pos 0x100 | ||
arr: | ||
.quad 5, 4, 3, | ||
|
||
2, 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# Y86-64 program to implement switchv using a jump table | ||
|
||
# Function: switchv | ||
# Arguments: | ||
# %rdi: idx - The value to switch on | ||
# Returns: | ||
# %rax: result - The result based on the switch cases | ||
switchv: | ||
irmovq $0x0, %rax # Initialize result to 0 | ||
|
||
irmovq $8, %rdx # Compute the offset for jump table indexing | ||
imulq %rdx, %rdi | ||
|
||
irmovq $jt, %rdx # Load jump table address into %rdx | ||
addq %rdi, %rdx # Add offset to jump table address | ||
|
||
mrmovq (%rdx), %rdx # Load address from jump table based on idx | ||
pushq %rdx # Push computed address onto the stack | ||
|
||
ret # Return, effectively jumping to the computed address | ||
|
||
# Jump table | ||
jt: | ||
.quad case_0 # Address of case 0 | ||
.quad default_case # Address of default case | ||
.quad case_2_5 # Address of case 2 and 5 | ||
.quad case_3 # Address of case 3 | ||
|
||
# Test code | ||
.pos 0 | ||
irmovq $CNT, %rcx # Counter for the loop | ||
irmovq $MINVAL, %rax # Initialize MINVAL | ||
|
||
loop: | ||
pushq %rcx # Push counter onto the stack | ||
|
||
irmovq $0, %rdi # Clear %rdi | ||
irmovq $0xaaa, %rax # Set result to 0xaaa | ||
cmpq $0, %rax # Compare result with 0 | ||
je common_case # Jump to common case if result is 0 | ||
|
||
irmovq $8, %rdx # Compute the offset for jump table indexing | ||
imulq %rdx, %rax # Multiply offset by result | ||
|
||
irmovq $jt, %rdx # Load jump table address into %rdx | ||
addq %rax, %rdx # Add offset to jump table address | ||
|
||
mrmovq (%rdx), %rdx # Load address from jump table based on result | ||
pushq %rdx # Push computed address onto the stack | ||
|
||
jmp handle_result # Jump to handle_result | ||
|
||
case_0: | ||
rmmovq %rax, (%rsp) # Store result on the stack | ||
irmovq $1, %rcx # Set counter to 1 | ||
jmp loop_end # Jump to loop_end | ||
|
||
case_2_5: | ||
rmmovq %rax, (%rsp) # Store result on the stack | ||
irmovq $2, %rcx # Set counter to 2 | ||
jmp loop_end # Jump to loop_end | ||
|
||
case_3: | ||
rmmovq %rax, (%rsp) # Store result on the stack | ||
irmovq $3, %rcx # Set counter to 3 | ||
jmp loop_end # Jump to loop_end | ||
|
||
default_case: | ||
rmmovq %rax, (%rsp) # Store result on the stack | ||
irmovq $4, %rcx # Set counter to 4 | ||
jmp loop_end # Jump to loop_end | ||
|
||
common_case: | ||
irmovq $0xbbb, %rax # Set result to 0xbbb | ||
|
||
handle_result: | ||
rmmovq %rax, (%rsp) # Store result on the stack | ||
irmovq $1, %rcx # Set counter to 1 | ||
|
||
loop_end: | ||
irmovq $0x8, %rdi # Set increment value to 8 | ||
addq %rdi, %rsp # Increment stack pointer | ||
|
||
popq %rdi # Pop the computed address into %rdi | ||
ret # Return, effectively jumping to the computed address |