Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!snorkelwacker!apple!well!brecher From: brecher@well.sf.ca.us (Steve Brecher) Newsgroups: comp.sys.mac.programmer Subject: Re: alloca; *almost* working... Message-ID: <16783@well.sf.ca.us> Date: 21 Mar 90 02:54:13 GMT References: <1801@sequent.cs.qmw.ac.uk> Reply-To: brecher@well.sf.ca.us (Steve Brecher) Organization: Software Supply, Sunnyvale, CA Lines: 85 In article <1801@sequent.cs.qmw.ac.uk>, morten@cs.qmw.ac.uk (Morten Ronseth) writes: > This is the assembly for my `alloca' routine, a rewrite of the > one used in GNU Emacs. > ... > movea.l (sp)+,a0 ; pop return addr from tos > move.l (sp)+,d0 ; pop size in bytes from tos > move.l sp,a1 ; save old sp for register copy > move.l sp,d1 ; compute new sp > sub.l d0,d1 ; allocate requested space on stack > and.l #-4,d1 ; round down to longword > sub.l #16 * 4,d1 ; space for saving registers > move.l d1,sp ; save new value of sp > move.w #16 - 1,d0 ; loop counter... > @loop > move.l (a1)+,(sp)+ ; copy the register to top of stack > dbra d0,@loop ; loop... > move.l sp,d0 ; return value > move.l d1,sp ; load new value for sp > jmp (a0) ; rts Unfortunately I don't know what "alloca" is or what it's supposed to do; but I know the above code is wrong, because (SP)+ never makes sense as the destination of a move, unless maybe to make sure some data on the stack is overwritten (say, a password) for security reasons. The stack is used by asynchronous processes such as interrupt handlers and hence any data immediately below SP is subject to destruction at any time. I infer that what is wanted is something like this: On entry-- stuff[15] ("stuff" = saved register value?) ... stuff[0] size of desired stack allocation SP-> return address On exit-- stuff[15] ... stuff[0] end of allocated stack area ... D0-> start of allocated stack area copy of stuff[15] ... SP-> copy of stuff[0] If I infer correctly, then: Move.L (SP)+,A0 ;return address MoveQ #-4,D0 ;truncation mask And.L (SP)+,D0 ;size of allocated area, truncated Lea 4*16(SP),A1 ;point beyond end of stuff to be copied Sub.L D0,SP ;allocate the area Move.L SP,D0 ;return value MoveQ #16-1,D1 ;Dbra count @0 Move.L -(A1),-(SP) ;copy a longword of stuff Dbra D1,@0 Jmp (A0) ;return > (If I remeber correctly, MPW C defers the pop'ing, `addq.l #n,sp', > of params after the return of a 'jsr', i.e. relying on an `unlk' to > adjust the stack. Hence I do not need a `subq.l #4,sp' in my 'alloca' > to fix the stack. But what, do I hear you ask, if the calling function > doesn't take any params nor uses any local vars? Well, I'm compiling > with `-g' so the compiler should generate a `link' and an `unlk' no > matter what...shouldn't it?) MPW C does not necessarily depend on a final UNLK to fix the stack; it may deallocate the parameters to a called routine, or re-use the allocated stack space, at any time after the call. So if the above is to be an MPW C function, you should indeed fix the stack by inserting SubQ #4,SP before the final Jmp. Whether the assumption that there are saved registers (and not some transient temporaries) on the stack immediately above the parameter is valid I cannot say, but in the general case of a function called from an arbitrary point in another, the assumption would NOT be warranted. -- brecher@well.sf.ca.us (Steve Brecher)