Tuesday, October 5, 2010

Assembler today?

The use of assembler inside the code nowaways is almost insignificant (at least on regular developments), in the old pascal one had to code assembler or yes, I've check where do I use asm in the library and I found a few places, all very specific:

fast memory functions


procedure SwapMem(const aSrc, aDst; aLength: integer);  //EAX,EDX,ECX
asm
  PUSH  EBX
  PUSH  ESI
  PUSH  EDI

  ADD    EAX,ECX
  MOV    ESI,EAX        //Save Source
  ADD    EDX,ECX
  MOV    EDI,EDX        //Save Destination

  MOV    EBX,ECX
  SHR    ECX,3
  JECXZ  @ODD
  NEG    ECX            //Length

@LOOP64:
  MOVQ  MM0,[EAX+ECX*8]
  MOVQ  MM1,[EDX+ECX*8]
  MOVQ  [EAX+ECX*8],MM1
  MOVQ  [EDX+ECX*8],MM0

  INC    ECX
  JLE    @LOOP64
  EMMS

@ODD:
  AND    EBX,7
  JZ     @END
  ADD    ESI,EBX
  ADD    EDI,EBX
  NEG    EBX

@LOOP8:
  MOV    AL,[ESI+EBX]
  MOV    AH,[EDI+EBX]
  MOV    [ESI+EBX],AH
  MOV    [EDI+EBX],AL
  INC    EBX
  JNZ    @LOOP8

@END:
  POP    EDI
  POP    ESI
  POP    EBX
end;
procedure Fill24(const aData: T24; const aDst; aLength: integer);  //EAX,EDX,ECX
asm
  PUSH  ESI
  TEST  ECX,ECX
  JLE   @out

  MOV   SI,[EAX]
  MOV   AL,[EAX+2]

@LOOP:
  MOV   [EDX],SI
  MOV   [EDX+2],AL
  ADD   EDX,3
  DEC   ECX
  JNZ   @LOOP

@out:
  POP    ESI
end;
procedure MoveMMX(const aSrc, aDst; aLength: integer);  //EAX,EDX,ECX
asm
  PUSH  EBX
  PUSH  ESI
  PUSH  EDI

  TEST  ECX,ECX
  JLE   @out

  ADD   EAX,ECX
  MOV   ESI,EAX  //Save Source
  ADD   EDX,ECX
  MOV   EDI,EDX  //Save Destination

  MOV   EBX,ECX
  SHR   ECX,3
  JECXZ  @ODD
  NEG   ECX            //Length

@LOOP:
  MOVQ  MM0,[EAX+ECX*8]
  MOVQ  [EDX+ECX*8],MM0

  INC   ECX
  JNZ   @LOOP
  EMMS

@ODD:
  and    EBX,7
  JZ    @out
  ADD    ESI,EBX
  ADD    EDI,EBX
  NEG    EBX

@LOOP8:
  MOV   AL,[ESI+EBX]
  MOV   [EDI+EBX],AL

  INC   EBX
  JNZ   @LOOP8

@out:
  POP    EDI
  POP    ESI
  POP    EBX
end;
In namespace BB.Screen.DirectDraw you have one texture mapping example
x87 specific code
rocedure SinCos(const aTheta: TFloat; var aSin, aCos: TFloat);
asm
  FLD     aTheta
  FSINCOS
  FSTP    TFloat([EDX])    // Cos
  FSTP    TFloat([EAX])    // Sin
  //  FWAIT
end;
Bits operations
procedure TBit._Clear(var aValue: integer; aBit: integer);
//EDX, ECX
ASM
  BTR   [EDX], ECX
END;

function TBit._GetBit(aValue, aBit: integer): boolean;
//EDX, ECX: AL
ASM
  BT    EDX, ECX
  SETC  AL
END;

procedure TBit._SetBit(var aValue: integer; aBit: integer);
//[EDX], ECX
ASM
  BTS [EDX], ECX
END

That's all

No comments:

Post a Comment