我需要对文件中的单词进行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.