x
• Status: Solved
• Priority: Medium
• Security: Public
• Views: 827

# Perform XOR operation on two binary blocks of memory ?

Hello Experts,

How to perform a XOR operation on two binary blocks of memory?

Thanks!

P.S: The two memory blocks have the same size(about 2mb) but the data inside is different
0
navy_seal
• 4
• 2
• 2
• +2
2 Solutions

Commented:
As simple as a for loop.

for I := 0 to SizeOf(Buffer1) do
Buffer1[I] := Buffer1[I] xor Buffer2[I];

This may be a bit inefficient if the buffer elements are Chars.
Try using Cardinals as buffer elements.
0

Commented:
navy_seal,

I dig up somebodys old code. It's quite fast:

procedure MemBlockXOR(const Source1, Source2, Destination: Pointer;
Blocksize: Integer); assembler;
asm
push edi
push esi
push ebx
mov esi,eax
mov edi,ecx
mov ecx,Blocksize;
mov eax,[esi]
and eax,[edx]
mov [edi],eax
mov eax,[esi+4]
and eax,[edx+4]
mov [edi+4],eax
shr ecx,3
test ecx,ecx
jz @@ending
neg ecx
@@doit:
mov eax,[esi+ecx*8]
mov ebx,[esi+ecx*8+4]
xor eax,[edx+ecx*8]
xor ebx,[edx+ecx*8+4]
mov [edi+ecx*8],eax
mov [edi+ecx*8+4],ebx
inc ecx
jnz @@doit
@@ending:
pop ebx
pop esi
pop edi
end;

I tested it with:

procedure TForm1.Button1Click(Sender: TObject);
var Block1, Block2, Block3: Pointer;
Size: Integer;
t0: DWord;
begin
try
// Must be multiple of 4-bytes:
Size:=16*1024*1024; //16Mb
GetMem(Block1, Size);
GetMem(Block2, Size);
GetMem(Block3, Size);
FillMemory(Block1, Size, 2);
FillMemory(Block2, Size, 3);
t0:=GetTickCount;
MemBlockXOR(Block1, Block2, Block3, Size);
Button1.Caption:=IntToStr(GetTickCount-t0)+' ms';
finally
FreeMem(Block1);
FreeMem(Block2);
FreeMem(Block3);
end;
end;

On my Athlon XP 1.4Ghz it XORed those 16Mb in 0.13 sec.

0

Commented:
I would guess that Delphi generates similar code.
The assembler code does a loop unroll to handle 2 DWORDs at once. That makes it "a multiple of 8-bytes".
The speed factor against my loop should be around 2x.
0

Commented:
navy_seal,

I dig up somebodys old code. It's quite fast:

procedure MemBlockXOR(const Source1, Source2, Destination: Pointer;
Blocksize: Integer); assembler;
asm
push edi
push esi
push ebx
mov esi,eax
mov edi,ecx
mov ecx,Blocksize;
mov eax,[esi]
and eax,[edx]
mov [edi],eax
mov eax,[esi+4]
and eax,[edx+4]
mov [edi+4],eax
shr ecx,3
test ecx,ecx
jz @@ending
neg ecx
@@doit:
mov eax,[esi+ecx*8]
mov ebx,[esi+ecx*8+4]
xor eax,[edx+ecx*8]
xor ebx,[edx+ecx*8+4]
mov [edi+ecx*8],eax
mov [edi+ecx*8+4],ebx
inc ecx
jnz @@doit
@@ending:
pop ebx
pop esi
pop edi
end;

I tested it with:

procedure TForm1.Button1Click(Sender: TObject);
var Block1, Block2, Block3: Pointer;
Size: Integer;
t0: DWord;
begin
try
// Must be multiple of 4-bytes:
Size:=16*1024*1024; //16Mb
GetMem(Block1, Size);
GetMem(Block2, Size);
GetMem(Block3, Size);
FillMemory(Block1, Size, 2);
FillMemory(Block2, Size, 3);
t0:=GetTickCount;
MemBlockXOR(Block1, Block2, Block3, Size);
Button1.Caption:=IntToStr(GetTickCount-t0)+' ms';
finally
FreeMem(Block1);
FreeMem(Block2);
FreeMem(Block3);
end;
end;

On my Athlon XP 1.4Ghz it XORed those 16Mb in 0.13 sec.

0

Commented:
OOPS,
Sorry for double post.

robert_marquardt, yes it is.
0

Author Commented:
Thanks guys,ill try it out, which solution is faster will get the points :-)
0

Author Commented:
sorry Cynna ,but I found the same code that you gave me 2 days a go, so I would give points only If you could give code that is faster

here is where I found it:

they are a bit different
0

Commented:
navy_seal,

Yes, its quite possible I saved it from Google some time ago. Anyway, as far as I can see, this code couldn't be turned up much faster, so you can count me out of the race...
0

Commented:
navy_seal:
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0

Commented:
navy_seal,
No comment has been added lately (17 days), so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area for this question:

RECOMMENDATION: split points between robert_marquardt http:#7083333 and Cynna http:#7083336

-- Please DO NOT accept this comment as an answer ! --

Thanks,

anAKiN
EE Cleanup Volunteer
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.