此例程是一个窗口化的get / put-sprite仿真例程。 我是意大利人,我没有翻译过它们。 此例程能够在将图像存储在16字节对齐的缓冲区之前对图像进行翻转。 出于保密原因,我省略了预先计算程序。我从彼得·科德斯的建议中学到了充分利用LEA声明,并且是第一个个人实施的汇编者BT'指令:
Procedure Sub_MoveSprite; Assembler;
(* Sub-ROUTINE per MoveSprite (FlipX-FlipY).
INPUT:
EAX= Attributi immagine.
EBX= Scarto X per origine.
ECX= Quantità X di Pixel per LINEA.
EDX= Quantità Y di linee da trasf.
EBP= Scarto X per destinazione.
ESI= OFFSET per origine.
EDI= OFFSET per destinaz *)
Asm
Push EBP
Push EBX
Push ECX
BT EAX,Def_Target_DirX_D
SbB EBP,EBP
LEA EBP,[2*EBP+1]
BT EAX,Def_Source_DirX_D
SbB EBX,EBX
LEA EBX,[2*EBX+1]
@@01:Mov AL,[ESI]
Cmp AL,AH
JE @@00
Mov [EDI],AL
@@00:Add ESI,EBX
Add EDI,EBP
Loop @@01
Mov ECX,[ESP]
Add ESI,[ESP+4]
Add EDI,[ESP+8]
Dec EDX
JNE @@01
Add ESP,12
End;
如何优化?例如,将其细分为几个子例程: 在这种情况下,我不会在Y轴上翻转图像:
Procedure Sub_MoveSprite_FX0; Assembler;
{Sub-ROUTINE per MoveSprite (FlipY).
INPUT:
EAX= Attributi immagine.
EBX= Scarto X per origine.
ECX= Quantità X di Pixel per LINEA.
EDX= Quantità Y di linee da trasf.
EBP= Scarto X per destinazione.
ESI= OFFSET per origine.
EDI= OFFSET per destinaz}
Asm
ClD
Push ECX
@@01:LodSB
Cmp AL,AH
JE @@00
Mov [EDI],AL
@@00:Inc EDI
Loop @@01
Mov ECX,[ESP]
Add ESI,EBX
Add EDI,EBP
Dec EDX
JNE @@01
Add ESP,4
End;
现在这里有完整的优化代码,没有任何建议:
Procedure PutImage_FullClipp; Assembler;
{Calcola la CLIPPING REGION.
INPUT:
-----:
EAX : Byte_0 = BkCol, nuovo colore sfondo OBPVBuff (Ex simmetria verticale).
Byte_1 = SpCol, nuovo colore sfondo SPRITE.
Byte_2 = MaskCol, colore maschera/FIGURA.
Byte_3 = Attributi EXTRA:
Bit0= 0 -> Col. predef. dello sfondo di OBPVBuff.
1 -> Il Col. dello sfondo di OBPVBuff è BkCol.
Bit1= 0 -> Col. predef. dello sfondo.
1 -> Il Col. dello sfondo è SpCol.
Bit2= 0 -> Rappresenta lo SPRITE.
1 -> Rappresenta lo sfondo dello SPRITE.
Bit3= 0 -> L' immagine non è uno SPRITE.
1 -> L' immagine è uno SPRITE;
Bit4= 0 -> L' immag. non è uno maschera.
1 -> L' immag. è uno maschera di colore MaskCol.
Bit5= 0 -> Put-IMAGE.
1 -> Get-IMAGE.
Bit6= 0 -> Nessuna simmetria orizzontale.
1 -> Simmetria orizzontale.
Bit7= 0 -> Nessuna simmetria verticale.
1 -> Simmetria verticale.
EBX = Dimensioni X e Y della finestra sul BUFFER VIDEO
(specif. 0, la Dim. sarà consid. = a quella del BUFFER VIDEO).
ECX = COORDINATE X e Y dell' immagine OBP di origine.
EDX = COORDINATE X e Y della finestra sul BUFFER VIDEO.
ESI = PUNTATORE all' immagine OBP di origine.
EDI = PUNTATORE al BUFFER VIDEO OBP di destinazione.
OUTPUT:
------:
EAX : Byte_0 = Colore sfondo OBPVBuff.
Byte_1 = Colore sfondo SPRITE.
Byte_2 = MaskCol, colore maschera/FIGURA.
Byte_3 = Attributi EXTRA:
Bit0= 0 -> Il dithering inizia per 0.
1 -> Il dithering inizia per 1.
Bit1= 0 -> Col. predef. dello sfondo.
1 -> Il Col. dello sfondo è SpCol.
Bit2= 0 -> Rappresenta lo SPRITE.
1 -> Rappresenta lo sfondo dello SPRITE.
Bit3= 0 -> L' immagine non è uno SPRITE.
1 -> L' immagine è uno SPRITE;
Bit4= 0 -> L' immag. non è uno maschera.
1 -> L' immag. è uno maschera di colore MaskCol.
Bit5= 0 -> Put-IMAGE.
1 -> Get-IMAGE.
Bit6= 0 -> Incremento X destinazione = 1.
1 -> Incremento X destinazione (FlipX) = -1.
Bit7= 0 -> Incremento X origine = 1.
1 -> Incremento X origine (FlipX)= -1.
EBX = Scarto X per origine.
ECX = Quantità X di Pixel per LINEA.
EDX = Quantità Y di linee.
EBP = Scarto X per destinazione.
ESI = PUNTATORE ai dati da trasferire per l' origine.
EDI = PUNTATORE alla destinazione dei dati da trasferire.
FCarry = 1 -> ERRORE, i registri di OUTPUT
non contengono valori attendibili.
= 0 -> Ok, tutti i registri di OUTPUT
contengono valori attendibili}
Asm
Sub ESP,60 {Definisce le variabili locali sullo STACK}
(* Attr {[ESP+00]: Attributi SPRITE}
X {[ESP+04]: COORDINATA X immagine da trasferire}
Y {[ESP+08]: COORDINATA Y immagine da trasferire}
DimX {[ESP+12]: Dimensione X immagine da trasferire}
DimY {[ESP+16]: Dimensione Y immagine da trasferire}
WindX {[ESP+20]: COORDINATA X finestra sul BUFFER VIDEO}
WindY {[ESP+24]: COORDINATA Y finestra sul BUFFER VIDEO}
DimWindX {[ESP+28]: Dimensione X finestra sul BUFFER VIDEO}
DimWindY {[ESP+32]: Dimensione Y finestra sul BUFFER VIDEO}
ADimX {[ESP+36]: Dimens. X immagine da trasf. allineata ai 16 BYTE}
ADimScrX {[ESP+40]: Dimensione X BUFFER VIDEO allineata ai 16 BYTE}
SourcePtr {[ESP+44]: PUNTATORE all' immagine OBP di origine}
TargetPtr {[ESP+48]: PUNTATORE alla destinazione dei dati da trasferire}
FlipX {[ESP+52]: Maschera x simmetria orizzontale}
FlipY {[ESP+56]: Maschera x simmetria verticale} *)
{Preparazione iniziale e controllo coerenza parametri}
{ SI<1 | DI<1 | CL | FSign
-------+--------+----------+-------
0 | 0 | -0 -0 0 | 0
0 | 1 | -0 -1 -1 | 1
1 | 0 | -1 -0 -1 | 1
1 | 1 | -1 -1 -2 | 1
-------+--------+----------+-------}
Cmp ESI,1 {Se IMAGE=NIL, ...}
SbB EBP,EBP {... EBP vale -1, altrim. vale 0}
Cmp EDI,1 {Se OBPVBuff=NIL, ...}
SbB EBP,0 {... EBP vale EBP-1, altrim. vale EBP}
StC {Se IMAGE=NIL o se OBPVBuff=NIL, imposta FCarry=1 ...}
JS @@Ex {... ed esce}
{-----------------------------------}
Mov EBP,[ESI] {Carica Dim_XY(IMAGE) IN EBP}
Add ESI,DimOBP_H {ESI punta all' area dati di IMAGE}
Mov [ESP+44],ESI {Salva ESI su SourcePtr}
{-----------------------------------}
MovSX ESI,BP {Estende con SEGNO ...}
Or ESI,ESI {... la Dim. X di IMAGE IN ESI; ...}
StC {... se è <=0, imposta FCarry=1 ...}
JLE @@Ex {... ed esce}
Or EBP,EBP {Estende con SEGNO ...}
SAR EBP,16 {... la Dim. Y di IMAGE IN EBP; ...}
StC {... se è <=0, imposta FCarry=1 ...}
JLE @@Ex {... ed esce}
{-----------------------------------}
Mov [ESP+12],ESI {Salva la Dim. X di IMAGE con 0 esteso su DimX}
Mov [ESP+16],EBP {Salva la Dim. Y di IMAGE con 0 esteso su DimY}
{-----------------------------------}
Mov EBP,ESI {Calcola, IN EBP, la Dim. X di IMAGE ...}
And EBP,R_OBP_Al-1 {...}
Neg EBP {...}
Add EBP,R_OBP_Al {...}
And EBP,R_OBP_Al-1 {...}
Add EBP,ESI {... allineata ai 16 BYTE e ...}
Mov [ESP+36],EBP {... la salva su ADimX}
{-----------------------------------}
Mov ESI,[EDI] {Carica Dim_XY(OBPVBuff) IN ESI}
Add EDI,DimOBP_H {EDI punta all' area dati di OBPVBuff}
Mov [ESP+48],EDI {Salva EDI su TargetPtr}
{-----------------------------------}
MovSX EDI,SI {Estende con SEGNO ...}
Or EDI,EDI {... la Dim. X di OBPVBuff IN EDI; ...}
StC {... se è <=0, imposta FCarry=1 ...}
JLE @@Ex {... ed esce}
Or ESI,ESI {Estende con SEGNO ...}
SAR ESI,16 {... la Dim. Y di OBPVBuff IN ESI; ...}
StC {... se è <=0, imposta FCarry=1 ...}
JLE @@Ex {... ed esce}
{-----------------------------------}
Test EAX,_Def_Attr_New_BkCol {Se il Bit0 di Attr.MODE <> 0 ...}
JNE @@00 {... usa il nuovo colore dello sfondo di OBPVBuff}
Mov EBP,[ESP+48] {Carica TargetPtr IN EBP e ...}
Mov AL,[EBP] {... carica IN AL il colore sfondo di OBPVBuff}
@@00:Test EAX,_Def_Attr_New_SpCol {Se il Bit1 di Attr.MODE <> 0 ...}
JNE @@01 {... usa il nuovo colore dello sfondo di IMAGE}
Mov EBP,[ESP+44] {Carica SourcePtr IN EBP e ...}
Mov AH,[EBP] {... carica IN AH il colore sfondo di IMAGE}
@@01:BT EAX,Def_Attr_FlipY_D {Bit7(Attr.MODE)<>0? Si: FCarry=1; no: FCarry=0}
SbB EBP,EBP {Se Bit7 di Attr.MODE <>0, EBP=-1, altrim. EBP=0}
Mov [ESP+56],EBP {Imposta FlipY=EBP}
BT EAX,Def_Attr_FlipX_D {Bit6(Attr.MODE)<>0? Si: FCarry=1; no: FCarry=0}
SbB EBP,EBP {Se Bit6 di Attr.MODE <>0, EBP=-1, altrim. EBP=0}
Mov [ESP+52],EBP {Imposta FlipX=EBP}
And EBP,_Def_Target_DirX {EBP contiene il Bit6 di Attr.MODE}
And EAX,-1-_Def_Source_DirX-_Def_Dither {CANC. Bit0 e Bit7 di Attr.MODE}
Test EAX,_Def_Attr_Get_Image {Se il Bit5 di Attr.MODE=0 ...}
JE @@02 {... salta}
XChg AL,AH {Scambia i colori dello sfondo di IMAGE e OBPVBuff}
Add EAX,EBP {Scambia il Bit6 Col Bit7 di Attr.MODE}
@@02:Mov [ESP],EAX {Salva Attr.MODE su Attr}
{-----------------------------------}
Mov EAX,EDI {Calcola, IN EAX, la Dim. X di OBPVBuff ...}
And EAX,R_OBP_Al-1 {...}
Neg EAX {...}
Add EAX,R_OBP_Al {...}
And EAX,R_OBP_Al-1 {...}
Add EAX,EDI {... allineata ai 16 BYTE e ...}
Mov [ESP+40],EAX {... la salva su ADimScrX}
{-----------------------------------}
MovSX EAX,CX {Calcola, IN EAX, la coord. X di IMAGE, ...}
Mov [ESP+4],EAX {... con SEGNO esteso e la salva su X}
Or ECX,ECX {Calcola, IN ECX, la coord. Y di IMAGE, ...}
SAR ECX,16 {... con SEGNO esteso e ...}
Mov [ESP+8],ECX {... la salva su Y}
{-----------------------------------}
MovSX EAX,DX {Estende con SEGNO la coord. X ...}
Or EAX,EAX {... della finestra sul BUFFER VIDEO IN EAX; ...}
StC {... se è <0, imposta FCarry=1 ...}
JS @@Ex {... ed esce}
Or EDX,EDX {Estende con SEGNO la coord. Y ...}
SAR EDX,16 {... della finestra sul BUFFER VIDEO IN EDX; ...}
StC {... se è <0, imposta FCarry=1 ...}
JS @@Ex {... ed esce}
{-----------------------------------}
Mov [ESP+20],EAX {Salva la coord. X fin. BUFFER Vid. con 0 e. su WindX}
Mov [ESP+24],EDX {Salva la coord. Y fin. BUFFER Vid. con 0 e. su WindY}
{-----------------------------------}
MovSX ECX,BX {Estende con SEGNO la dimens. X ...}
Or ECX,ECX {... della finestra sul BUFFER VIDEO IN ECX; ...}
StC {... se è <0, imposta FCarry=1 ...}
JS @@Ex {... ed esce}
JNE @@03 {Se la dimens. X della finestra sul BUFFER VIDEO ...}
Mov ECX,EDI {... è =0, la imposta con la Dim. X di OBPVBuff}
@@03:Add EAX,ECX {Se la coord. X della finestra sul BUFFER VIDEO ...}
Cmp EDI,EAX {... più la Dim. X finestra sul BUFFER VIDEO ...}
JB @@Ex {... > Dim. X di OBPVBuff, esce (FCarry=1)}
{-----------------------------------}
Or EBX,EBX {Estende con SEGNO la dimens. Y ...}
SAR EBX,16 {... della finestra sul BUFFER VIDEO IN EBX ...}
StC {... se è <0, imposta FCarry=1 ...}
JS @@Ex {... ed esce}
JNE @@04 {Se la dimens. Y della finestra sul BUFFER VIDEO ...}
Mov EBX,ESI {... è =0, la imposta con Dim. Y di OBPVBuff}
@@04:Add EDX,EBX {Se la coord. Y della finestra sul BUFFER VIDEO ...}
Cmp ESI,EDX {... più la Dim. Y finestra sul BUFFER VIDEO ...}
JB @@Ex {... > Dim. Y di OBPVBuff, esce (FCarry=1)}
{-----------------------------------}
Mov [ESP+28],ECX {Salva la Dim.X fin. BUFFER Vid. con 0 e. su DimWindX}
Mov [ESP+32],EBX {Salva la Dim.Y fin. BUFFER Vid. con 0 e. su DimWindY}
{Calcola scarti XLow (ESI) e XHigh (ECX)}
Mov EDI,[ESP+4] {Carica, IN EDI, la coord. X di IMAGE}
Mov EBX,[ESP+12] {Carica, IN EBX, la Dim. X di IMAGE}
XOr ESI,ESI {Imposta XLow=0}
XOr ECX,ECX {Imposta XHigh=0}
Or EDI,EDI {Se EDI>=0 ...}
JNS @@05 {... salta}
Add EDI,EBX {Imposta EDI=EDI+EBX; ...}
StC {... se EDI<0, ...}
JS @@Ex {... imposta FCarry=1 ed esce}
Mov ESI,[ESP+4] {Imposta XLow con la coord. X di IMAGE}
Neg ESI {Imposta XLow=-XLow}
Mov DWord Ptr [ESP+4],0 {Imposta la coord. X di IMAGE a 0}
Jmp @@06 {Salta}
@@05:Cmp EDI,[ESP+28] {Se EDI>=Dim. X della finestra su OBPVBuff ...}
CmC {...}
JB @@Ex {... imposta FCarry=1 ed esce}
Add EDI,EBX {Imposta EDI=EDI+EBX}
@@06:Cmp EDI,[ESP+28] {Se EDI<=Dim. X della finestra su OBPVBuff ...}
JBE @@07 {... salta}
Mov ECX,EDI {Imposta ...}
Sub ECX,[ESP+28] {... XHigh=EDI-Dim. X della finestra su OBPVBuff}
{Calcola scarti YLow (EDI) e YHigh (EBX)}
@@07:Mov EAX,[ESP+8] {Carica, IN EAX, la coord. Y di IMAGE}
Mov EDX,[ESP+16] {Carica, IN EDX, la Dim. Y di IMAGE}
XOr EDI,EDI {Imposta YLow=0}
XOr EBX,EBX {Imposta YHigh=0}
Or EAX,EAX {Se EAX>=0 ...}
JNS @@08 {... salta}
Add EAX,EDX {Imposta EAX=EAX+EDX; ...}
StC {... se EAX<0, ...}
JS @@Ex {... imposta FCarry=1 ed esce}
Mov EDI,[ESP+8] {Imposta YLow con la coord. Y di IMAGE}
Neg EDI {Imposta YLow=-YLow}
Mov DWord Ptr [ESP+8],0 {Imposta la coord. Y di IMAGE a 0}
Jmp @@09 {Salta}
@@08:Cmp EAX,[ESP+32] {Se EAX>=Dim. Y della finestra su OBPVBuff ...}
CmC {...}
JB @@Ex {... imposta FCarry=1 ed esce}
Add EAX,EDX {Imposta EAX=EAX+EDX}
@@09:Cmp EAX,[ESP+32] {Se EAX<=Dim. Y della finestra su OBPVBuff ...}
JBE @@10 {... salta}
Mov EBX,EAX {Imposta ...}
Sub EBX,[ESP+32] {... YHigh=EAX-Dim. Y della finestra su OBPVBuff}
{Prepara i registri di OUTPUT EAX, EBX, ECX, EDX, EDI, ESI}
@@10:Cmp DWord Ptr [ESP+56],-1 {Se FlipY=-1 ...}
Mov EAX,EDI {...}
CMovE EDI,EBX {...}
CMovE EBX,EAX {... scambia YHigh con YLow}
{-----------------------------------}
Add EBX,EDI { EBX= YHigh+YLow}
Neg EBX { EBX= -YHigh-YLow}
Add EBX,[ESP+16] { EBX= DimY-YHigh-YLow; N.righe da trasf.}
StC {Se non CI sono righe da trasf., FCarry=1 ...}
JE @@Ex {... esce}
{-----------------------------------}
Cmp DWord Ptr [ESP+52],-1 {Se FlipX=-1 ...}
Mov EAX,ESI {...}
CMovE ESI,ECX {...}
CMovE ECX,EAX {... scambia XHigh con XLow}
{-----------------------------------}
Add ECX,ESI { ECX= XHigh+XLow}
Neg ECX { ECX= -XHigh-XLow}
Add ECX,[ESP+12] { ECX= DimX-XHigh-XLow; N.Col. da trasf.}
StC {Se non CI sono colonne da trasf., FCarry=1 ...}
JE @@Ex {... esce}
{-----------------------------------}
Mov EBP,ESI { EBP= XLow}
XOr EBP,EDI { EBP= XLow ^ YLow}
And EBP,1 { EBP= (XLow ^ YLow) & 1}
ShL EBP,Def_Dither_D { EBP= ((XLow ^ YLow) & 1)<<24}
Or [ESP],EBP { Attr.MODE= Attr.MODE | ((XLow ^ YLow) & 1)}
{-----------------------------------}
Mov EBP,ECX { EBP= -XLow-XHigh+DimX}
Dec EBP { EBP= -XLow-XHigh+DimX-1}
And EBP,[ESP+52] { EBP= (-XLow-XHigh+DimX-1) & FlipX}
Add EBP,[ESP+4] { EBP= X+[-XLow-XHigh+DimX-1]}
Add EBP,[ESP+20] { EBP= X+[-XLow-XHigh+DimX-1]+WindX}
Mov EAX,EBX { EAX= -YLow-YHigh+DimY}
Dec EAX { EAX= -YLow-YHigh+DimY-1}
And EAX,[ESP+56] { EAX= (-YLow-YHigh+DimY-1) & FlipY}
Add EAX,[ESP+8] { EAX= Y+[-YLow-YHigh+DimY-1]}
Add EAX,[ESP+24] { EAX= Y+[-YLow-YHigh+DimY-1]+WindY}
Mul DWord Ptr [ESP+40] {EDX:EAX= (Y+[-YLow-YHigh+DimY-1]+WindY)*ADimScrX}
Add EAX,EBP { EAX= (Y+[-YLow-YHigh+DimY-1]+WindY)*ADimScrX+ ...}
{... +X+[-XLow-XHigh+DimX-1]+WindX}
Add [ESP+48],EAX {TargetPtr=(Y+[-YLow-YHigh+DimY-1]+WindY)*ADimScrX+...}
{... +X+[-XLow-XHigh+DimX-1]+WindX+TargetPtr}
{-----------------------------------}
Mov EAX,EDI { EAX= YLow}
Mul DWord Ptr [ESP+36] {EDX:EAX= YLow*ADimX}
Add EAX,ESI { EAX= YLow*ADimX+XLow}
Add [ESP+44],EAX {SourcePtr=YLow*ADimX+XLow+SourcePtr}
{-----------------------------------}
Mov EDX,EBX { EDX= DimY-YHigh-YLow; N.righe da trasf.}
Mov EBX,ECX { EBX= DimX-XHigh-XLow}
Neg EBX { EBX= -DimX+XHigh+XLow}
Mov EAX,EBX { EAX= -DimX+XHigh+XLow}
Add EBX,[ESP+36] { EBX= -DimX+XHigh+XLow+ADimX; scarto X per Orig}
Add EAX,[ESP+40] { EAX=-DimX+XHigh+XLow+ADimScrX; scarto X per Dest}
(* SX= Scarto X per Dest. (EAX)
NCol= N.Col. da trasf. (ECX)
------+-------+---------------
FlipX | FlipY | ScartoXDest
0 | 0 | SX
0 | -1 | -2*NCol-SX)
-1 | 0 | 2*NCol+SX
-1 | -1 | -SX *)
LEA EDI,[2*ECX] { EDI= 2*ECX}
Mov EBP,[ESP+52] { ...}
XOr EBP,[ESP+56] {... EBP= FlipX ^ FlipY}
And EDI,EBP { EDI= 2*NCol & (FlipX ^ FlipY)}
Add EAX,EDI { EAX= SX+2*NCol & (FlipX ^ FlipY)}
XOr EAX,[ESP+56] {Se FlipY=-1 allora EAX=-EAX ...}
Sub EAX,[ESP+56] {... altrimenti EAX è inalterato}
Mov EBP,EAX { EBP= Scarto X per Dest}
Mov EDI,[ESP+48] { EDI= PTR Dest.}
Mov ESI,[ESP+44] { ESI= PTR Orig.}
Mov EAX,[ESP] { EAX= Attr}
Test EAX,_Def_Attr_Get_Image {Se il Bit5 di Attr.MODE=0 ...}
JE @@Ex {... salta}
XChg ESI,EDI { Scambia PTR Orig. con PTR Dest.}
XChg EBX,EBP { Scambia scarto X per Orig. con scarto X per Dest}
ClC { FCarry=0; nessun ERRORE}
{-----------------------------------}
@@Ex:LEA ESP,[ESP+60] { Reimposta lo STACK-POINTER; esce}
End;
Procedure MoveImage(Image:T_Image_Ptr;
Prop:T_Long_Attrib_Ptr;
OBPVBuff:Pointer;
Clipp:T_Clipp_Rect_Ptr); Assembler;
{Disegna un immagine con CLIPPING REGION.
INPUT:
EAX = PUNTATORE a RECORD di definizione dell' immagine.
EDX = PUNTATORE alle proprietà dell' immagine.
ECX = PUNTATORE al BUFFER VIDEO IN formato OBP.
Clipp = PUNTATORE al RECORD della CLIPPING REGION.
PARAMETERs order:
1°=EAX; 2°=EDX; 3°=ECX}
Asm
Push EBX
Push EDI
Push ESI
Push EBP
Mov ESI,Image {EAX}
Mov EBX,Prop {EDX}
Mov EDI,OBPVBuff {ECX}
Mov EDX,Clipp
Mov EAX,EBX
Or EBX,EBX
JE @@00
Mov EAX,[EBX]
Mov EBX,[EBX+4]
@@00:Push EBX
Or ESI,ESI
JE @@01
Mov ECX,[ESI]
Mov ESI,[ESI+4]
Mov EBX,EDX
Or EDX,EDX
JE @@02
Mov EDX,[EBX] {Clipp.XY}
Mov EBX,[EBX+4] {Clipp.Dim_XY}
@@02:Call PutImage_FullClipp
JB @@01
(* _DirX | _Sprite | ShadowTable | _Mask | _BackG | FUNCTION
------+---------+-------------+-------+--------+---------
0 | 0 | 0 | 0 | 0 | Sub_MoveImage_FX0
0 | 0 | 0 | 0 | 1 | Sub_MoveImage_FX0
0 | 0 | 0 | 1 | 0 | Sub_MoveImageMask_FX0
0 | 0 | 0 | 1 | 1 | Sub_MoveImageMask_FX0
0 | 0 | 1 | 0 | 0 | Sub_MoveImageShadow_FX0
0 | 0 | 1 | 0 | 1 | Sub_MoveImageShadow_FX0
0 | 0 | 1 | 1 | 0 | Sub_MoveImageShadow_FX0
0 | 0 | 1 | 1 | 1 | Sub_MoveImageShadow_FX0
0 | 1 | 0 | 0 | 0 | Sub_MoveSprite_FX0
0 | 1 | 0 | 0 | 1 | Sub_MoveSpriteBk_FX0
0 | 1 | 0 | 1 | 0 | Sub_MoveSpriteMask_FX0
0 | 1 | 0 | 1 | 1 | Sub_MoveSpriteBkMsk_FX0
0 | 1 | 1 | 0 | 0 | Sub_MoveSpriteShad_FX0
0 | 1 | 1 | 0 | 1 | Sub_MoveSprBkShad_FX0
0 | 1 | 1 | 1 | 0 | Sub_MoveSpriteShad_FX0
0 | 1 | 1 | 1 | 1 | Sub_MoveSprBkShad_FX0
1 | 0 | 0 | 0 | 0 | Sub_MoveImage
1 | 0 | 0 | 0 | 1 | Sub_MoveImage
1 | 0 | 0 | 1 | 0 | Sub_MoveImageMask
1 | 0 | 0 | 1 | 1 | Sub_MoveImageMask
1 | 0 | 1 | 0 | 0 | Sub_MoveImageShadow
1 | 0 | 1 | 0 | 1 | Sub_MoveImageShadow
1 | 0 | 1 | 1 | 0 | Sub_MoveImageShadow
1 | 0 | 1 | 1 | 1 | Sub_MoveImageShadow
1 | 1 | 0 | 0 | 0 | Sub_MoveSprite
1 | 1 | 0 | 0 | 1 | Sub_MoveSpriteBk
1 | 1 | 0 | 1 | 0 | Sub_MoveSpriteMask
1 | 1 | 0 | 1 | 1 | Sub_MoveSpriteBkMask
1 | 1 | 1 | 0 | 0 | Sub_MoveSpriteShadow
1 | 1 | 1 | 0 | 1 | Sub_MoveSpriteBkShadow
1 | 1 | 1 | 1 | 0 | Sub_MoveSpriteShadow
1 | 1 | 1 | 1 | 1 | Sub_MoveSpriteBkShadow *)
Test EAX,_Def_DirX
JE @@03
Test EAX,_Def_Attr_Sprite
JNE @@04
Cmp DWord Ptr [ESP],0
JNE @@05
Test EAX,_Def_Attr_Mask
JNE @@06
Call Sub_MoveImage
Jmp @@01
@@06:Call Sub_MoveImageMask
Jmp @@01
@@05:Call Sub_MoveImageShadow
Jmp @@01
@@04:Cmp DWord Ptr [ESP],0
JNE @@07
Test EAX,_Def_Attr_Mask
JNE @@08
Test EAX,_Def_Attr_BackG
JNE @@09
Call Sub_MoveSprite
Jmp @@01
@@09:Call Sub_MoveSpriteBk
Jmp @@01
@@08:Test EAX,_Def_Attr_BackG
JNE @@10
Call Sub_MoveSpriteMask
Jmp @@01
@@10:Call Sub_MoveSpriteBkMask
Jmp @@01
@@07:Test EAX,_Def_Attr_BackG
JNE @@11
Call Sub_MoveSpriteShadow
Jmp @@01
@@11:Call Sub_MoveSpriteBkShadow
Jmp @@01
@@03:Test EAX,_Def_Attr_Sprite
JNE @@12
Cmp DWord Ptr [ESP],0
JNE @@13
Test EAX,_Def_Attr_Mask
JNE @@14
Call Sub_MoveImage_FX0
Jmp @@01
@@14:Call Sub_MoveImageMask_FX0
Jmp @@01
@@13:Call Sub_MoveImageShadow_FX0
Jmp @@01
@@12:Cmp DWord Ptr [ESP],0
JNE @@15
Test EAX,_Def_Attr_Mask
JNE @@16
Test EAX,_Def_Attr_BackG
JNE @@17
Call Sub_MoveSprite_FX0
Jmp @@01
@@17:Call Sub_MoveSpriteBk_FX0
Jmp @@01
@@16:Test EAX,_Def_Attr_BackG
JNE @@18
Call Sub_MoveSpriteMask_FX0
Jmp @@01
@@18:Call Sub_MoveSpriteBkMsk_FX0
Jmp @@01
@@15:Test EAX,_Def_Attr_BackG
JNE @@19
Call Sub_MoveSpriteShad_FX0
Jmp @@01
@@19:Call Sub_MoveSprBkShad_FX0
@@01:Add ESP,4
Pop EBP
Pop ESI
Pop EDI
Pop EBX
End;
答案 0 :(得分:1)
在优化速度时不要使用the slow loop
instruction,除非AMD CPU实际上并不慢。
通过使用movzx进行字节加载,避免部分寄存器减速。 (lodsb比movzx
+ inc esi
慢,所以也不要使用它。有关更多x86性能优化的信息,请参阅http://agner.org/optimize/。 (以及the x86 tag wiki中的链接。)
您的第二个功能只是基于字节不是特殊透明值的混合。使用SSE2优化pcmpeqb
,然后与pand
/ pandn
+ por
混合。或SSE4.1 pblendvb
。
SSSE3 pshufb
可让您更有效地向所有位置广播一个字节。
特别是如果你制作一个具有固定宽度的版本,如16,24或32像素宽,你可以避免在标量清理代码中需要很多处理奇数宽度。但是,对于可能重叠的第一个/最后一个未对齐的矢量存储,任何宽于16的东西都应该是可行的。
是的,制作函数的不同版本而不是传递整数翻转/无翻转参数可能是好的,特别是如果你使用SSSE3翻转pshufb
(或多个SSE2 shuffle,甚至是标量{{ 1}})。使用bswap
,您可以进行身份随机播放(使矢量保持不变而不是反转),但为没有翻转的情况设置一个单独的循环会更加有效,因为它不会使用{{ 1}}。