Processing Assembler Instructions
This procedure processes one assembler instruction. It resets data used for instruction processing, reads next assembler token, checks for label and processes prefix instructions (if present). Then it checks and processes assembler directive (DB
, DW
or DD
) or assembler instruction parameters. Finally it generates intermediate code for assembler instruction.
Procedure ProcessAssemblerInstruction (Var CharPtr: PChar; LineCharCounter: Byte; AsmFlags: Word; ProcIdDataOffset: Word);
Procedure ResetAsmStatementData;
begin
LineCharacterCounter := LineCharCounter;
Flags := AsmFlags;
MaxAsmStackTop := SPtr - $400;
AsmCharacterPointer := CharPtr;
AsmSourceErrorPosition := nil;
AsmIdentifierAdditionalData := nil;
PrefixOpcode [0] := 0;
SizeOfAsmIntermediateCodeRecords := 0;
LastOpCodeBeforeDataValid := False;
end;
begin
ResetAsmStatementData;
BeforeOperands := True;
GetNextAsmToken;
AsmSourceErrorPosition := AsmCharacterPointer;
CheckForAsmLabel;
ProcessPrefixes;
BeforeOperands := False;
If not ProcessAssemblerDirective then
begin
If not CheckAndGetNextAsmToken (AsmToken_Semicolon) then
begin
ExpectAsmTokenAndGetNext (AsmToken_Instruction);
ProcessInstructionExpresions;
GenerateInstructionOpcodes;
end else GeneratePrefixOpCodes;
end;
GenerateAsmStatementIntermediateCode;
CharPtr := AsmCharacterPointer;
end;
This procedure checks for valid assembler label and creates intermediate code label record.
Procedure CheckForAsmLabel;
Var LabelIdentifierData: PLabelIdentifierData;
IdToken: TToken;
LabelIdentifier: Word;
IntermediateCodeRecord: PIntermediateCodeRecord;
begin
If GetFirstNonBlankCharacter = ':' then
begin
CopyStringToCurrentIdentifier (AsmTokenString);
If not IsValidAsmIdentifier (nil, IdToken, Pointer (LabelIdentifierData), LabelIdentifier) or
(IdToken <> Token_LabelIdentifier) then
AsmError (UnknownIdentifier);
If Ofs (LabelIdentifierData^) < Ofs (CurrentScopeIdentifierTableAddress^) then AsmError (LabelNotWithinCurrentBlock);
If LabelIdentifierData^.LabelRecordOffset <> 0 then AsmError (LabelAlreadyDefined);
IntermediateCodeRecord := IncreaseSymbolTable (stIntermediateCode, 3);
IntermediateCodeRecord^.RecordType := icLabel;
LabelIdentifierData^.LabelRecordOffset := Ofs (IntermediateCodeRecord^) + 1;
GetNextAsmToken;
ExpectAsmTokenAndGetNext (AsmToken_Colon);
end;
end;
This procedure processes prefixes in instruction (LOCK
, REP
, REPE
, REPZ
, REPNE
, REPNZ
, SEGES
, SEGCS
, SEGSS
, SEGDS
) and stores its opcodes to PrefixOpcode
buffer.
Procedure ProcessPrefixes;
Var Counter: Byte;
begin
While AsmToken = AsmToken_Instruction do
begin
If InstructionData^.B0 <> $AE then Exit;
Counter := 0;
While (PrefixOpcode [Counter] <> 0) and (Counter < 4) do Inc (Counter);
PrefixOpcode [Counter] := InstructionData^.Data [0];
PrefixOpcode [Counter + 1] := 0;
GetNextAsmToken;
end;
end;