Background
I'm just learning x86 asm by examining the binary code generated by the compiler.
Code compiled using the C++ compiler in Visual Studio 2010 beta 2.
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.21003.01 for 80x86
C code (sandbox.c)
int mainCRTStartup()
{
int x=5;int y=1024;
while(x) { x--; y/=2; }
return x+y;
}
Compile it using the Visual Studio Command Prompt
cl /c /O2 /Oy- /MD sandbox.c
link /NODEFAULTLIB /MANIFEST:NO /SUBSYSTEM:CONSOLE sandbox.obj
Disasm sandbox.exe in OllyDgb
The following starts from the entry point.
00401000 >/$ B9 05000000 MOV ECX,5
00401005 |. B8 00040000 MOV EAX,400
0040100A |. 8D9B 00000000 LEA EBX,DWORD PTR DS:[EBX]
00401010 |> 99 /CDQ
00401011 |. 2BC2 |SUB EAX,EDX
00401013 |. D1F8 |SAR EAX,1
00401015 |. 49 |DEC ECX
00401016 |.^75 F8 \JNZ SHORT sandbox.00401010
00401018 \. C3 RETN
Examination
MOV ECX, 5 int x=5;
MOV EAX, 400 int y=1024;
LEA ... // no idea what LEA does here. seems like ebx=ebx. elaborate please.
// in fact, NOPing it does nothing to the original procedure and the values.
CQD // sign extends EAX into EDX:EAX, which here: edx = 0. no idea why.
SUB EAX, EDX // eax=eax-edx, here: eax=eax-0. no idea, pretty redundant.
SAR EAX,1 // okay, y/= 2
DEC ECX // okay, x--, sets the zero flag when reaches 0.
JNZ ... // okay, jump back to CQD if the zero flag is not set.
This part bothers me:
0040100A |. 8D9B 00000000 LEA EBX,DWORD PTR DS:[EBX]
00401010 |> 99 /CDQ
00401011 |. 2BC2 |SUB EAX,EDX
You can nop it all and the values of EAX and ECX will remain the same at the end. So, what's the point of these instructions?