Xref: utzoo comp.os.msdos.programmer:615 alt.msdos.programmer:2065 comp.lang.c:31309 Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!usenet.ins.cwru.edu!ncoast!dale From: dale@NCoast.ORG (Dale Smith) Newsgroups: comp.os.msdos.programmer,alt.msdos.programmer,comp.lang.c Subject: Re: alloca() for TurboC Keywords: alloca, DOS, TurboC, assembly Message-ID: <1990Aug23.032751.15666@NCoast.ORG> Date: 23 Aug 90 03:27:51 GMT References: <2745@onion.reading.ac.uk> <3860@bingvaxu.cc.binghamton.edu> <1990Aug22.032243.18214@usenet.ins.cwru.edu> Organization: North Coast Public Access *NIX, Cleveland, OH Lines: 134 In article <1990Aug22.032243.18214@usenet.ins.cwru.edu> trier@po.CWRU.Edu writes: >Here's a version of alloca I use. It's my clone of a version from some >piece of PD software I saw a year or two ago. > > #define alloca(A) ((_SP -= ((A)+1) & 0xFFFE), (void far *)(((unsigned long)_SS << 16) | _SP)) > >The idea is to subtract the size A from the stack pointer, making sure >it's word-aligned. (This is the (_SP -= ((A)+1) & 0xFFFE) part.) Then, >since alloca returns a pointer to the allocated space, the macro must >kludge together a far pointer from the stack segment and stack pointer. > >I should add the disclaimer that I'm not entirely sure that this works. >It's my own version of someone else's, but I changed it a bit. (I don't >remember what the original looked like.) > >Hope this helps! > >-- >Stephen Trier Case Western Reserve University >Home: sct@seldon.clv.oh.us Information Network Services >Work: trier@cwlim.ins.cwru.edu > I may work for the University, but that doesn't mean I speak for them. I believe I saw something like that in an early port of bison. It's really cute but will trash register variables. Someone posted an alloca for the 386 which I hacked to fit Turbo C. I also took a peek at a disassembly of the Microsoft C 5.1 alloca(). Here it is, have fun. ------ Snip it or somethin' ------------------------------ ; alloca.asm ; Allocate from the stack for Turbo C 2.0 ; I have not tried this this TC++ 1.0 ; 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 -------------- Ok, that's it ----------------------------------------- dale -- Dale P. Smith dale@ncoast.org uunet!usenet.ins.cwru.edu!ncoast!dale