Lazarus Pascal中的Xor Inline ASM无法访问 - 访问错误

时间:2015-02-24 13:35:51

标签: asmx pascal lazarus

我需要对文件中的单词进行xor计算校验和。我拿了一些未注释的在线代码并将添加更改为xor(最少的其他更改)。我如何让xor工作?

请参阅标有'***更改为xor'的行。我认为改变'添加'到'xor'应该有效。

代码附加到带有单个按钮的表单。我添加了一个WriteDemoFile过程来尝试使这个示例自包含,但它也有问题。

感谢潜伏者,我坚持了一点,我可以看到它不只是添加/ xor线。我主要得到“访问违规”。我禁用WriteDemofile并使用ShowMessage(IntToStr(GetCheckSum('c:\ Autoexec.bat')));时出错。如果它编译它返回一个带有25964的MessageBox - 与add或xor相同的结果。通过第三次运行,如果它编译Access违规错误再次发生。我想这是一个内存寻址问题。如何加载asm变量? 'xor eax,[edi + 2 * ecx]'发生了什么?

unit Unit1;
// Free Pascal Lazarus Version#: 1.2.6
{$mode objfpc}{$H+}
{$asmmode intel}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type
  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

  procedure WriteDemoFile;
  function GetCheckSum(FileName: string): WORD;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure WriteDemoFile;

var
  Buffer: array[0..85] of byte = (
  $01, $00, $00, $00, $01, $00, $00, $00, $74, $65, $73, $74, $00, $00, $00, $00,
  $00, $74, $78, $74, $00, $00, $00, $00, $40, $00, $00, $00, $0B, $00, $00, $00,
  $34, $11, $4D, $41, $47, $45, $4C, $4C, $41, $4E, $00, $00, $00, $00, $00, $00,
  $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
  $48, $65, $6C, $6C, $6F, $20, $57, $6F, $72, $6C, $64, $4D, $41, $47, $45, $4C,
  $4C, $41, $4E, $00, $0B, $2B
  );
  FileStream1: TFileStream;

begin
  with FileStream1.Create('TestArchive.Imi', fmCreate) do
  try
    FileStream1.Write(Buffer[0], SizeOf(Buffer)-1);
  finally
    FileStream1.Free;
  end;
end;



function GetCheckSum(FileName: string): WORD;
// http://www.swissdelphicenter.ch/en/showcode.php?id=324
var
  F: file of WORD;
  P: Pointer;
  Fsize: WORD;
  Buffer: array [0..500] of WORD;
begin
  FileMode := 0;                        // Read only
  AssignFile(F, FileName);              // Use FileName variable
  Reset(F);                             // Open file (read only)
  Seek(F, FileSize(F) div 2);           // Calculate numer of words
  Fsize := FileSize(F) - 1 - FilePos(F);// Calculate fsize from current position
  if Fsize > 500 then Fsize := 500;     // Limit fsize to 500
  BlockRead(F, Buffer, Fsize);          // Read file into buffer fsize length
  Close(F);                             // Close file
  P := @Buffer;                         // Pointer to address of buffer
  asm
     xor eax, eax                // initialise eax as nul for checksum variable
     xor ecx, ecx                // initialise ecx as nul for position variable
     mov edi , p                 // move ptr to edi
     @again:                     // start of again routine
       add eax, [edi + 2*ecx]    // add 2bytes at new position *** Change to xor
       inc ecx                   // next record (2 bytes)
       cmp ecx, fsize            // compare position variable with file size
     jl @again                   // if previous calculation is less jump to again
     mov @result, eax            // move eax variable to result address
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  WriteDemoFile;
  ShowMessage(IntToStr(GetCheckSum('TestArchive.Imi')));
end;

end. 

0 个答案:

没有答案