⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 assembler.pas

📁 一个编译器源代码。用法看里面的“使用说明”
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  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 + -