Valhalla Legends Forums Archive | Assembly Language (any cpu) | Using return values

AuthorMessageTime
iago
Fairly often, I notice things like this in compiled code:
[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[/code]

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.
May 3, 2003, 8:00 PM
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.
May 3, 2003, 8:34 PM
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
May 3, 2003, 10:06 PM

Search