Trying to understand Assembler, I see many possibilities which lead to the same result. e.g.
1.
INVOKE function...
mov function_hnd,eax
or
INVOKE function...
push eax
pop function_hnd
2.
mov esi,offset buffer1
mov edi,offset buffer2
or
lea esi,buffer1
lea edi,buffer2
3.
mov ecx,value
copyb:
loadsb
stosb
loop copyb
or
mov ecx,value
copyb:
mov al,[esi]
mov [edi],al
inc esi
inc edi
loop copyb
What are the (dis)advantages of the 3 examples ?
1. in this case, there is no advantage to push/pop - it is slower
there are cases where push/pop is used because direct memory-to-memory moves are not allowed
push dwVar1
pop dwVar2
2. the offset method is used for global buffers
the LEA method is used primarily for local buffers (or when the base address is in register)
mov esi,offset buffer1 might look like this when disassembled, assuming buffer1 is global (in data section)
mov esi,00403434h
however, if buffer1 is local, it's on the stack and referenced by EBP
offset won't work because the address is not known at assemble-time
lea esi,[ebp-12]
LEA calculates the value of (ebp-12) and places it in esi
LEA might be used for an array index if the base address is in a register - like in a loop, for example
lea edx,[esi+4*ecx]
LEA is sometimes used to perform math, even though it's intended for addressing
lea ecx,[4*ecx+ecx]
multiplies ECX x 5
3. LODSB and STOSB are a bit slower
however, there are times when they still might be used
for example, parsing a command line is only done once - and not many characters to process
so, speed isn't critical
the code is small, because LODSB and STOSB are single-byte op-codes
similar for LOOP - slower, but might be used if speed isn't important
Hi,
For the most part, for what you have shown, I see it as a matter
of one's preference. You use what you are used to, or what you
like. You should at least assemble the code and look at a listing to
see what opcodes are actually generated.
That said, and without looking at a listing, I prefer the first in your
example 1. One instruction versus two and one memory reference
versus two. I prefer the first again in your example 2. I have not
used LEA enough to know how it differs from the moves in this
simple case. The results are identical. In your third example I would
normally use the first over the second. Mainly due to less typing,
and thus less room for error. In fact for that example I would use:
MOV ECX,[Value]
REP MOVSB
Again personal preference.
Note that LEA has additional uses and can do things other than a
simple move offset. And the third example can have variants that
do things that will make one usable while the other is not. Such as:
MOV AH,[High]
LODSB ; Load a byte.
STOSW ; Store a word.
LOOP ...
Or incrementing ESI and decrementing EDI to reverse a string.
HTH,
Steve N.
P.S.
Dave beat me while I was typing this. So, duplicate info.
SRN