ARMv7架构Visual2中快速排序汇编代码实现问题求助
ARMv7递归快速排序汇编代码修正方案
核心待完成任务
- 在
QUICKSORT子程序末尾弹出开头保存的所有寄存器 - 实现当列表长度≤1时提前终止子程序
修正后完整代码
; INIZIO PROGRAMMA MOV R0, #LIST ; Carico l'indirizzo di memoria di LIST STR R0, [R13] MOV R0, #LEN ; Carico l'indirizzo di memoria di LEN LDR R0, [R0] ; Carico il valore dell'indirizzo di memoria STR R0, [R13, #-4]! BL QUICKSORT ; muovo il contenuto di PC in LR e salto a QUICKSORT END ; SOTTOPROGRAMMA "QUICKSORT" ; R0 = Registro che punta alla posizione assoluta del primo elemento della lista ; R1 = Registro che indica la lunghezza della lista alla destra del pivot (偏移量,字节) ; R8 = Registro che indica la lunghezza della lista alla sinistra del pivot (偏移量,字节) ; R2 = Registro che serve per scorrere gli elementi della lista ; R3 = Registro che indica la posizione relativa in cui andrà inserito il pivot una volta ordinata la lista ; R4 = Registro che contiene il valore del pivot ; R5 = Registro che contiene progressivamente i valori da confrontare con il pivot ; R7 = Registro d'appoggio QUICKSORT STR R0, [R13, #-4]! STR R1, [R13, #-4]! STR R8, [R13, #-4]! STR R2, [R13, #-4]! STR R3, [R13, #-4]! STR R4, [R13, #-4]! STR R5, [R13, #-4]! STR R7, [R13, #-4]! LDR R0, [R13, #32] ; Viene azzerato il contenuto dei registri che non vengono inizialmente sovrascritti MOV R1, #0 MOV R2, #0 MOV R3, #0 MOV R8, #0 ; Converto la lunghezza della lista come multiplo di 4 CONV ADD R1, R1, #4 SUB R0, R0, #1 CMP R0, #1 BGT CONV LDR R0, [R13, #36] Q_SORT STR LR, [R13, #-4]! ; --- 新增:列表长度≤1时提前终止 --- SUB R7, R1, R8 ; 计算当前子列表的字节长度 CMP R7, #4 ; 字节长度≤4 → 元素个数≤1 BLE SORTED ; 直接终止,无需排序 ; --- 新增结束 --- CMP R8, R1 BGE SORTED MOV R7, R1 LENGTH ADD R2, R2, #4 SUB R7, R7, #4 CMP R8, R7 BLT LENGTH ADD R3, R2, #4 LDR R4, [R0, R8] ; Ciclo sulla lista CYCLESRT LDR R5, [R0, R2] ; Carico in R5 il valore dell'array all'indirizzo R0+[R2] CMP R2, R8 ; Quando si è raggiunta la posizione del pivot si termina il ciclo e si passa in "SW_PIV" BLE SW_PIV CMP R5, R4 ; Se il valore contenuto in R5 > R4 salta in SWITCH BGT SWITCH ADD R2, R2, #-4 ; Si aggiorna lo spiazzamento B CYCLESRT ; Blocco in cui si effettua lo scambio di due valori SWITCH SUB R3, R3, #4 ; Si aggiorna la posizione del pivot al valore precedente ; Blocco in cui viene effettuato lo scambio dei due valori LDR R7, [R0, R3] ; Si inserisce il valore che si trova all'indirizzo R0+[R3] in R7 STR R5, [R0, R3] ; Si inserisce il valore di R5 all'indirizzo R0+[R3] STR R7, [R0, R2] ; Si inserisce il valore di R7 all'indirizzo R0+[R2] SUB R2, R2, #4 ; Si aggiorna lo spiazzamento B CYCLESRT ; Blocco in cui ci si entra una volta aver ordinato tutta la lista tranne che il pivot. Viene switchato il pivot con il primo elemento ; minore o uguale in modo tale che il pivot prenda la sua posizione finale all'interno dell'array. SW_PIV SUB R3, R3, #4 LDR R7, [R0, R3] STR R4, [R0, R3] STR R7, [R0, R8] STR R3, [R13, #-4]! STR R1, [R13, #-4]! LEFT SUB R1, R3, #4 BL Q_SORT RIGHT LDR R1, [R13], #4 LDR R3, [R13], #4 ADD R2, R3, #4 MOV R8, R2 BL Q_SORT SORTED LDR PC, [R13], #4 ; --- 新增:弹出开头保存的所有寄存器 --- LDR R7, [R13], #4 LDR R5, [R13], #4 LDR R4, [R13], #4 LDR R3, [R13], #4 LDR R2, [R13], #4 LDR R8, [R13], #4 LDR R1, [R13], #4 LDR R0, [R13], #4 ; --- 新增结束 --- ; AREA DATI LIST DCD 4, -23, 3, 4, 12, 54 LEN DCD 6
关键修正说明
长度≤1提前终止逻辑
在Q_SORT标签后,通过SUB R7, R1, R8计算当前子列表的总字节长度,由于每个元素为4字节的DCD类型,当字节长度≤4时,说明元素个数≤1,直接跳转到SORTED标签终止递归,避免无效的排序操作。寄存器出栈操作
按照入栈的逆顺序(R7→R5→R4→R3→R2→R8→R1→R0)弹出所有保存的寄存器,确保每个寄存器恢复到调用前的状态,符合ARM调用规范,避免破坏调用者的寄存器上下文。
内容的提问来源于stack exchange,提问作者David Della Morte
相关产品推荐
相关产品推荐

