好吧,我必须转换
# j = 0
# x = a[j+k]
# a[j+k] = a[j]
# repeat n-1 times
# j = (j+k) mod n
# m = (j+k) mod n
# y = a[m]
# a[m] = x
# x = y
# end repeat
到 MIPS 代码。到目前为止,我已经想出了这个,但它打印出不正确的输出。有什么帮助吗?
.data
.align 2
head1: .asciiz "\n\nThis program reads a list of integers into an array, and then"
head2: .asciiz "\nshifts the array to the right with wrap around."
head3: .asciiz "\nThe list is terminated by a negative integer."
prompt1: .asciiz "\nEnter the shift amount first: "
prompt2: .asciiz "\nEnter array numbers (negative to end)"
newline: .asciiz "\n"
.text
.globl main
main:
# print the prompt messages See appendix B of P&H or chapter 4 of Britton
li $v0, 4 # $v0 = print_string system call code
la $a0, head1 # $a0 = address of first prompt
syscall # print first prompt
li $v0, 4 # $v0 = print_string system call code
la $a0, head2 # $a0 = address of second prompt
syscall # print second prompt
li $v0, 4 # $v0 = print_string system call code
la $a0, head3 # $a0 = address of third prompt
syscall # print third prompt
# Main program - calls read, rearrange and print functions
li $v0, 4 # $v0 = print_string system call code
la $a0, prompt1 # $a0 = address of fourth prompt
syscall # print fourth prompt
li $v0, 5 # $v0 = read_int system call code
syscall # read an integer - n
move $a2, $v0 # $a2 = separation point for rearranging array
li $v0, 4 # $v0 = print_string system call code
la $a0, prompt2 # $a0 = address of fifth prompt
syscall # print fifth prompt
li $a0, 0x10000000 # $a0 = base address of array = 10000000 (hex)
jal reada # read numbers into array
move $a1, $v0 # $a1 = number of ints read - size of array
jal shift # shift the array to the right
jal printa # print numbers from array to screen
# Call system exit
li $v0, 10 # $v0 = exit system call code
syscall # halt program execution
# Algorithm for reading numbers into an array
reada: move $t0, $a0 # $t0 = base address of array
move $t1, $zero # $t1 = counter = 0
read: li $v0, 5 # $v0 = read_int system call code
syscall # read an integer - n
slt $t2, $v0, $zero # if n < 0 then stop reading
bne $t2, $zero, exit # exit procedure and return to caller
sw $v0, 0($t0) # a[i] = n
addi $t1, $t1, 1 # i = i + 1
addi $t0, $t0, 4 # $t0 = address of a[i + 1]
j read # go back up and read another integer
exit: move $v0, $t1 # return number of integers read into array
jr $ra # return to calling routine
# Algorithm for printing numbers from an array
printa: move $t0, $a0 # $t0 = base address of array
move $t1, $zero # $t1 = counter = 0
print: beq $t1, $a1, exitp # if (array index = array size), then exit
lw $t2, 0($t0) # $t2 = a[i]
li $v0, 4 # $v0 = print_string system call code
la $a0, newline # $a0 = address of newline character
syscall # print new line
li $v0, 1 # $v0 = print_int system call code
move $a0, $t2 # $a0 = a[i]
syscall # print a[i]
addi $t1, $t1, 1 # i = i + 1
addi $t0, $t0, 4 # $t0 = address of a[i + 1]
j print # go back up and print another integer
exitp: li $v0, 4 # $v0 = print_string system call code
la $a0, newline # $a0 = address of newline character
syscall # print new line
jr $ra
# Algorithm for rearranging array
# j = 0
# x = a[j+k]
# a[j+k] = a[j]
# repeat n-1 times
# j = (j+k) mod n
# m = (j+k) mod n
# y = a[m]
# a[m] = x
# x = y
# end repeat
# Register usage
# $a0 = base address of array
# $a1 = n, size of array
# $a2 = k, the shift amount
shift: li $t3, 0 #j = 0
lw $t3, 0($a0) #load the value of $a0 in to j
add $t3, $t3, $a2 # j = j+k
sw $t3, 4($a0) # store the new value of j in to $a0
repeat: beq $a1, $zero, end
sub $a1, $a1, 1 #n = n-1
add $t4, $t3, $a2 #j+k
div $t4, $a1 #divide (j+k) by n
mfhi $t5
move $t5, $t3 #j = (j+k) mod n
add $t4, $t5, $a2 #j+k
div $t4, $a1 #divide (j+k) by n
mfhi $t5 #move rem into t2
move $t5, $t3 #m = (j+k) mod n
sw $t3, 4($a0)
jr $ra
lw $t3, 0($a0)
b repeat
end: