• Welcome to Valhalla Legends Archive.
 

Using return values

Started by iago, May 03, 2003, 03:00 PM

Previous topic - Next topic

iago

Fairly often, I notice things like this in compiled code:
.text:19016F85 43C                 push    ecx             ; lpLibFileName
.text:19016F86 440                 call    ds:LoadLibraryA ; maps the specified executable module into the address space of the calling process
.text:19016F86                                             ; LPCSTR lpLibFileName - [in] Pointer to a null-terminated string that names the executable module
.text:19016F8C 43C                 mov     esi, eax
.text:19016F8E 43C                 test    esi, esi
.text:19016F90 43C                 mov     [esp+43Ch+LibFileName], esi
.text:19016F94 43C                 jz      loc_19017086


My question is, why is the value moved to esi before it's tested?  I see this done a lot, and it seems like an extra operation that isn't needed in both cases.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Kp

Conventionally, esi is a stable register, whereas eax is not.  Therefore, if the code is going to shortly be making another call, it must move eax to a stable register or to memory.  As to why it moves before testing, that's probably an optimization by the compiler -- but I don't know what specifically would be gained by such an optimization.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Adron

Could be
somevar = LoadLibrary(...);
if(somevar)

where somevar is optimized and put into the register esi, but also needs to be available later when esi has been used for other purposes. I would think that it'd be better to test eax,eax, but the compiler might have emitted those instructions as

; somevar = LoadLibrary(...);
call loadlibrary
mov esi, eax ; Store into register for read access

mov memorylocation, esi ; Store into permanent location because esi is about to be reused

; if(somevar)
test esi, esi
jz bla

then second pass optimization - peephole optimization(?) - has reordered the instructions to improve performance, but hasn't been allowed to rewrite them