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

📄 simx86p.pas

📁 汇编编程艺术
💻 PAS
📖 第 1 页 / 共 4 页
字号:

end;

Procedure SetGet(Pat:TPatPtr);
begin

     HasOpcode := True;
     Opcode := $0;
     HasReg := true;
     RegCode := $0;
     HasOperand := true;
     OperandCode := $6;

end;




Procedure SetAX(Pat:TPatPtr);
begin

     HasReg := True;
     Regcode := $00;

end;

Procedure SetBX(Pat:TPatPtr);
begin

     HasReg := True;
     Regcode := $08;

end;

Procedure SetCX(Pat:TPatPtr);
begin

     HasReg := True;
     Regcode := $10;

end;

Procedure SetDX(Pat:TPatPtr);
begin

     HasReg := True;
     Regcode := $18;

end;




Procedure SetAX2(Pat:TPatPtr);
begin

     HasOperand := True;
     Operandcode := $00;

end;

Procedure SetBX2(Pat:TPatPtr);
begin

     HasOperand := True;
     Operandcode := $1;

end;

Procedure SetCX2(Pat:TPatPtr);
begin

     HasOperand := True;
     Operandcode := $2;

end;

Procedure SetDX2(Pat:TPatPtr);
begin

     HasOperand := True;
     Operandcode := $3;

end;

Procedure SetBXInd(Pat:TPatPtr);
begin

     HasOperand := True;
     Operandcode := $4;

end;

Procedure SetBXIndx(Pat:TPatPtr);
begin

     HasOperand := True;
     Operandcode := $5;

end;

Procedure SetABS(Pat:TPatPtr);
begin

     HasOperand := True;
     Operandcode := $6;

end;

Procedure SetImm(Pat:TPatPtr);
begin

     HasOperand := True;
     Operandcode := $7;

end;

{$F-}













{ Whenever the user presses the CLEAR button on the memory page, the	}
{ following method zeros out memory.					}

procedure TSIMx86Form.ClrMemBtnClick(Sender: TObject);
var i:word;
begin

    AdrsEntry.Text := '0000';
    AdrsEntryChange(AdrsEntry);

    { Zero out memory }

    for i := 0 to $ffef do
    	Memory^[i] := 0;

    MemAdrs := 0;
    Adrs := 0;

end;




{ Handle the NEW, OPEN, SAVE, SAVEAS, Print, and QUIT entries in the File Menu }

procedure TSIMx86Form.QuitClick(Sender: TObject);
begin

	Application.Terminate;

end;



procedure TSIMx86Form.PrintMenuItemClick(Sender: TObject);
var
    i: integer;
    f: TextFile;

begin

    if PrintDialog.Execute then begin

      if (SIMx86Pages.PageIndex = 0) then begin

    	AssignPrn(f);
        Rewrite(f);

	for i := 0 to SourceCode.Lines.Count-1 do
        	writeln(f,SourceCode.Lines[i]);

        CloseFile(f);

      end
      else Print;

    end;

end;



procedure TSIMx86Form.NewClick(Sender: TObject);
begin

    SourceCode.Clear;
    Filename := '';

end;

procedure TSIMx86Form.OpenClick(Sender: TObject);
var
    name:string;

begin

    if OpenDialog.Execute then
    begin

        SourceCode.Lines.LoadFromFile(OpenDialog.Filename);
        Filename := OpenDialog.Filename;

    end;

end;

procedure TSIMx86Form.SaveAsClick(Sender: TObject);
begin

    if SaveDialog.Execute then
    begin

    	FileName := SaveDialog.Filename;
    	SourceCode.Lines.SaveToFile(SaveDialog.Filename);

    end;

end;

procedure TSIMx86Form.SaveClick(Sender: TObject);
begin

    if (Filename = '') then
    begin
    	if SaveDialog.Execute then
           Filename := SaveDialog.Filename;

    end;

    if (Filename <> '') then
    begin

    	SourceCode.Lines.SaveToFile(Filename);

    end;



end;




{ Handle Cut, Copy, Paste, Delete, and SelectAll in the Edit Menu }

