On 24-Aug-01 David O'Brien wrote:
> On Fri, Aug 24, 2001 at 01:01:39AM +0100, Steve Roome wrote:
>> How exactly should functions work in assembly, afaict, the
>> following C :
>>
>> void printasint(int p) { printf ("print this %d\n", (int)p);}
>
> Why not just ask the compiler??
>
> $ cc -S -O0 printasint.c
> $ cat printasint.s
>
>
> .file "foo.c"
> .version "01.01"
> gcc2_compiled.:
> .section .rodata
> .LC0:
> .byte 0x70,0x72,0x69,0x6e,0x74,0x20,0x74,0x68,0x69,0x73
> .byte 0x20,0x25,0x64,0xa,0x0
> .text
> .p2align 2,0x90
> .globl printasint
> .type printasint,@function
> printasint:
> pushl %ebp
> movl %esp,%ebp
> subl $8,%esp
> addl $-8,%esp
> movl 8(%ebp),%eax
> pushl %eax
> pushl $.LC0
> call printf
> addl $16,%esp
> .L2:
> leave
> ret
> .Lfe1:
Because this code is broken and obfuscated? :)
We save %esp in %ebp (the only thing that keeps it from breaking) then for some
reason allocate two quadwords on the stack unnecessarily, one using an add
instruction, one using a sub. Then we push the two dword args on the stack and
call the function. After the call, we adjust the stack by 16, even though
we only used 8 bytes of arguments! Thus, it seems to be reclaiming one of the
2 quadwords it allocated on the stack in addition to the arguments passed to
the function. At this point if we did a 'pop %ebp' instead of leave, things
would break since we have a misaligned stack, but the leave restores the %esp
from %ebp, before pop'ing %ebp thus working around the bogus stack handling.
A better version would be this:
printasint:
pushl %ebp
movl %ebp, %esp
pushl 8(%ebp)
pushl $.LC0
call printf
addl $8,%esp
leave
ret
Note that with hand optimizing, you could axe the addl after the call since
leave will clean up after that anyways. Also, you don't really need a frame
here anyways. In that case, you could just push 8(%esp) as your first
instruction and axe the leave (but leave the addl).
--
John Baldwin <[EMAIL PROTECTED]> -- http://www.FreeBSD.org/~jhb/
PGP Key: http://www.baldwin.cx/~john/pgpkey.asc
"Power Users Use the Power to Serve!" - http://www.FreeBSD.org/
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message