mike2@lcuxa.UUCP (M S Slomin) (05/19/88)
Quick question: has anyone worked out a way to simulate the 'alloca' function in either TurboC or MSC (DOS for those who don't know)? Alloca is a memory allocation analogue to an automatic variable. Just as an automatic variable exists only while a function is in progress, alloca allocates memory only while a function is in progress, and when the function exits that memory is freed. Obviously, this can be implemented with malloc/free combinations, but the automatic approach seems cleaner, which perhaps explains why many programmers use alloca if it is available. It would be nice to implement this. Thanks for the help. Mike Slomin bellcore!lcuxa!mike2
dg@lakart.UUCP (David Goodenough) (05/24/88)
From article <203@lcuxa.UUCP>, by mike2@lcuxa.UUCP (M S Slomin): > Quick question: has anyone worked out a way to simulate the 'alloca' > function in either TurboC or MSC (DOS for those who don't know)? Write it in assembler. I don't know how to do alloca in C in a portable manner. Come to that - since you have to mess with your frame/stack pointer I don't think it can be done in anything other than assembler. Sure can't on a z80. CAVEAT for my z80 implementetion, you are advised NOT TO USE in a complex expression (where temp results need to be stacked) think about it!! .extern _alloca _alloca: pop de pop hl call #neg ; negate argument add hl,sp ; allocate the space push hl push de ; put args back so return works ret ; home we go - hl points to space. This should be fairly easy to convert to 8086 assembler (What, your C compiler can't talk in assembler?? :-) Different segments may be a pain - this space will be in SS:, and I can just see referencing through a 16 bit pointer as DS: UGH!!. Still if you send back a 32 bit pointer SEG:OFFSET or make sure DS: and SS: are the same, you should be flying. -- dg@lakart.UUCP - David Goodenough +---+ | +-+-+ ....... !harvard!adelie!cfisun!lakart!dg +-+-+ | +---+
kent@happym.UUCP (Kent Forschmiedt) (05/26/88)
I don't know about TurboC, but MSC seems to use a conventional stack structure. The alloca() that I use actually uses malloc() and free(), but saves a tag pointing to the current stack frame whenever a block is alloca()'d. When alloca() is called, it free()'s all of the blocks whose tags point below (on a down-growing stack) the current frame. I think that this scheme will work with any implementation that uses a real stack, but probably not if frames are randomly allocated from a heap, and I doubt that TurboC uses such an unconventional scheme. -- -- Kent Forschmiedt -- kent@happym.UUCP, tikal!camco!happym!kent Happy Man Corporation 206-282-9598
darrylo@hpsrli.HP.COM (Darryl Okahata) (05/28/88)
In comp.sources.d, dg@lakart.UUCP (David Goodenough) writes: > From article <203@lcuxa.UUCP>, by mike2@lcuxa.UUCP (M S Slomin): > > Quick question: has anyone worked out a way to simulate the 'alloca' > > function in either TurboC or MSC (DOS for those who don't know)? > > Write it in assembler. I don't know how to do alloca in C in a portable [ ... ] > .extern _alloca > _alloca: > pop de > pop hl > call #neg ; negate argument > add hl,sp ; allocate the space > push hl > push de ; put args back so return works > ret ; home we go - hl points to space. > > This should be fairly easy to convert to 8086 assembler (What, your C compiler > can't talk in assembler?? :-) Different segments may be a pain - this space [ ... ] Whoa, it's not as easy as it seems. Take the following code fragment, for example: foo(a) int a; { char *here; here = NULL; if (a == 17) { char *there; there = alloca(SOME_NUMBER); bar(there); here = there; } blech(here); } The problem in the above code fragment is that the stack frame allocated at the start of the if statement block is deallocated at the end of the block. If the above Z80 code was translated into 80x8x code (taking care to move the stack pointer BELOW the allocated area because of interrupts), that code will not work for the above code fragment. Why? Because, at the end of the if block, code will be generated to reset the stack pointer to the value it had at the beginning of the if block (and, chances are, if a simple ADD SP,n is used, the system will eventually crash because the stack pointer was modified by alloca() and is not where it should be). > dg@lakart.UUCP - David Goodenough +---+ > | +-+-+ > ....... !harvard!adelie!cfisun!lakart!dg +-+-+ | > +---+ -- Darryl Okahata {hplabs!hpccc!, hpfcla!} hpsrla!darrylo CompuServe: 75206,3074 Disclaimer: the above is the author's personal opinion and is not the opinion or policy of his employer or of the little green men that have been following him all day.
skip@skipnyc.UUCP (Skip Gilbrech) (05/28/88)
In article <203@lcuxa.UUCP> mike2@lcuxa.UUCP (M S Slomin) writes: >Quick question: has anyone worked out a way to simulate the 'alloca' >function in either TurboC or MSC (DOS for those who don't know)? I hate to point this out ;-) but MSC has had 'alloca' in their library at least since the 4.0 release... Check out the library reference (don't know about TurboC). -- Skip Gilbrech UUCP: uunet!pwcmrd!skip PaineWebber, NYC attmail!skipnyc!skip
james@bigtex.uucp (James Van Artsdalen) (05/28/88)
IN article <134@lakart.UUCP>, dg@lakart.UUCP (David Goodenough) wrote: > From article <203@lcuxa.UUCP>, by mike2@lcuxa.UUCP (M S Slomin): > > Quick question: has anyone worked out a way to simulate the 'alloca' > > function in either TurboC or MSC (DOS for those who don't know)? MS-C 5.0 has alloca(). > Write it in assembler. I don't know how to do alloca in C in a portable > manner. Come to that - since you have to mess with your frame/stack pointer > I don't think it can be done in anything other than assembler. Sure can't > on a z80. There is a version in C in the GNU gawk distribution. I can mail it to anyone who can't get it from the archives. I doubt it's quick, but it is supposed to be portable. They use malloc() to allocate, and some heuristic to detect when the stack pointer is different than it was the last invocation: I'm not sure of exactly how they work it. > This should be fairly easy to convert to 8086 assembler (What, your C compiler > can't talk in assembler?? :-) Different segments may be a pain - this space > will be in SS:, and I can just see referencing through a 16 bit pointer as DS: > UGH!!. Still if you send back a 32 bit pointer SEG:OFFSET or make sure > DS: and SS: are the same, you should be flying. DS: and ES: are typically going to be the same in a small model program (or in native 386 mode). For Microport 386, I just put this in my malloc.h include file: asm char *alloca(n) { %mem n subl n, %esp andl $-4, %esp mov %esp,%eax %reg n subl n, %esp andl $-4, %esp mov %esp,%eax %con n subl n, %esp andl $-4, %esp mov %esp,%eax } Note that it longword-aligns the allocated area. -- James R. Van Artsdalen ...!ut-sally!utastro!bigtex!james "Live Free or Die" Home: 512-346-2444 Work: 328-0282; 110 Wild Basin Rd. Ste #230, Austin TX 78746
james@bigtex.uucp (James Van Artsdalen) (05/30/88)
IN article <3100002@hpsrli.HP.COM>, darrylo@hpsrli.HP.COM (Darryl Okahata) wrote: > [ code fragment deleted ] > The problem in the above code fragment is that the stack frame allocated at > the start of the if statement block is deallocated at the end of the block. As near as I can tell, that is indeed the nature of alloca(), and hence the code in question is not in error. Perhaps some Joe Vaxhacker out there can say what the BSD code really does. The Microsoft C code does what the 8080 code shown in the original posting did, and my alloca() has gotten away with it too thus far. The BSD 4.3 manuals are, shall we say, somewhat less than definitive on the matter. -- James R. Van Artsdalen ...!ut-sally!utastro!bigtex!james "Live Free or Die" Home: 512-346-2444 Work: 328-0282; 110 Wild Basin Rd. Ste #230, Austin TX 78746
mouse@mcgill-vision.UUCP (der Mouse) (06/03/88)
In article <443@happym.UUCP>, kent@happym.UUCP (Kent Forschmiedt) writes: > I don't know about TurboC, but MSC seems to use a conventional stack > structure. The alloca() that I use actually uses malloc() and > free(), but saves a tag pointing to the current stack frame whenever > a block is alloca()'d. When alloca() is called, it free()'s all of > the blocks whose tags point below (on a down-growing stack) the > current frame. I think that this scheme will work with any > implementation that uses a real stack, [...] I doubt it. How about main() { while (1) { test(); } } test() { char *foo; char *alloca(); foo = alloca(10); } With a proper alloca() (free on return), this will be an infinite loop. With the scheme you suggest, it will slowly chew up memory, ten bytes at a crack. Unless you have some scheme for putting serial numbers in stack frames, so you can tell one call to test() from the next.... der Mouse uucp: mouse@mcgill-vision.uucp arpa: mouse@larry.mcrcim.mcgill.edu