MIPS 快速排序数组

Posted

技术标签:

【中文标题】MIPS 快速排序数组【英文标题】:MIPS quicksort an array 【发布时间】:2018-10-28 15:48:57 【问题描述】:

出于学习目的,我正在尝试将一段“C”代码转换为 MIPS 汇编语言。我编写了 MIPS 代码,但在某处我做错了,没有得到想要的输出。当我运行程序时,它显示的数字完全不同。请纠正我哪里做错了?

C 代码:

void swap(int array[], int a, int b) 
     int t = array[a];
     array[a] = array[b];
     array[b] = t;
 

int partition (int arr[], int low, int high) 
    int pivot = arr[high]; // pivot
    int i = (low - 1); // Index of smaller element
     for (int j = low; j <= high- 1; j++) 
         if (arr[j] <= pivot) 
            i++; // increment index of smaller element
            swap(arr, i, j);
            
      
    swap(arr, i + 1, high);
    return (i + 1);



void quickSort(int arr[], int low, int high) 
     if (low < high) 
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi - 1);
       quickSort(arr, pi + 1, high);
     
 

MIPS 写入:

.data # Defines variable section of an assembly routine.
array: .word 12,1,13,10,3,5,2,1 # Define a variable named array as a word (integer) array.

.text # Defines the start of the code section for the program .
.globl main
main:
la $t0, array # Moves the address of array into register $t0.
addi $a0, $t0, 0 # Set argument 1 to the array.
addi $a1, $zero, 0 # Set argument 2 to (low = 0)
addi $a2, $zero, 7 # Set argument 3 to (high = 7, last index in array)
jal quickSort # Call quick sort

li $v0, 10 # Terminate program run and
syscall # Exit

### My code start from here
quickSort: 
		addi $sp, $sp, -20 #Make room on stack for  5 registers 
		sw $ra, 16($sp)	#save return address on memory
		sw $a0, 12($sp)	#save a0
		sw $a1, 8($sp)	#save a1
		sw $a2, 4($sp)	#save a2
		sw $s0 , 0($sp)	#save $s0

		slt $t1, $a1, $a2 		#t1=1 --> low < high, otherwise 0
		beq $t1, $zero, Exit	#if low > high, branch to Exit 
		jal partition			#call  if low < high
		
		move $s0, $v0			#load partition output to s0
		addi $a2, $s0, -1		#a2 = pi - 1
		jal quickSort			#calling quickSort

		addi $a1, $s0, 1		#a1 = pi + 1
		lw $a2, 4($sp)			#loading original a2
		jal quickSort			#calling quickSort

