📄 disasm.pas
字号:
1: Result := Result + '[bx+di';
2: Result := Result + '[bp+si';
3: Result := Result + '[bp+di';
4: Result := Result + '[si';
5: Result := Result + '[di';
6: Result := Result + '[bp';
7: Result := Result + '[bx';
end
else
begin
Case RM of
0: Result := Result + '[eax';
1: Result := Result + '[ecx';
2: Result := Result + '[edx';
3: Result := Result + '[ebx';
4: Result := Result + ReadSib;
5: Result := Result + '[ebp';
6: Result := Result + '[esi';
7: Result := Result + '[edi';
end;
if RM <> 4 then
begin
Ref.ARegister1 := TRegister(RM);
Ref.MultiplyReg1 := 1;
end;
end;
Case AMod of
0: Result := Result + ']';
1: begin
I := ShortInt(ReadByte);
Result := Result + SignedIntToHex(I, 2) + ']';
Inc(Ref.Immidiate, I);
end;
2: Result := Result + '+' + GetRefAddress + ']';
end;
if Assigned(OnRef) then OnRef(Param, Ref, OperandSize, Result);
end;
var
I: Integer;
begin
Result := '';
Case OperandType of
'a': if DeffOperandSize = 2 then OperandSize := 4
else OperandSize := 8;
'b': OperandSize := 1;
'c': if DeffOperandSize = 2 then OperandSize := 1
else OperandSize := 2;
'd': OperandSize := 4;
'p': OperandSize := AddressSize + 2;
'q': OperandSize := 8;
's': OperandSize := 6;
'v': OperandSize := DeffOperandSize;
'w': OperandSize := 2;
't': OperandSize := 10;
end;
Case AddrMethod of
'A': if OperandType = 'p' then
begin
if SegOverride then Result := SegName + ':'
else Result := '';
if AddressSize = 4 then Result := Result + GetRefAddress
else Result := Result + '$' + IntToHex(ReadWord, 2);
end
else
Raise EDisAsmError.Create(ERROR_INVALID_OPERAND);
'C': if OperandType = 'd' then
begin
Result := Format('C%d', [(ModRM and ModRMReg) div 8]);
MustHaveSize := False;
end
else
Raise EDisAsmError.Create(ERROR_INVALID_OPERAND);
'D': if OperandType = 'd' then
begin
Result := Format('D%d', [(ModRM and ModRMReg) div 8]);
MustHaveSize := False;
end
else
Raise EDisAsmError.Create(ERROR_INVALID_OPERAND);
'E', 'M', 'R': Result := GetEffectiveAddress(False);
'F': ;
'G': begin
Result := GetRegName((ModRM and ModRMReg) div 8);
MustHaveSize := False;
end;
'H': begin
Case OperandSize of
1: I := ShortInt(ReadByte);
2: I := SmallInt(ReadWord);
4: I := Integer(ReadDWord);
else Raise EDisAsmError.Create(ERROR_INVALID_OPERAND_SIZE);
end;
Result := SignedIntToHex(I, OperandSize * 2);
if Assigned(OnImmidiateData) then
OnImmidiateData(Param, Address + Size - OperandSize, OperandSize, True, Result);
Result := '^' + Chr(Length(Result)) + Result;
end;
'I': begin
Result := '';
For I := OperandSize downto 1 do
Result := IntToHex(ReadByte, 2) + Result;
Result := '$' + Result;
if Assigned(OnImmidiateData) then
OnImmidiateData(Param, Address + Size - OperandSize, OperandSize, False, Result);
Result := '^' + Chr(Length(Result)) + Result;
end;
'J': begin
Case OperandSize of
1: I := ShortInt(ReadByte);
2: I := SmallInt(ReadWord);
4: I := Integer(ReadDWord);
else Raise EDisAsmError.Create(ERROR_INVALID_OPERAND_SIZE);
end;
Result := SignedIntToHex(I, OperandSize * 2);
if (EnhOperandType = 'j') and Assigned(OnJumpInstr) then
begin
OnJumpInstr(Param, Address + Size - OperandSize, Address + Size + I, Result);
Result := '^' + Chr(Length(Result)) + Result;
end;
if (EnhOperandType = 'c') and Assigned(OnCallInstr) then
begin
OnCallInstr(Param, Address + Size - OperandSize, Address + Size + I, Result);
Result := '^' + Chr(Length(Result)) + Result;
end;
end;
'O': if AddressSize = 2 then
Result := '%s' + Chr(OperandSize) + '[$' + IntToHex(ReadWord, 4) + ']'
else
begin
Result := '%s' + Chr(OperandSize) + '[' + GetRefAddress + ']';
if Assigned(OnRef) then
OnRef(Param, Ref, OperandSize, Result);
end;
'P': begin
Result := Format('MM%d', [(ModRM and ModRMReg) div 8]);
MustHaveSize := False;
end;
'Q': if (ModRM and ModRMMod) = $C0 then
begin
Result := Format('MM%d', [(ModRM and ModRMReg) div 8]);
MustHaveSize := False;
end
else
Result := GetEffectiveAddress(False);
'S': Case (ModRM and ModRMReg) div 8 of
0: Result := 'es';
1: Result := 'cs';
2: Result := 'ss';
3: Result := 'ds';
4: Result := 'fs';
5: Result := 'gs';
end;
'T': begin
Result := Format('T%d', [(ModRM and ModRMReg) div 8]);
MustHaveSize := False;
end;
end;
end;
function Replacer(FirstChar, SecondChar: Char): String;
begin
Case FirstChar of
'c': if SecondChar = '2' then
Result := TwoByteOpCodes[Char(ReadByte)]
else
if ModRm <= $BF then
Result := FloatingPointOpCodes[SecondChar, (ModRM and ModRMReg) div 8 + $B8]
else
Result := FloatingPointOpCodes[SecondChar, ModRm];
'e': if DeffOperandSize = 4 then Result := 'e' + SecondChar
else Result := SecondChar;
'p': begin
SegOverride := True;
SegName := SecondChar + 's';
Result := OneByteOpCodes[Char(ReadByte)];
end;
's': begin
Case SecondChar of
'o': DeffOperandSize := 2;
'a': AddressSize := 2;
end;
Result := OneByteOpCodes[Char(ReadByte)];
end;
'o': if DeffOperandSize = 4 then
Case SecondChar of
'2': Result := 'w';
'4': Result := 'd';
'8': Result := 'q';
end
else
Case SecondChar of
'2': Result := 'b';
'4': Result := 'w';
'8': Result := 'd';
end;
'm': begin
Result := '';
MustHaveSize := True;
end;
'g': Result := GroupsOpCodes[SecondChar, (ModRM and ModRMReg) div 8];
'h': Result := GroupsOperands[SecondChar, (ModRM and ModRMReg) div 8];
end;
end;
var
I, J, K, SPos, EPos : Integer;
begin
DeffOperandSize := 4;
AddressSize := 4;
SegOverride := False;
Size := 0;
XHasSib := False;
XHasModRM := False;
MustHaveSize := True;
Ref.MultiplyReg1 := 0;
Ref.MultiplyReg2 := 0;
Ref.Immidiate := nil;
Result := OneByteOpCodes[Char(ReadByte)];
I := 1;
While I < Length(Result) -1 do
Case Result[I] of
'#': begin
Insert(Operand(Result[I + 1], Result[I + 2], Result[I + 3]), Result, I + 4);
Delete(Result, I, 4);
end;
'@': begin
Insert(Replacer(Result[I + 1], Result[I + 2]), Result, I + 3);
Delete(Result, I, 3);
end;
'^': begin
J := I;
Inc(I, Ord(Result[I + 1]));
Delete(Result, J, 2);
end;
else Inc(I);
end;
I := 1;
While I < Length(Result) - 1 do
Case Result[I] of
'%': begin
Case Result[I + 1] of
's': if MustHaveSize then
Case Result[I + 2] of
#1: Insert('byte ptr ', Result, I + 3);
#2: Insert('word ptr ', Result, I + 3);
#4: Insert('dword ptr ', Result, I + 3);
#6: ;
#8: Insert('qword ptr ', Result, I + 3);
#10: Insert('tbyte ptr ', Result, I + 3);
else Insert('???? ptr ', Result, I + 3);
end;
'c': begin
Insert(' //', Result, I + 3);
For J := Size - 1 downto 1 do
Insert(', $' + IntToHex(PByte(Address + J)^, 2), Result, I + 3);
Insert('DB $' + IntToHex(PByte(Address)^, 2), Result, I + 3);
end;
end;
Delete(Result, I, 3);
end;
else Inc(I);
end;
SPos := Pos('[$', Result);
if SPos <> 0 then
begin
EPos := Pos(']', Result);
if EPos - SPos < 10 then
For K := EPos - SPos to 9 do Insert('0', Result, SPos + 2);
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -