Author | Message | Time |
---|---|---|
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 |