Exit: 
		lw $s0, 0($sp)
		lw $a2, 4($sp)
		lw $a1, 8($sp)
		lw $a0, 12($sp)
		lw $ra, 16($sp)
		addi $sp, $sp, 20 
		jr $ra



 partition:
 		addi $sp, $sp, -24
 		sw $ra, 20($sp)
 		sw $s0, 16($sp)
 		sw $s1, 12($sp)
 		sw $s2, 8($sp)
 		sw $s3, 4($sp)
 		sw $s4, 0($sp)

 		sll $t1, $a2, 2		#t1 = 4 * high
 		add $t1, $a0, $t1	#t1 = *arr + t1
 		lw $s0, 0($t1)		#s0, pivot = arr[high]
 		addi $s1, $a1, -1	#i=low -1
 		add $s2, $a1, $zero	#j=low
 		add $s3, $a2, $zero	#s3=high

 		forloop:

 			addi $t2, $s3, -1		#t2 = high - 1
 			slt $t3, $t2, $s2		#t3=1 --> j> high - 1
 			bne $t3, $zero, Exit1	#if j>high -1 branch to Exit 1

 			sll $t4, $s2,2			#t4 = 4j
 			add $t4, $a0, $t4		#t4 = *arr + 4j
 			lw $s4, 0($t4)			#s4 = arr[j]

 			slt $t5, $s0, $s4		#t5=1 --> arr[j] > pivot
 			beq $t5, $zero, Exit2	#if arr[j] <= pivot, branch to Exit2
 			addi $s2, $s2, 1		#j++
 			j forloop				#jump to forloop

 			Exit2:
 				addi $s1, $s1, 1	#i++
 				move $a1, $s1		#a1 = i 
 				move $a2, $s2		#a2 = j 
 				jal swap 			#calling swap
 				addi $s2, $s2, 1	#j++
 				j forloop			#calling forloop

 		Exit1:	 
 				addi $s1, $s1, 1	#i=i+1
 				move $a1, $s1		#a1=i+1
 				move $a2, $s3		#a2=high
 				jal swap 			#calling swap
 				move $v0, $a1		#return i+1

 			lw $ra, 20($sp)
	 		lw $s0, 16($sp)
 			lw $s1, 12($sp)
 			lw $s2, 8($sp)
 			lw $s3, 4($sp)
 			lw $s4, 0($sp)
 			jr $ra

 swap:  
 		addi $sp, $sp, -8			# Make room for two elements
 		sw $ra, 4($sp)				# Save return address
 		sw $s5, 0($sp)				# Save s5 register

 		sll $t6, $a1, 2				#t6 = a*4
 		add $t6, $a0, $t6			#t6 = *a0 + 4a
 		lw $s5, 0($t6)				#t = array[a]

 		sll $t7, $a2, 2				#t7 = b*4
 		add $t7, $a0, $t7			#$t7 = *a0 + 4b
 		lw $t8, 0($t7)				#t8 = array[b]
 		sw $t8, 0($t6)				#array[a] = array[b]
 		sw $s5, 0($t7)				#array[b] = t 

 		lw $s5, 0($sp)
 		lw $ra, 4($sp)
 		addi $sp, $sp, 8
 		jr $ra	

【问题讨论】:

“当我运行程序时” - 这个。您不会编写 50 行 asm,然后运行它。您再添加 2-5 行,然后使用调试器单步执行每条指令,检查是否一切都按照预期进行,仅此而已。跨度> 你的 C 不是人类可读的。正确缩进。但更重要的是,展示您正在得到什么,以及预期的结果是什么,以使其成为minimal reproducible example。更好的是,使用 MARS 或 SPIM 内置的调试器来单步执行您的代码,并找出哪条指令没有按照您的希望执行。 (例如,哪个分支走错了路。)您至少评论了您的 asm,但它太多了,无法轻松手动阅读并验证所有逻辑。 【参考方案1】:

这是用于快速排序的 MIPS 程序。取自:https://github.com/bharathkarumudi/MIPS/blob/master/quicksort.asm

#------------------------------------#
# Authored by: Bharath Karumudi     #
# Purpose Quicksort in MIPS         #
#------------------------------------#

.data # Defines variable section of an assembly routine.
array: .word 12,15,10,5,7,3,2,1 # Define a variable named array as a word (integer) array.
# After your program has run, the integers in this array
# should be sorted.
.text # Defines the start of the code section for the program .
.globl main

main:
la $t0, array # Moves the address of array into register $t0.
addi $a0, $t0, 0 # Set argument 1 to the array.
addi $a1, $zero, 0 # Set argument 2 to (low = 0)
addi $a2, $zero, 7 # Set argument 3 to (high = 7, last index in array)
jal quicksort # Call quick sort
li $v0, 10 # Terminate program run and
syscall # Exit


swap:               #swap method

addi $sp, $sp, -12  # Make stack room for three

sw $a0, 0($sp)      # Store a0
sw $a1, 4($sp)      # Store a1
sw $a2, 8($sp)      # store a2

sll $t1, $a1, 2     #t1 = 4a
add $t1, $a0, $t1   #t1 = arr + 4a
lw $s3, 0($t1)      #s3  t = array[a]