procedure TSIMx86Form.CutClick(Sender: TObject);
begin

    SourceCode.CutToClipBoard;

end;

procedure TSIMx86Form.CopyClick(Sender: TObject);
begin

	SourceCode.CopyToClipBoard;

end;

procedure TSIMx86Form.PasteClick(Sender: TObject);
begin

    SourceCode.PasteFromClipBoard;

end;

procedure TSIMx86Form.DeleteClick(Sender: TObject);
begin

    SourceCode.ClearSelection;

end;

procedure TSIMx86Form.SelectAllClick(Sender: TObject);
begin

    SourceCode.SelectAll;
    SourceCode.Repaint;

end;




{ Whenver a value changes in one of the memory data entry boxes, this	}
{ method converts the data data to hexadecimal and stores the resulting	}
{ value away into memory.						}

procedure TSIMx86Form.HexChange(Sender: TObject);
var Cell:TEdit;
    HexVal:byte;
    i,
    j,
    index:word;

begin

    Cell := TEdit(Sender);
    CheckHex(Cell);

    { Only store the data if there is no error.  If there is an error,	}
    { the memory cell's background color will be red.			}

    if (Cell.Color <> clRed) then
    begin

        for i := 0 to 7 do
            for j := 0 to 7 do
            	if (Sender = MemEntry[i,j]) then
                    WriteMem(MemAdrs+ i*8+j, HexToWord(Cell.Text));

    end;

end;




{ AdrsEntryChange-	This method executes whenever the user changes	}
{			a value in the address box on the Memory page.	}
{			This method converts the string representation	}
{			of the address to binary, updates all the labels}
{			on the screen, and then updates all the memory	}
{			entry boxes on the page.			}

procedure TSIMx86Form.AdrsEntryChange(Sender: TObject);
var
    HexVal:	word;
    index:	word;
    i,j:	word;

begin

    CheckHex(TEdit(Sender));

    { If the entry is invalid, don't do anything.	}

    if (AdrsEntry.Color <> clRed) then begin

    	HexVal := HexToWord(AdrsEntry.Text);

        { Update the labels on the page.  Make sure the values we use	}
        { are all even multiples of eight.				}

        MemAdrs := HexVal and $FFF8;
        Lbl8.Caption  := IntToHex(MemAdrs+8,4);
        Lbl10.Caption := IntToHex(MemAdrs+16,4);
        Lbl18.Caption := IntToHex(MemAdrs+24,4);
        Lbl20.Caption := IntToHex(MemAdrs+32,4);
        Lbl28.Caption := IntToHex(MemAdrs+40,4);
        Lbl30.Caption := IntToHex(MemAdrs+48,4);
        Lbl38.Caption := IntToHex(MemAdrs+56,4);

        { Update the data in the entry cells on the page.  If	}
        { the location we access is before the starting address	}
        { (because we may have rounded it down to the previous	}
        {  eight-byte boundary), then turn the background color	}
        { gray.							}

        for i := 0 to 7 do
            for j := 0 to 7 do
            begin

            	index := MemAdrs + i*8 + j;
                MemEntry[i,j].Text := IntToHex(ReadMem(index),2);
                if ((index < HexVal) or (Index >=$fff0)) then
                begin

                	MemEntry[i,j].Color := clSilver;
                        MemEntry[i,j].Enabled := false;

                end
                else begin

                	MemEntry[i,j].Color := clWindow;
                        MemEntry[i,j].Enabled := true;

                end;

            end;


    end;

end;



procedure TSIMx86Form.StartAdrsChange(Sender: TObject);
begin

    CheckHex(StartAdrs);

end;



{ Do the assembly here }

procedure TSIMx86Form.ASMbtnClick(Sender: TObject);
var
   i:word;
   ch:char;
   line:array[0..255] of char;
   s:PChar;

begin

     { Initialize the symbol table }

     for ch := 'A' to 'Z' do
     begin

          SymTbl[ch].Value := 0;
          SymTbl[ch].Defined := false;

     end;

     { Compute the address of the first instruction }

     if (StartAdrs.Color <> clRed) then
     	Adrs := HexToWord(StartAdrs.Text)
     else Adrs := 0;

     { Assemble each line of source code }

     for LineNum := 0 to SourceCode.Lines.Count-1 do begin

         s := strPCopy(line, SourceCode.Lines[LineNum]);
         NoError := true;
         HasValue := false;
         HasOpcode := false;
         HasReg := false;
         HasOperand := false;
         if (not Match(stmt, s)) then
         begin

           if (NoError) then
              ErrorMsg('Syntax Error',
                   SourceCode.lines[LineNum]);
           if (AbortAsm) then break;

         end
         else begin


             { Okay, the instruction is syntactically cor-	}
             { rect.  Now emit the opcode and any necessary	}
             { operands to memory.				}

             Val := 0;
             if (HasOpcode) then  {It's not a blank line }
             begin

             	Val := Val or Opcode;
                if (HasReg) then Val := Val or Regcode;
                if (HasOperand) then Val := Val or OperandCode;
                WriteMem(Adrs, Val);
                inc(adrs);

                if (HasValue) then begin {It has an operand }

                	WriteMem(Adrs, OperandValue and $ff);
                        inc(adrs);
                        WriteMem(Adrs, OperandValue shr 8);
                        inc (adrs);

                end;

             end;

         end;

     end;

     { Check to see if there were any undefined symbols }

     for ch := 'A' to 'Z' do
     	if (not SymTbl[ch].Defined)then
           if (SymTbl[ch].Value <> 0) then
              ErrorMsg('Undefined Symbol', ch);

end;



{ Given an opcode, the following function returns the size of	}
{ an instruction (in bytes).  This is either one or three.	}

function InstrSz(opcode:word):integer;
begin

	if (opcode > $1f) or ((opcode and $18) = $10) then
        	if (opcode and $7) >= 5 then Result := 3
                else Result := 1
        else if (opcode and $18) = $8 then Result := 3
        else Result := 1;

end;


{ Given an opcode, the following function returns a string that	}
{ corresponds to the instruction's mnemonic.			}

function Instr(opcode:word):string;
begin

        Result := '????';
	case (opcode shr 5) of

            1: Result := 'or  ';
            2: Result := 'and ';
            3: Result := 'cmp ';
            4: Result := 'sub ';
            5: Result := 'add ';
            6: Result := 'mov ';
            7: Result := 'mov ';
            0: begin

            	if (opcode and $18) = $10 then
                   Result := 'not '
                else if (opcode and $18) = $8 then
                begin

                    case opcode and $7 of

                    0: Result := 'je  ';
                    1: Result := 'jne ';
                    2: Result := 'jb  ';
                    3: Result := 'jbe ';
                    4: Result := 'ja  ';
                    5: Result := 'jae ';
                    6: Result := 'jmp ';
                    7: Result := '****';
                    end;

                end
                else if (opcode and $18) = $18 then Result := '****'
                else begin

                    case (opcode and $7) of
                    0: Result := '****';
                    1: Result := '****';
                    2: Result := '****';
                    3: Result := 'brk ';
                    4: Result := 'iret';
                    5: Result := 'halt';
                    6: Result := 'get ';
                    7: Result := 'put ';
                    end;
                end;
               end;
        end;

end;



{ Given an opcode and an option operand, the following function returns	}
{ a string that represents the reg/memory addressing mode.		}

function AdrsMode(opcode, operand:word):string;

	function MemMode(opcode,operand:word):string;
        begin

        	case opcode and $7 of
                0: Result := 'ax';
                1: Result := 'bx';
                2: Result := 'cx';
                3: Result := 'dx';
                4: Result := '[bx]';
                5: Result := '['+IntToHex(operand,4)+'+bx]';
                6: Result := '['+IntToHex(operand,4)+']';
                7: Result := IntToHex(operand,4);
                end;
        end;

begin

	if (opcode > $1f) or (opcode and $18 = $10) then
        	Result := MemMode(opcode,operand)
        else if (opcode and $18 = $8) then
        	Result := MemMode($27, operand)
        else	Result := '';

end;





{ The following function disassembles a single instruction at the given	}
{ address and returns the string representation of that instruction.	}

function Disassemble2(var CodeAdrs:word):string;
var 	Size,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -