You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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. 长度≤1提前终止逻辑
    在Q_SORT标签后,通过SUB R7, R1, R8计算当前子列表的总字节长度,由于每个元素为4字节的DCD类型,当字节长度≤4时,说明元素个数≤1,直接跳转到SORTED标签终止递归,避免无效的排序操作。

  2. 寄存器出栈操作
    按照入栈的逆顺序(R7→R5→R4→R3→R2→R8→R1→R0)弹出所有保存的寄存器,确保每个寄存器恢复到调用前的状态,符合ARM调用规范,避免破坏调用者的寄存器上下文。

内容的提问来源于stack exchange,提问作者David Della Morte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 23:36:03