1.7. STACK
push esi
call _puts
add esp, 28
...
The solealloca()argument is passed viaEAX(instead of pushing it into the stack)^64.
GCC + Intel syntax
GCC 4.4.1 does the same without calling external functions:
Listing 1.39: GCC 4.7.3
.LC0:
.string "hi! %d, %d, %d\n"
f:
push ebp
mov ebp, esp
push ebx
sub esp, 660
lea ebx, [esp+39]
and ebx, -16 ; align pointer by 16-bit border
mov DWORD PTR [esp], ebx ; s
mov DWORD PTR [esp+20], 3
mov DWORD PTR [esp+16], 2
mov DWORD PTR [esp+12], 1
mov DWORD PTR [esp+8], OFFSET FLAT:.LC0 ; "hi! %d, %d, %d\n"
mov DWORD PTR [esp+4], 600 ; maxlen
call _snprintf
mov DWORD PTR [esp], ebx ; s
call puts
mov ebx, DWORD PTR [ebp-4]
leave
ret
GCC + AT&T syntax
Let’s see the same code, but in AT&T syntax:
Listing 1.40: GCC 4.7.3
.LC0:
.string "hi! %d, %d, %d\n"
f:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $660, %esp
leal 39(%esp), %ebx
andl $-16, %ebx
movl %ebx, (%esp)
movl $3, 20(%esp)
movl $2, 16(%esp)
movl $1, 12(%esp)
movl $.LC0, 8(%esp)
movl $600, 4(%esp)
call _snprintf
movl %ebx, (%esp)
call puts
movl -4(%ebp), %ebx
leave
(^64) It is because alloca() is rather a compiler intrinsic (11.3 on page 999) than a normal function. One of the reasons we need a
separate function instead of just a couple of instructions in the code, is because theMSVC^65 alloca() implementation also has code
which reads from the memory just allocated, in order to let theOSmap physical memory to thisVM^66 region. After thealloca()
call,ESPpoints to the block of 600 bytes and we can use it as memory for thebufarray.