Press enter to see results or esc to cancel.

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;