Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
Solved

# Perform XOR operation on two binary blocks of memory ?

Posted on 2002-06-16
Medium Priority
789 Views
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
Question by:navy_seal
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 4
• 2
• 2
• +2

LVL 11

Assisted Solution

robert_marquardt earned 588 total points
ID: 7083037
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

LVL 7

Accepted Solution

Cynna earned 592 total points
ID: 7083308
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

LVL 11

Expert Comment

ID: 7083333
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

LVL 7

Expert Comment

ID: 7083336
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

LVL 7

Expert Comment

ID: 7083340
OOPS,
Sorry for double post.

robert_marquardt, yes it is.
0

Author Comment

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

Author Comment

ID: 7084913
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

LVL 7

Expert Comment

ID: 7086284
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

Expert Comment

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

LVL 5

Expert Comment

ID: 9453405
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

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi. Â  One of the more specific questions is how to show progress of the thread. Â  Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to theâ€¦