Skip to content

Commit

Permalink
done with homework04
Browse files Browse the repository at this point in the history
  • Loading branch information
lemorage committed Jul 4, 2023
1 parent 1d241f5 commit b36bb35
Show file tree
Hide file tree
Showing 6 changed files with 290 additions and 9 deletions.
38 changes: 29 additions & 9 deletions hw04/README.md
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
13 changes: 13 additions & 0 deletions hw04/bubblesort.c
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;
}
}
}
}
50 changes: 50 additions & 0 deletions hw04/bubblesort.ys
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
50 changes: 50 additions & 0 deletions hw04/bubblesort_nojump.ys
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
63 changes: 63 additions & 0 deletions hw04/bubblesort_onlycmov.ys
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
85 changes: 85 additions & 0 deletions hw04/switchv.ys
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

0 comments on commit b36bb35

Please sign in to comment.