jfw (01/15/83)
A long time ago, I wanted to write a better setjump/longjump system. This involved finding out what the C stack frame looks like. After 3 days of poking through cc -S output, I determined the stack frame for the PDP-11 and, not desiring to ever go through that work again, came up with the following manual page for the stack frame: **************** /usr/man/unix/chap5/stack.5 **************** .nr LL 6.5 .TH STACK 5 PDP-11 .SH NAME stack, C subroutine discipline .SH DESCRIPTION A C subroutine stack frame looks like the following: .nf .in +5 .ta 8 16 24 32 40 48 56 64 ------------------ |...nth argument | push arguments in reverse order ------------------ |second argument | ------------------ | first argument | ------------------ JSR PC,*$_FOO | return address | ------------------ JSR R5,CSV | old R5 value | <----- ------------------ | | r4 | | ------------------ | | r3 | | ------------------ | | r2 | | ------------------ | | blank word | | ------------------ | This is the top of the stack | routine | | when the called routine "starts" | allocates | | | storage | | SUB $n,SP | temporary | | ------------------ | | push arguments | | | of next routine| | ------------------ | JSR PC,*$_BAR | return address | | ------------------ | JSR R5,CSV | old R5 value---+------- ------------------ ^ | r4/43/r2/... | | ------------------ | and so on..... | .fi .in -5 Functions leave their return value in R0 (floating functions return it in FR0). "long" functions leave return values in R1/R0; functions returning structures leave a pointer to bss storage (one chunk of which is allocated for each such routine) in R0, and the caller will copy from that bss storage to the local destination. Local variables are allocated in such a way that they are referred to as "-N(R5)", arguments are referred to as "+N(R5)"; arguments start at 4(R5), the first integer local declared will be at -10[8](R5). It is important to note that routines know how many arguments they pass to a function, and will adjust the stack accordingly after a function returns. .SH AUTHOR John F. Woods, MIT Concouse Computer Center
ka (01/17/83)
One corrections to John's article: there is no blank word above the space for local variables. There IS a blank word below this if the routine con- tains function calls with arguments; this is used to save the last function argument to decrease the number of pushes and pops done on the stack pointer. Kenneth Almquist
jfw (01/18/83)
Could someone mail me a copy of what went out on the net for my PDP-11 stack use manual page? Ken Almquist's comment sounds like the older version of my document, which I first submitted in a fit of narcolepsy. I thought I editted the version in /usr/spool/news, but uucp might have (for once) promptly logged in and spirited it off before I noticed. Sigh. John Woods
dmmartindale (01/18/83)
Note that the "blank word" in the PDP11 stack layout is always BELOW the local variables, not between them and the saved registers. One word of space is reserved by csv, but if the routine has any local variables one of these will use this word, and the stack address below all of the locals becomes the "blank word". Thus, unless an arithmetic temporary has been stored on the stack, (sp) is always a free word, and so when calling another routine, the last argument can be stuffed directly rather than using auto-decrement addressing. This saves a tiny bit of time, but the real saving comes when adjusting the stack after that routine's return. If you passed only one word of arguments, no adjustment is necessary, if there were two arguments you can use a tst (sp)+ instead of a cmp (sp)+,(sp)+, and for three arguments you can use cmp instead of add. Since an awful lot of subroutine calls will have 1, 2, or 3 arguments this saving is worthwhile.
gwyn@brl-vld.arpa (03/05/83)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld.arpa> Fine, except there is not a "blank word" in the stack frame after the saved R2; it is part of allocated auto storage. The cell "(sp)" is available for scratch use by the C code generator and percolates to the top of the stack as it grows. The same stack frame is used on modern Bell PDP-11 UNIX, but the procedure linkage was changed from "jsr r5,csv" to "jsr r0,csav" to solve a problem discussed in this mailing list not very long ago. Bell UNIX documents the stack frame, although not as thoroughly as you have done, in the sources for csav and cret.
cak@Purdue (04/01/83)
From: Christopher A Kent <cak@Purdue> Aw come on! Such a man page would give it all away! I mean, a programmer could just sit down and have it all right there, and not have to go digging! What fun would that be? It would be too easy to become a wizard. (I'm actually half serious...I think that some of the best learning I did was prowling through the UPM looking for something totally different than what I found. I STILL tell new users to go home and read the WHOLE UPM; I also say that they probably won't care/understand at least 50% of it, but someday, they'll need something, and it will be tucked away in the back of their hindbrains that they saw it SOMEWHERE once...) Cheers, chris