sll $t2, $a2, 2     #t2 = 4b
add $t2, $a0, $t2   #t2 = arr + 4b
lw $s4, 0($t2)      #s4 = arr[b]

sw $s4, 0($t1)      #arr[a] = arr[b]
sw $s3, 0($t2)      #arr[b] = t 


addi $sp, $sp, 12   #Restoring the stack size
jr $ra          #jump back to the caller



partition:          #partition method

addi $sp, $sp, -16  #Make room for 5

sw $a0, 0($sp)      #store a0
sw $a1, 4($sp)      #store a1
sw $a2, 8($sp)      #store a2
sw $ra, 12($sp)     #store return address

move $s1, $a1       #s1 = low
move $s2, $a2       #s2 = high

sll $t1, $s2, 2     # t1 = 4*high
add $t1, $a0, $t1   # t1 = arr + 4*high
lw $t2, 0($t1)      # t2 = arr[high] //pivot

addi $t3, $s1, -1   #t3, i=low -1
move $t4, $s1       #t4, j=low
addi $t5, $s2, -1   #t5 = high - 1

forloop: 
    slt $t6, $t5, $t4   #t6=1 if j>high-1, t7=0 if j<=high-1
    bne $t6, $zero, endfor  #if t6=1 then branch to endfor

    sll $t1, $t4, 2     #t1 = j*4
    add $t1, $t1, $a0   #t1 = arr + 4j
    lw $t7, 0($t1)      #t7 = arr[j]

    slt $t8, $t2, $t7   #t8 = 1 if pivot < arr[j], 0 if arr[j]<=pivot
    bne $t8, $zero, endfif  #if t8=1 then branch to endfif
    addi $t3, $t3, 1    #i=i+1

    move $a1, $t3       #a1 = i
    move $a2, $t4       #a2 = j
    jal swap        #swap(arr, i, j)

    addi $t4, $t4, 1    #j++
    j forloop

    endfif:
    addi $t4, $t4, 1    #j++
    j forloop       #junp back to forloop

endfor:
    addi $a1, $t3, 1        #a1 = i+1
    move $a2, $s2           #a2 = high
    add $v0, $zero, $a1     #v0 = i+1 return (i + 1);
    jal swap            #swap(arr, i + 1, high);

    lw $ra, 12($sp)         #return address
    addi $sp, $sp, 16       #restore the stack
    jr $ra              #junp back to the caller

quicksort:              #quicksort method

addi $sp, $sp, -16      # Make room for 4

sw $a0, 0($sp)          # a0
sw $a1, 4($sp)          # low
sw $a2, 8($sp)          # high
sw $ra, 12($sp)         # return address

move $t0, $a2           #saving high in t0

slt $t1, $a1, $t0       # t1=1 if low < high, else 0
beq $t1, $zero, endif       # if low >= high, endif

jal partition           # call partition 
move $s0, $v0           # pivot, s0= v0

lw $a1, 4($sp)          #a1 = low
addi $a2, $s0, -1       #a2 = pi -1
jal quicksort           #call quicksort

addi $a1, $s0, 1        #a1 = pi + 1
lw $a2, 8($sp)          #a2 = high
jal quicksort           #call quicksort

 endif:

lw $a0, 0($sp)          #restore a0
lw $a1, 4($sp)          #restore a1
lw $a2, 8($sp)          #restore a2
lw $ra, 12($sp)         #restore return address
addi $sp, $sp, 16       #restore the stack
jr $ra              #return to caller

【讨论】:

这段代码对包含某些负元素的数组给出了错误的答案。

以上是关于MIPS 快速排序数组的主要内容,如果未能解决你的问题,请参考以下文章

java编程实现随机数组的快速排序

快速排序

排序算法入门之快速排序(java实现)

小橙书阅读指南——快速排序和三向切分快速排序

快速排序

算法_快速排序