Stack cleanup after CALL misses a DWORD on x86
Phil Jerkins
jpjerkins@yahoo.com
Fri Oct 4 11:34:00 GMT 2002
To Whom It Concerns:
First, a word of thanks. You have done a great work
for free, and it is greatly appreciated. This
compiler has contributed perhaps more than Linux to
the changes we're seeing in the software landscape.
And they're good changes.
THE SHORT VERSION
If an external function that returns a structure is
called through a function pointer, an extra DWORD gets
left on the stack after each call, leading to possible
stack overflow.
THE CONTEXT
I'm using MinGW and NASM. I'm writing a function in
NASM that I'm calling using a FUNCTION POINTER in C.
The function takes and returns a structure, and does
absolutely nothing - see the code. The code generated
for the call sets up the stack:
1 LEA the return struct's address into EAX
2 Reserve 12 bytes on the stack (?) 12
3 Push the input structure +16 = 28
4 Push EAX (the return struct's address) +4 = 32
5 Load the function pointer into EAX
6 CALL EAX.
THE PROBLEM
The code that immediately follows the CALL EAX
instruction is the problem. Remember - it has pushed
a 16-byte structure, reserved an additional 12 bytes,
then pushed the return struct's address - 32 bytes
total. After the CALL returns, it only adds 28 bytes
to the stack pointer - leaving out 4 bytes, or 1
DWORD.
I found the problem because I'm calling my ASM
function in a loop 200 million times (comparing it's
performance to that of a comparable C# program). With
that many DWORDs missed, it eventually ran out of
stack space. The program executes normally until it
runs out of stack space.
I'm including the source files. I'm using MinGW32
2.0.0.3 (which includes gcc 3.2 mingw special
20020817-1 - www.mingw.org), and NASM 0.98.34 for
Win32 (nasm.sourceforge.net) on Windows XP SP1. Note
how little is NOT commented out in the ASM file. You
can use a hex editor to change the byte at offset
0x0A02 from 0x1C to 0x20, and the program runs
correctly. I used PEBrowse Pro Interactive (freeware
at www.smidgeonsoft.com) to disassemble and debug the
EXE.
The command lines I'm using to compile:
nasmw -f coff VectorSSE.asm
gcc -fpcc-struct-return -c SpeedTests2.c
gcc -o SpeedTests2 SpeedTests2.o VectorSSE.o
Feel free to contact me for more info.
Thanks again!
Phil Jerkins
jpjerkins@yahoo.com
__________________________________________________
Do you Yahoo!?
New DSL Internet Access from SBC & Yahoo!
http://sbc.yahoo.com
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: SpeedTests2.c
URL: <http://gcc.gnu.org/pipermail/gcc-bugs/attachments/20021004/a346da1e/attachment.c>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: VectorSSE.asm
URL: <http://gcc.gnu.org/pipermail/gcc-bugs/attachments/20021004/a346da1e/attachment.ksh>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: SpeedTests2.exe
Type: application/octet-stream
Size: 23770 bytes
Desc: SpeedTests2.exe
URL: <http://gcc.gnu.org/pipermail/gcc-bugs/attachments/20021004/a346da1e/attachment.exe>
More information about the Gcc-bugs
mailing list