📄 assembler.pas
字号:
else if Reg in [rAX..rDI] then
begin
Dec(Reg,Ord(rAX));
X := $58 + Ord(Reg);
AddBytes(X,1);
end;
end;
procedure TAsm.AsmPopSeg(Seg: TSegment);
var
X: Array[0..1] of Byte;
begin
case Seg of
sSS:
X[0] := $17;
sDS:
X[0] := $1F;
sES:
X[0] := $07;
sFS:
begin
X[0] := $0F;
X[1] := $A1;
end;
sGS:
begin
X[0] := $0F;
X[1] := $A9;
end;
end;
if X[1] = 0 then
AddBytes(X,1)
else
AddBytes(X,2);
end;
procedure TAsm.AsmXorReg(Reg: TRegister);
var
X: Array[0..1] of Byte;
begin
X[0] := $31;
if Reg in [rAX..rDI] then
begin
Dec(Reg,Ord(rAX));
end
else if Reg in [rAL..rBH] then
begin
X[0] := $30;
Dec(Reg,Ord(rAL));
end;
X[1] := $C0 or (Ord(Reg) shl 3) or Ord(Reg);
AddBytes(X,2);
end;
procedure TAsm.AsmJmp(Value: LongWord; Size: TSymbolSize);
var
X: Array[0..4] of Byte;
begin
if Size = ss8 then
begin
X[0] := $EB;
X[1] := Byte(Value);
AddBytes(X,2);
end
else if Size = ss16 then
begin
X[0] := $E9;
Word((@X[1])^) := Value;
AddBytes(X,3);
end
else if Size = ss32 then
begin
X[0] := $E9;
LongWord((@X[1])^) := Value;
AddBytes(X,5);
end;
end;
procedure TAsm.AsmJe(Value: LongWord; Size: TSymbolSize);
var
X: Array[0..5] of Byte;
begin
if Size = ss8 then
begin
X[0] := $74;
X[1] := Byte(Value);
AddBytes(X,2);
end
else if Size = ss16 then
begin
X[0] := $0F;
X[1] := $84;
Word((@X[2])^) := Value;
AddBytes(X,4);
end
else if Size = ss32 then
begin
X[0] := $0F;
X[1] := $84;
LongWord((@X[2])^) := Value;
AddBytes(X,6);
end;
end;
procedure TAsm.AsmJg(Value: LongWord; Size: TSymbolSize);
var
X: Array[0..5] of Byte;
begin
if Size = ss8 then
begin
X[0] := $7F;
X[1] := Byte(Value);
AddBytes(X,2);
end
else if Size = ss16 then
begin
X[0] := $0F;
X[1] := $8F;
Word((@X[2])^) := Value;
AddBytes(X,4);
end
else if Size = ss32 then
begin
X[0] := $0F;
X[1] := $8F;
LongWord((@X[2])^) := Value;
AddBytes(X,6);
end;
end;
procedure TAsm.AsmJl(Value: LongWord; Size: TSymbolSize);
var
X: Array[0..5] of Byte;
begin
if Size = ss8 then
begin
X[0] := $7C;
X[1] := Byte(Value);
AddBytes(X,2);
end
else if Size = ss16 then
begin
X[0] := $0F;
X[1] := $8C;
Word((@X[2])^) := Value;
AddBytes(X,4);
end
else if Size = ss32 then
begin
X[0] := $0F;
X[1] := $8C;
LongWord((@X[2])^) := Value;
AddBytes(X,6);
end;
end;
procedure TAsm.AsmJng(Value: LongWord; Size: TSymbolSize);
var
X: Array[0..5] of Byte;
begin
if Size = ss8 then
begin
X[0] := $7E;
X[1] := Byte(Value);
AddBytes(X,2);
end
else if Size = ss16 then
begin
X[0] := $0F;
X[1] := $8E;
Word((@X[2])^) := Value;
AddBytes(X,4);
end
else if Size = ss32 then
begin
X[0] := $0F;
X[1] := $8E;
LongWord((@X[2])^) := Value;
AddBytes(X,6);
end;
end;
procedure TAsm.AsmJnl(Value: LongWord; Size: TSymbolSize);
var
X: Array[0..5] of Byte;
begin
if Size = ss8 then
begin
X[0] := $7D;
X[1] := Byte(Value);
AddBytes(X,2);
end
else if Size = ss16 then
begin
X[0] := $0F;
X[1] := $8D;
Word((@X[2])^) := Value;
AddBytes(X,4);
end
else if Size = ss32 then
begin
X[0] := $0F;
X[1] := $8D;
LongWord((@X[2])^) := Value;
AddBytes(X,6);
end;
end;
procedure TAsm.AsmJne(Value: LongWord; Size: TSymbolSize);
var
X: Array[0..5] of Byte;
begin
if Size = ss8 then
begin
X[0] := $75;
X[1] := Byte(Value);
AddBytes(X,2);
end
else if Size = ss16 then
begin
X[0] := $0F;
X[1] := $85;
Word((@X[2])^) := Value;
AddBytes(X,4);
end
else if Size = ss32 then
begin
X[0] := $0F;
X[1] := $85;
LongWord((@X[2])^) := Value;
AddBytes(X,6);
end;
end;
procedure TAsm.AsmJge(Value: LongWord; Size: TSymbolSize);
var
X: Array[0..5] of Byte;
begin
if Size = ss8 then
begin
X[0] := $7D;
X[1] := Byte(Value);
AddBytes(X,2);
end
else if Size = ss16 then
begin
X[0] := $0F;
X[1] := $8D;
Word((@X[2])^) := Value;
AddBytes(X,4);
end
else if Size = ss32 then
begin
X[0] := $0F;
X[1] := $8D;
LongWord((@X[2])^) := Value;
AddBytes(X,6);
end;
end;
procedure TAsm.AsmJle(Value: LongWord; Size: TSymbolSize);
var
X: Array[0..5] of Byte;
begin
if Size = ss8 then
begin
X[0] := $7E;
X[1] := Byte(Value);
AddBytes(X,2);
end
else if Size = ss16 then
begin
X[0] := $0F;
X[1] := $8E;
Word((@X[2])^) := Value;
AddBytes(X,4);
end
else if Size = ss32 then
begin
X[0] := $0F;
X[1] := $8E;
LongWord((@X[2])^) := Value;
AddBytes(X,6);
end;
end;
procedure TAsm.AsmCmp(Val1, Val2: LongWord; Size: TSymbolSize);
var
X: Array[0..5] of Byte;
begin
if Size = ss8 then
begin
AsmMovRegImm(rAL,Val1);
X[0] := $3C;
X[1] := Byte(Val2);
AddBytes(X,2);
end
else if Size = ss16 then
begin
AsmMovRegImm(rAX,Val1);
X[0] := $3D;
Word((@X[1])^) := Val2;
AddBytes(X,3);
end
else if Size = ss32 then
begin
AsmMovRegImm(rEAX,Val1);
X[0] := $3D;
LongWord((@X[1])^) := Val2;
AddBytes(X,5);
end;
end;
procedure TAsm.AsmCmpV(Val1, Val2: LongWord; Size: TSymbolSize);
var
X: Array[0..5] of Byte;
begin
if Size = ss8 then
begin
X[0] := $80;
X[1] := $3E;
Word((@X[2])^) := Val1;
AddBytes(X,4);
AddFixup(Val1,ss16,ftDataAddress);
X[0] := Word(Val2);
AddBytes(X,1);
end
else if Size = ss16 then
begin
X[0] := $81;
X[1] := $3E;
Word((@X[2])^) := Val1;
AddBytes(X,4);
AddFixup(Val1,ss16,ftDataAddress);
Word((@X[0])^) := Val2;
AddBytes(X,2);
end
else if Size = ss32 then
begin
X[0] := $81;
X[1] := $3E;
LongWord((@X[2])^) := Val1;
AddBytes(X,6);
AddFixup(Val1,ss32,ftDataAddress);
LongWord((@X[0])^) := Val2;
AddBytes(X,4);
end;
end;
procedure TAsm.AsmCmpVV(Val1, Val2: LongWord; Size: TSymbolSize);
var
X: Array[0..5] of Byte;
begin
if Size = ss8 then
begin
AsmMovAccImm(ss8,Val1);
AddFixup(Val1,ss16,ftDataAddress);
X[0] := $3A;
X[1] := $06;
Word((@X[2])^) := Val2;
AddBytes(X,4);
AddFixup(Val2,ss16,ftDataAddress);
end
else if Size = ss16 then
begin
AsmMovAccImm(ss16,Val1);
AddFixup(Val1,ss16,ftDataAddress);
X[0] := $3B;
X[1] := $06;
Word((@X[2])^) := Val2;
AddBytes(X,4);
AddFixup(Val2,ss16,ftDataAddress);
end
else if Size = ss32 then
begin
AsmMovAccImm(ss32,Val1);
AddFixup(Val1,ss32,ftDataAddress);
AddPrefix;
X[0] := $3B;
X[1] := $06;
LongWord((@X[2])^) := Val2;
AddBytes(X,6);
AddFixup(Val2,ss32,ftDataAddress);
end;
end;
procedure TAsm.AsmInt(Value: Byte);
var
X: Array[0..1] of Byte;
begin
X[0] := $CD;
X[1] := Value;
AddBytes(X,2);
end;
procedure TAsm.AsmCall(Value: LongWord; Size: TSymbolSize);
var
X: Array[0..4] of Byte;
begin
X[0] := $E8;
if Size = ss16 then
begin
Word((@X[1])^) := Value;
AddBytes(X,3);
end
else if Size = ss16 then
begin
LongWord((@X[1])^) := Value;
AddBytes(X,5);
end;
end;
procedure TAsm.AsmRet(FarRet: Boolean = False);
var
X: Byte;
begin
if FarRet then
X := $CB
else
X := $C3;
AddBytes(X,1);
end;
procedure TAsm.FuncAE(SAssign, Extra: String);
begin
if SAssign <> '' then
begin
if (GetSymbol(SAssign).Size = ss8) or (GetSymbol(SAssign).Size = ss16) then
begin
AsmMovImmAcc(0,ss8);
AddFixUp(GetSymbol(SAssign).Offset,ss16,ftDataAddress);
if Extra <> '' then
FuncExpr(SAssign,SAssign+Extra);
end
else
WriteMsg(InvalidSize);
end;
end;
procedure TAsm.FuncVar(Name, VType, Value: String);
var
ss: TSymbolSize;
Offset: Word;
begin
ss := ss8;
if LowerCase(VType) = 'byte' then ss := ss8
else if LowerCase(VType) = 'word' then ss := ss16
else if LowerCase(VType) = 'dword' then ss := ss32
else if LowerCase(Copy(VType,1,7)) = 'string[' then ss := ssString;
if ss <> ssString then
begin
if Value = '' then
AddOffset(AddVar('0',ss))
else
AddOffset(AddVar(Value,ss));
AddSymbol(Name,ss,stVariable);
ClearOffsets;
end
else
begin
if CurrSize = ss16 then
begin
Offset := AddDataBuffer(StrToInt(Copy(VType,8,Pos(']',VType)-8)));
AddOffset(Offset+2);
AddSymbol(Name,ss16,stString);
AddOffset(Offset);
AddSymbol(Name+'.size',ss16,stString);
end;
end;
end;
procedure TAsm.FuncBegin;
var
X: Array[0..3] of Byte;
begin
X[0] := $0E;
X[1] := $1F;
X[2] := $0E;
X[3] := $07;
AddBytes(X,4);
end;
procedure TAsm.FuncWriteLn;
begin
FuncWrite;
FuncNewLine;
end;
procedure TAsm.FuncWrite;
var
i: Integer;
begin
for i := 0 to Offsets.Count - 1 do
begin
AsmMovRegImm(rAH,9);
AsmMovRegImm(rDX,0);
AddFixup(Word(Offsets[i]),ss16,ftDataAddress);
AsmInt($21);
end;
ClearOffsets;
end;
procedure TAsm.FuncSetColor(Color: String; Len: String = '$07D0');
begin
AsmMovRegImm(rAH,9);
AsmMovRegImm(rAL,0);
AsmMovRegImm(rBH,0);
if Symbols.IndexOf(LowerCase(Color)) > -1 then
begin
AsmMovRegVal(rBL,0);
AddFixup(GetSymbol(Color).Offset,ss16,ftDataAddress);
end
else
AsmMovRegImm(rBL,GetNumber(Color));
AsmMovRegImm(rCX,GetNumber(Len));
AsmInt($10);
end;
procedure TAsm.FuncGetCursor(X, Y: String);
begin
AsmMovRegImm(rAH,3);
AsmXorReg(rBH);
AsmInt($10);
if (GetSymbol(X).Size = ss8) and (GetSymbol(Y).Size = ss8) then
begin
AsmMovValReg(rDL,0);
AddFixUp(GetSymbol(X).Offset, ss16, ftDataAddress);
AsmMovValReg(rDH,0);
AddFixUp(GetSymbol(Y).Offset, ss16, ftDataAddress);
end
else
WriteMsg(InvalidSize);
end;
procedure TAsm.FuncMoveCursor(X, Y: String);
begin
if Symbols.IndexOf(LowerCase(Y)) > -1 then
begin
AsmMovRegVal(rDH,0);
AddFixup(GetSymbol(Y).Offset,ss16,ftDataAddress);
end
else
AsmMovRegImm(rDH,GetNumber(Y));
if Symbols.IndexOf(LowerCase(X)) > -1 then
begin
AsmMovRegVal(rDL,0);
AddFixup(GetSymbol(X).Offset,ss16,ftDataAddress);
end
else
AsmMovRegImm(rDL,GetNumber(X));
AsmMovRegImm(rAH,2);
AsmXorReg(rBH);
AsmInt($10);
end;
procedure TAsm.FuncClearScreen;
begin
AsmMovRegImm(rAX,$0600);
AsmMovRegImm(rBH,7);
AsmMovRegImm(rCX,0);
AsmMovRegImm(rDX,$184F);
AsmInt($10);
end;
procedure TAsm.FuncNewLine;
begin
AsmMovRegImm(rAH,2);
AsmMovRegImm(rDL,13);
AsmInt($21);
AsmMovRegImm(rAH,2);
AsmMovRegImm(rDL,10);
AsmInt($21);
end;
procedure TAsm.FuncBeep;
begin
AsmMovRegImm(rAH,2);
AsmMovRegImm(rDL,7);
AsmInt($21);
end;
procedure TAsm.FuncRandom(SAssign, Extra: String);
var
X: Array[0..4] of Byte;
begin
X[0] := $E4;
X[1] := $40;
X[2] := $0F;
X[3] := $C0;
X[4] := $C0;
AddBytes(X,5);
FuncAE(SAssign,Extra);
end;
procedure TAsm.FuncSleep;
var
X: Array[0..3] of Byte;
begin
AsmXorReg(rAX);
AsmMovRegImm(rCX,$1000);
AsmAddAccImm(raAX,1);
X[0] := $83;
X[1] := $F8;
X[2] := $10;
AddBytes(X,3);
AsmJne($F8,ss8);
X[0] := $E2;
X[1] := $F6;
X[2] := $EB;
X[3] := $00;
AddBytes(X,4);
end;
procedure TAsm.FuncGetCount(X, Extra: String);
var
rr: TRegister;
begin
if CurrSize = ss16 then rr := rCX
else rr := rECX;
if Symbols.IndexOf(LowerCase(X)) > -1 then
begin
AsmMovValReg(rr,0);
AddFixUp(GetSymbol(X).Offset,CurrSize,ftDataAddress);
end
else
AsmMovRegImm(rr,GetNumber(X));
FuncExpr(X,X+Extra);
end;
procedure TAsm.FuncSetCount(X: String);
var
rr: TRegister;
begin
if CurrSize = ss16 then rr := rCX
else rr := rECX;
if Symbols.IndexOf(LowerCase(X)) > -1 then
begin
AsmMovRegVal(rr,0);
AddFixup(GetSymbol(X).Offset,CurrSize,ftDataAddress);
end
else
AsmMovRegImm(rr,GetNumber(X));
end;
procedure TAsm.FuncLoop(Lab: String);
var
X: Array[0..1] of Byte;
begin
X[0] := $E2;
X[1] := 0;
AddBytes(X,2);
AddFixup(Size(True),ss8,ftJump,CurrFunc+Lab);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -