Here's code that performs some arithmetics.
int main(void) {
int i = 3;
i++;
i+= 2;
return 0;
}
I compiled it using 32-bit tcc
with the following command
tcc -o hello.exe hello.c
I, then, disassembled it using IDA free edition, and after some time staring at the start
of the instructions I realized that the main function that I was looking for is in a subroutine, and going there I see this:
sub_401000 proc near
var_4= dword ptr -4
push ebp
mov ebp, esp
sub esp, 4 // allocate 4 bytes on the stack for var i
nop
mov eax, 3 // i = 3 instructions
mov [ebp+var_4], eax //
mov eax, [ebp+var_4] // i++ instructions
mov ecx, eax //
inc eax //
mov [ebp+var_4], eax //
mov eax, [ebp+var_4] // i+=2 instructions
add eax, 2 //
mov [ebp+var_4], eax //
mov eax, 0
jmp $+5
leave
retn
sub_401000 endp
I've added my understanding of what's going on in comments on the right for the body of the method that I am interested in.
For example, incrementing the variable would involve moving a value onto a register and then operating on it. I would expect i++
to look something like
mov eax, [ebp+var_4]
inc eax
But the actual instructions involved an extra move
mov eax, [ebp+var_4]
mov ecx, eax // <----- ?
inc eax
In the add instruction, the extra move isn't there. When I modified the code with a decrement operation, I see that extra move as well.
Is there some purpose for this move from eax
to ecx
?
UPDATE:
I am still reading about registers, and from what I've read ecx
is used as a counter, but from this code it isn't obvious what it's being used for, if anything.
i++
expression, it puts the old value into ecx in case some outer expression needs it; without optimizations, it never realizes there is no outer expression. Would be interesting to know if the instruction disappears when you use++i
instead.++i
instead.