How to clear a buffer in Assembly?

assemblyx86

I'm programming in assembler and I've created an auxiliary buffer to temporarily to store some characters and then write them to a file. The thing is that I have to use the auxiliary buffer several times so I need to clean/restore it and I don't know how to accomplish this.

I'm using i386 architecture with Linux.

PD: I forgot, this is how I have the buffer declared:

section .bss           
      auxBuffer resb 1000

Best Answer

You clear a buffer by writing to it.
Obviously a location in memory is never truly empty, so clearing a buffer effectively means fill it with zero's.
There is nothing stopping you from filling it with 0xCAFEBABE hex values, but zero's is the standard convention.

mov dword ptr [buffer],0
mov dword ptr [buffer+4],0
mov ...              +8],0
....

Obviously this is a silly way of clearing a buffer. If the buffer were 40,000 bytes you'd need 10,000 instructions; possible but wasteful.

Instead you write a loop and use a counter to keep track of what you've written so far.

mov ecx,10000        //10000 x 4 = 40.000 bytes
lea edx,[buffer]     //point edx to the start of the block to be cleared.  
xor eax,eax          //xor reg,reg is the same as mov reg,0, but faster.
@loop:
mov [edx+ecx*4],eax  //fill the buffer starting at the end.
dec ecx              //decrease the counter; also moving the destination.   
jnz @loop            //if ecx <> 0 (Non-Zero) then repeat.
ret                  //we are done, return.

ecx does double duty as a counter and as a pointer into the buffer.
Note that xor eax,eax is the standard way of setting a register to zero. It is both shorter than mov eax,0 and faster because the CPU is hard-wired to give the former instruction preferential treatment.
There is however an even shorter way of doing this.
x86 has so called string instructions that accept a rep (repeat) prefix.
If thus prefixed the instruction will run ecx times.

push edi           //on Windows edi is non-volatile (callee-save), so save it.
lea edi,[buffer]   //edi is the start of the buffer.
xor eax,eax        //fill the buffer with zeros.
mov ecx,10000      
rep stosd          //store string with 10000 dwords = 40000 bytes.
pop edi            //restore edi to its previous value.
ret                //return.

stosd (s̲t̲o̲re s̲tring per d̲word) uses edi as its D̲estination and ecx as the C̲ounter and eax as the source.
Note that stosd is a complex instruction. Modern x86 CPU's work faster with simple instructions and often an optimized (!) version of the second code snippet will work faster than a simple use of rep stosd.
rep stosd moves forward by default on Windows/Linux. You can set up the CPU to make it move backwards, but then you'd have to restore the direction setting afterwards.

Under windows eax, ecx and edx are volatile and can be changed at will. All other registers need to be preserved between calls.

Related Topic