データ分離して逆アセンブルした状態で、プログラムから置換をするという試行. プログラム全体の流れをみることはないので正常動作としては100%同じ動作になることを優先.
clr.l dn
moveq #0,dn
move.l #imm,dn
imm は -0x80 から 0x7f に限る.
moveq #imm,dn
(add|sub)[ai]?.[bwl] #imm,ea
imm は 1 から 8 に限る. moveq と違って ea の制限が少ない.
(add|sub)q.[bwl] #imm,ea
(jsr|jmp|lea) abs(,an)?
jsr,jmp,lea で例が多いので ea 次第では他の命令で利用可能.
ea が -0x8000から0x7fffの場合 (jsr|jmp|lea) abs.w(,an)? ea が pc+2 との距離が -0x8000から0x7fffの場合 (jsr|jmp|lea) (pc,ea),an
jump table 共通次項
下記の命令を想定.
lea table.l,an move.w ram,dn lsl.w #2,dn movea.l (an,dn),an jmp (an) table: dc.l pointer0,pointer1,...
jump table が近い場合
- jmp/jsr の pc+2 との距離が table が -0x80 から 0x7e の場合. jsr は近くにないことがある.
- addressing (offset,pc,ix) を使うため offset が狭い.
pointer と bra.s の PC + 2 との距離が -0x80 から 0x7e で収まる場合 move.w ram,dn lsl.w #1,dn jmp (table,pc,dn.w) table: bra.s pointer0 bra.s pointer1
命令数は減るが実行数は変わらないと思う.
pointer の値が -0x8000 から 0x7ffe で収まる場合 move.w ram,dn lsl.w #1,dn movea.w (table,pc,dn.w),an jmp (an) table: dc.w pointer0 dc.w pointer1
pointer と table の距離が -0x8000 から 0x7ffe で収まる場合 move.w ram,dn lsl.w #1,dn movea.w (table,pc,dn.w),an jmp (table,pc,an.l) table: dc.w pointer0 - table dc.w pointer1 - table
jump table が遠い場合
pointer と bra.s の PC + 2 との距離が -0x80 から 0x7e で収まる場合 lea table,an ;先述の table.w, pc(table) も併用する move.w ram,dn lsl.w #1,dn jmp (an,dn.w) ... ... ... table: bra.s pointer0 bra.s pointer1
pointer の値が -0x8000 から 0x7ffe で収まる場合 lea table,an ;同上 move.w ram,dn lsl.w #1,dn movea.w (an,dn.w),an jmp (an) ... ... ... table: dc.w pointer0 dc.w pointer1
pc に関わらず利用できる.
pointer と table の距離が -0x8000 から 0x7ffe で収まる場合 lea table,an ;同上 move.w ram,dn lsl.w #1,dn adda.w (an,dn.w),an jmp (an) ... ... ... table: dc.w pointer0 - table dc.w pointer1 - table
これはあまりいいものが思いつかなかった.
pointer が上記の方法で16bit以下に収まらない場合
pointer の最大値と最小値の差が 0x10000 未満の場合 center set pointer.min + (pointer.max - pointer.min) / 2 lea table,an ;同上 move.w ram,dn lsl.w #1,dn movea.w (an,dn.w),an if center < 0x8000 jmp (an,center) else adda.l #center,an jmp (an) endif table: dc.w pointer0 - center dc.w pointer1 - center
一応動作確認したが pointer の最大値と最小値を算出するのはビルドの過程で効率が悪すぎる. table の中身が奇数になることもありちょっと変. また adda.l が増えるので遅いので実用に向いていない.