Motorola 68000汇编:双字向量单遍交换求和能否优化?
Motorola 68000 固定长度循环优化:数组交换与求和
任务
我正在练习Motorola 68000的固定长度循环。给定两个10字长的有符号数组A和B,需要完成以下操作:
- 原地交换每一对元素(A[i] ↔ B[i]);
- 构建第三个数组C,其中C[i] = A[i] + B[i](交换后求和结果不变)。
所有参数必须通过栈传递。
初始可运行代码(Easy68k)
ORG $8000 VectorA DC.W 2,2,1,0,4,4,2,5,-1,2 VectorB DC.W 2,3,1,2,-7,4,-3,-2,0,2 C DS.W 10 LEN EQU 10 ; array size START: MOVE.W #LEN,-(A7) ; push n (word) PEA.L C ; push &C PEA.L VectorB ; push &B PEA.L VectorA ; push &A BSR.S SwapAndSumN ADDA.L #14,A7 ; 3 longs (12) + 1 word (2) = 14 SIMHALT ; SwapAndSumN(&A,&B,&C,n) — one pass, branch-free counters ; 4(A7)=&A 8(A7)=&B 12(A7)=&C 16(A7)=n (word) SwapAndSumN: MOVE.W 16(A7),D7 ; D7 = n SUBQ.W #1,D7 ; DBRA wants n–1 MOVEA.L 4(A7),A0 ; A0 = A MOVEA.L 8(A7),A1 ; A1 = B MOVEA.L 12(A7),A2 ; A2 = C Loop: MOVE.W (A0),D0 ; D0 = A[i] MOVE.W (A1),D1 ; D1 = B[i] MOVE.W D1,(A0)+ ; B → A MOVE.W D0,(A1)+ ; old A → B ADD.W D1,D0 ; sum MOVE.W D0,(A2)+ ; C[i] DBRA D7,Loop RTS END START
技术疑问
交换两个字需要临时寄存器,我已对每个元素各读取一次。上述的两次加载/两次存储序列是否是Motorola 68000能实现的最优方案?是否存在经典技巧(如EXG、对齐数据上的MOVE.L、MOVEM等),能在保持字对齐且仅使用现有寄存器的前提下,减少循环的周期或字节数?
优化后的代码(Easy68k)
ORG $8000 ; ============================================================= ; 68000 — 成对交换A[i]↔B[i] **并** 存储C[i] = A[i]+B[i] ; 使用Peter Cordes的长字交换技巧: ; add.w / swap / swap / add.w / swap / move.l ; ▸ 每对元素仅一次MOVE.L存储 ; ▸ 无额外MOVE.W操作,周期开销与4次MOVE.W相当 ; 数组按字对齐,长度为偶数 ; ============================================================= VectorA DC.W 2,2,1,0,4,4,2,5,-1,2 VectorB DC.W 2,3,1,2,-7,4,-3,-2,0,2 C DS.W 10 LEN EQU 10 ; ---------- 主程序 ---------- START: MOVE.W #LEN,-(A7) ; 压入n(字) PEA.L C ; 压入&C PEA.L VectorB ; 压入&B PEA.L VectorA ; 压入&A BSR.S SwapSum_LongPairs ; 执行操作 ADDA.L #14,A7 ; 弹出3个长字+1个字 SIMHALT ; ------------------------------------------------------------ ; SwapSum_LongPairs(&A,&B,&C,n) ; 4(A7)=&A 8(A7)=&B 12(A7)=&C 16(A7)=n(字,偶数) ; 使用寄存器: A0,A1,A2 / D0,D1,D7 ; 内循环流程: 加载A/加载B | add.w | swap | swap | add.w | swap | 存储 ; ------------------------------------------------------------ SwapSum_LongPairs: MOVE.W 16(A7),D7 ; D7 = n LSR.W #1,D7 ; 转换为元素对数量 SUBQ.W #1,D7 ; DBRA需要计数-1 MOVEA.L 4(A7),A0 ; A0指向数组A MOVEA.L 8(A7),A1 ; A1指向数组B MOVEA.L 12(A7),A2 ; A2指向数组C PairLp: MOVE.L (A0),D0 ; D0 = A的高字|A的低字 MOVE.L (A1),D1 ; D1 = B的高字|B的低字 MOVE.L D1,(A0)+ ; 将B的内容写入A,并自增指针 MOVE.L D0,(A1)+ ; 将A的内容写入B,并自增指针 ADD.W D1,D0 ; 低字求和 → D0低字 SWAP D0 ; D0: 低字和 | A的高字 SWAP D1 ; D1: B的低字 | B的高字 ADD.W D1,D0 ; 低字运算: A高字 + B高字 → 高字和 SWAP D0 ; D0: 高字和 | 低字和(大端顺序) MOVE.L D0,(A2)+ ; 将一对和写入数组C,并自增指针 DBRA D7,PairLp RTS END START
优化后的内循环为加载-交换-加法-交换-加法-交换-存储,无冗余移动操作,仅一次DBRA分支,内存访问量最小。
内容的提问来源于stack exchange,提问作者Pato
相关产品推荐
相关产品推荐

