I've been wondering, why all the hassle with variable length arrays (such as int x[n])? Theoretically, it's just another local variable, so it's merely a matter of subtracting the appropriate value from ESP. This question - and excellent answer - at StackOverflow: https://stackoverflow.com/questions/1887097/variable-length-arrays-in-c has cleared things up a bit.
However, I was curious to see what code would be generated by compilers. I've tried MSVC 2013 and MinGW 4.8.1, with the latter successfully compiling the code and the former refusing to cooperate. The C++ (well actually C, but compiled with g++) code is as follows:
#include<stdio.h>
int main()
{
int size;
scanf("%d", &size);
int array[size];
array[0] = 0xBEEF;
printf("Done with the arrays!\n");
return 0;
}
This will be compiled to the following assembly code (diassembled with Olly 1.10, but also tried IDA and got the same results):
(some main( ) initialization)
LEA EAX,[LOCAL.5]
MOV DWORD PTR SS:[ESP+4],EAX
MOV DWORD PTR SS:[ESP],tesst.00403064 ;"%d"
CALL <JMP.&msvcrt.scanf>
MOV EAX,[LOCAL.5]
SUB EAX,1
MOV [LOCAL.3],EAX
ADD EAX,1
SHL EAX,2
LEA EDX,DWORD PTR DS:[EAX+3]
MOV EAX,10
SUB EAX,1
ADD EAX,EDX
MOV ECX,10
MOV EDX,0
DIV ECX
IMUL EAX,EAX,10
CALL tesst.00401C60
SUB ESP,EAX
LEA EAX,DWORD PTR SS:[ESP+8]
ADD EAX,3
SHR EAX,2
SHL EAX,2
MOV [LOCAL.4],EAX
MOV EAX,[LOCAL.4]
MOV DWORD PTR DS:[EAX],0BEEF
MOV DWORD PTR SS:[ESP],tesst.00403067
CALL <JMP.&msvcrt.puts>
MOV EAX,0
MOV ESP,EBX
LEA ESP,[LOCAL.2]
POP ECX
POP EBX
POP EBP
LEA ESP,DWORD PTR DS:[ECX-4]
RETN
To me, this code looks redundant and absurd, at times, to be honest. Why do we LEA EAX+3 to EDX just to add it a couple lines later, without altering EDX in any way? Why MOV EAX to ESP-0C (LOCAL.3) if it's not used at all later? And, of course, what's with the MOV ESP, EBX and then LEA ESP,EBP-8 immediately after?
And most of all, why all the hassle? Wouldn't it just have been enough to do something like this:
LEA EAX,[LOCAL.5]
MOV DWORD PTR SS:[ESP+4],EAX
MOV DWORD PTR SS:[ESP],tesst.00403064 ; "%d"
CALL <JMP.&msvcrt.scanf>
MOV EAX,[LOCAL.5]
SHL EAX,2 ;multiply times 4 - sizeof int
SUB ESP,EAX ;memory is allocated, all done