使用MOVEM真正烧穿设置内存!
我建议你不要使用 CLR.L;如果您查看时钟计时,您会发现它似乎效率很低。最好使用您要设置内存的值加载一个寄存器,然后 MOVE.L ,(A0)+
但是,为了获得极快的速度,请使用MOVEM.L设置/清除大面积的内存。它比使用 CLR 或标准 MOVE.L 快 2 到 3 倍
这是一个设置 64 字节块的子例程示例,然后设置任何剩余的长字,但可以自定义。
ORG $2000
MOVE.L #MEMSTART,A0 ; memory to clear
MOVE.L #ZEROS,A1 ; value to set memory to e.g. 0
MOVE.L #600,D7 ; number of bytes
BSR SETBLOCK
STOP #2700
SETBLOCK
; MOVEM doesn't support destination = (Ax)+,
; does support destination = -(Ax)
ADD.L D7,A0 ; so start at end
LSR.L #2,D7 ; divide by 4 for Long words.
MOVE.L D7,D6
LSR.L #4,D6 ; # of 16 longword blocks
BEQ.S NOBLOCK ; branch if no none
SUBQ.L #1,D6 ; one less so DBRA works
MOVEM.L (A1),D0-D4/A2-A4 ; 8 registers = 32 bytes
ZAPBLOCK MOVEM.L D0-D4/A2-A4,-(A0) ; 8 x 4 = 32 bytes
MOVEM.L D0-D4/A2-A4,-(A0) ; 8 x 4 again for 64 bytes
DBRA D6,ZAPBLOCK ; loop ends when D7=-1
NOBLOCK AND.W #$0F,D7 ; how many long words left
BEQ.S NONE
; do any remainder
SUBQ.W #1,D7 ; 1 less so DBRA works
MOVE.L (A1),D0 ; pattern in D0 if not there b4
ZAP MOVE.L D0,-(A0) ; set memory long word at a time
DBRA D7,ZAP
NONE
RTS
ZEROS DC.L 0,0,0,0,0,0,0,0 ; 8x4 = 32
ORG $2500
MEMSTART DS.B 600
此示例使用 D0-D4 和 A2-A4 获取 8 个寄存器,一次设置 32 个字节,重复两次为 64 个字节。没有理由不能向 ZAPBLOCK 循环添加更多 MOVEM 指令,以便为每次循环迭代写入 128、256 或更多字节,从而相应地更改 LSR/AND 指令。
请注意,DBRA 仅对字进行操作,因此这只会设置 65k x 块大小。这可以修复,例如使用 SUBQ 和 BGT,而不是 DBRA。
出于某种原因,我记得 CLR 指令在一些 68k 上进行了读取和写入
定时
比较 3 种备选方案,假设标准 68000 具有 16 位数据总线...
使用 CLR
LOOP:
CLR (A0)+ 12+8
DBRA D7,LOOP 10/14
每个长字 30 个循环,每个长字 20 个,多次清除。
使用 MOVE.L
MOVEQ #0,D0 ; 4
LOOP:
MOVE.L D0,(A0)+ ; 12
DBRA D7,LOOP ; 10/14
每个长字 22 个周期,每个长字 12 个,带有多个 MOVE.L 操作。
使用 MOVEM.L
LOOP:
MOVEM.L D0-D4/A2-A4,-(A0) ; 8+8*8 = 72
MOVEM.L D0-D4/A2-A4,-(A0) ; 8+8*8 = 72
DBRA D6,LOOP ; 10/14
154 个周期/迭代,但每个长字只有大约 9.5 个周期。这可能与硬件 blitter 的性能相媲美。