Improve company productivity with a Business Account.Sign Up

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

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
Asked:
navy_seal
  • 4
  • 2
  • 2
  • +2
2 Solutions
 
robert_marquardtCommented:
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
 
CynnaCommented:
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
  add esi,ecx
  add edx,ecx
  add edi,ecx
  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
 
robert_marquardtCommented:
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
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
CynnaCommented:
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
  add esi,ecx
  add edx,ecx
  add edi,ecx
  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
 
CynnaCommented:
OOPS,
Sorry for double post.

robert_marquardt, yes it is.
0
 
navy_sealAuthor Commented:
Thanks guys,ill try it out, which solution is faster will get the points :-)
0
 
navy_sealAuthor 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:

http://groups.google.com/groups?hl=en&lr=&frame=right&th=a0343ed619e02a7a&seekm=7nbvmi%24qtf1%40forums.borland.com#s

they are a bit different
0
 
CynnaCommented:
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
 
CleanupPingCommented:
navy_seal:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0
 
Lukasz LachCommented:
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 leave any comments here within 7 days.

-- 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.

Join & Write a Comment

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 4
  • 2
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now