Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!snorkelwacker!mit-eddie!attctc!torch From: torch@attctc.Dallas.TX.US (Jay Finger) Newsgroups: comp.sys.mac.programmer Subject: Re: alloca for Think C 4.0: here it is Summary: Here's a fixed version! Keywords: alloca Think C Message-ID: <11393@attctc.Dallas.TX.US> Date: 10 Feb 90 07:37:35 GMT References: <11376@attctc.Dallas.TX.US> <6521@uhccux.uhcc.hawaii.edu> Organization: The Unix(R) Connection, Dallas, Texas Lines: 71 Mike Morton cat allocax From mikem@uhccux.UUCP Thu Feb 8 23:38:06 1990 Path: attctc!ames!elroy.jpl.nasa.gov!jarthur!uunet!samsung!munnari.oz.au!uhccux!mikem From: mikem@uhccux.uhcc.hawaii.edu (Mike Morton) Newsgroups: comp.sys.mac.programmer Subject: Re: alloca for Think C 4.0: here it is Keywords: alloca Think C Message-ID: <6521@uhccux.uhcc.hawaii.edu> Date: 9 Feb 90 05:38:06 GMT References: <11376@attctc.Dallas.TX.US> Reply-To: mikem@uhccux.UUCP (Mike Morton) Organization: University of Hawaii Lines: 19 In <6521@uhccux.uhcc.hawaii.edu> Mike Morton writes: >Jay Finger writes: >>pascal void *alloca(long size) = >> { >> 0x201F, /* MOVE.L (SP)+,D0 ;get size */ >> 0x5680, /* ADDQ.L #3,D0 ;make it a multiple of 4 */ >> 0x0240, 0xFFFC, /* ANDI.W #-4,D0 */ >> 0x9FC0, /* SUB.L D0,SP ;allocate it */ >> 0x2F0F /* MOVE.L SP,-(SP) ;return value on stack */ >> }; > >Since the "calling" C code has already done something like a: > SUBQ #4, SP >to make room for a Pascal-style returned value, then isn't this >allocating 4 bytes more than needed? I think changing -(SP) to >just (SP) would work, but haven't tried it. You got me. You're right, almost. Changing to (SP) would keep the correct amount of space on the stack, but the pointer would then get screwed up: the address returned would be the address of the return value itself, which would then get popped off the stack, letting other things write into the newly allocated block. There are three ways to fix it (described from worst to (IMHO) best): 1: Move SP to D0, add 4, and then do a "MOVE.L D0,(SP)". This takes two more instructions, and about two additional words. 2: Replace "MOVE.L SP,-(SP)" with "LEA 4(SP),(SP)". The same number of instructions, but an extra word for the displacement. 3: Keep the "MOVE.L SP,-(SP)" at the bottom, but simply allocate four less bytes, making use of the four bytes that the caller already allocated for the return value. Since #3 is already being added to the block size for word-alligning, subtracting 4 can be merged into the operation by replacing the ADDQ #3 with a SUBQ #1. Same number of instructions, same number of words. So anyhow, here's a new version (using method #3) that allocates the correct number of bytes on the stack: ---------------------- cut here ---------------------- pascal void *alloca(long size) = { 0x201F, /* MOVE.L (SP)+,D0 ;get size */ 0x5380, /* SUBQ.L #1,D0 ;long-word allign, allowing for */ 0x0240, 0xFFFC, /* ANDI.W #-4,D0 ; 4 bytes already on the stack */ 0x9FC0, /* SUB.L D0,SP ;allocate it */ 0x2F0F /* MOVE.L SP,-(SP) ;return value on stack */ }; ---------------------- the end! ---------------------- Jay Finger, {ames,mit-eddie}!attctc!torch ames!torch@attctc