Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!wuarchive!rex!uflorida!gatech!usenet.ins.cwru.edu!ncoast!dale From: dale@NCoast.ORG (Dale Smith) Newsgroups: comp.os.msdos.programmer Subject: Re: alloca() for Turbo C Message-ID: <1991Mar24.210419.24321@NCoast.ORG> Date: 24 Mar 91 21:04:19 GMT References: <200@esun49.nms.gdc.portal.com> <1991Mar20.054928.24101@ucselx.sdsu.edu> Organization: North Coast Public Access Un*x (ncoast) Lines: 134 In article <1991Mar20.054928.24101@ucselx.sdsu.edu> vaitl@ucselx.sdsu.edu (Eric Vaitl) writes: >>Does anyone know where I can get a PD version of alloca() for Turbo C? >>I'm trying to compile some GNU stuff which uses it. >> >>Thanks! >>-- >>Jeff Chadbourne >>chadbourne@nms.gdc.portal.com > > >I got this from one of the versions of Bison floating around: > >/***********************************************************************\ >| The following gives the definition of a macro (alloca) that allocates | >| space like malloc EXCEPT that it is allocated from the stack and does | >| not have to be freed. The allocated space will automatically disap- | >| pear when the function that allocated the space exits. | >\***********************************************************************/ >#if !defined(alloca) >#if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) >#define alloca(i) (_SP-=((i+1)&0xFFFE),(void *)(((unsigned long)_SS<<16)|_SP)) >#else >#define alloca(i) (_SP-=((i+1)&0xFFFE),(void *)_SP) >#endif >#endif The above will trash register variables. This one works better.... ---------------- Use Ginsu knife here --------------------- ; alloca.asm ; Allocate from the stack for Turbo C 2.0 ; I have not tried this with TC++ 1.0 ; I got this off the net as a 386 version for unix. I hacked it ; it fit Turbo C and non-32 bit registers. The original was probably ; from Chip Salzenberg (if I can't spell... sorry Chip). ; -- Dale P. Smith ; void *alloca(size_t size); ; Beware of using alloca in functions without arguments ; and -k- in tiny, small, and medium models. The stack has a ; possibility of growing. ifdef __TINY__ .model tiny elseifdef __SMALL__ .model small elseifdef __MEDIUM__ .model medium elseifdef __COMPACT__ .model compact elseifdef __LARGE__ .model large elseifdef __HUGE__ .model huge else .model small endif if @DataSize EQ 0 .data extrn ___brklvl:word endif .code public _alloca _alloca proc ;; Pop return address into (es:) cx and size into ax pop cx ; return address if @CodeSize pop es ; return segment endif pop ax ; size ;; Make sure that ax is greater than zero, and is a multiple of two. cmp ax,0 jl error inc ax and ax,not 1 ;; Figure new stack pointer, check for negative and less than brk. mov bx,sp sub bx,ax jb error ; below zero if @DataSize EQ 0 ; tiny, small, medium cmp bx,___brklvl jb error ; below the brk endif xchg sp,bx mov ax,sp ;; Copy the (hypothetical) register variables. ifdef __MEDIUM__ push ss:6[bx] ; return segment(medium) endif push ss:4[bx] ; return offset(med,sm,tiny) or ds(huge) push ss:2[bx] ; di (all) push ss:[bx] ; si (all) if @DataSize mov dx,ss endif exit: ;; Put something on the stack so that our caller can pop it off. push ax ;; Return to the the caller. if @CodeSize push es push cx ret else jmp cx endif error: xor ax,ax if @DataSize cwd endif jmp exit endp end -- Dale P. Smith dale@ncoast.org dale@harco3.uucp uunet!usenet.ins.cwru.edu!ncoast!dale uunet!aablue!fmsystm!harco3!dale