The PDP-11 MARK instruction
leichterj at rani.DEC
leichterj at rani.DEC
Thu Feb 28 12:37:07 AEST 1985
Gary Ansok writes:
Newsgroups: net.unix-wizards
Path: decwrl!decvax!genrad!panda!talcott!harvard!seismo!brl-tgr
!tgr!geacc022%timevx at lbl.arpa
Subject: Curiosity
Posted: Fri Feb 22 17:53:17 1985
All right, you guys! I've been watching this conversation fly by for
some weeks now, and I have one burning question to ask:
What the #%$@ does the MARK instruction do??!?
Gary Ansok
GEACC022%TIMEVX%CITHEX @ LBL-G.ARPA
GEA @ CALTECH.BITNET
...ucbvax!cithep!timevx#geacc022
"All the world loves a straight man."
"You want this knowledge? How much you pay for this knowledge?" (Where IS
that from?)
Here is the formal definition of MARK, as given in the (1979-80 edition of)
the PDP-11 Processor Handbook:
MARK; opcode 0064NN.
SP <- PC + 2*NN
PC <- R5
R5 <- (SP)+
Condition codes: Unaffected
NN is the number of parameters. [Really, locals.]
Used as part of the standard PDP-11 subroutine return convention.
MARK facilitates the stack cleanup procedures involved in subroutine
exit.
It's been a while; let me see if I can make some sense of this.
First off, PC is the program counter, SP is the stack pointer, R5 is just
register 5, which will be used as a linkage register. Stacks grow down-
ward in memory; MOV <something>,-(SP) is a PUSH; MOV (SP)+,<something> is
a POP.
To understand how MARK might be used, you have to first off realize that
it is meant to be executed off the stack! The first instruction shows
this: SP is set to PC plus something, so PC better have SOMETHING to do
with the stack. In fact, the way you use MARK is as follows:
JSR R5,SUB ;Call subroutine with R5 as the linkage
;register: (R5) is where to return to, old
;value of R5 is on the top of the stack.
...
SUB: ;The subroutine
SUB #2*NN,SP ;Claim NN words (2*NN bytes) of stack space
;for locals
MOV (PC)+,-(SP) ;Push next word onto stack
MARK NN
(execute subroutine; locals are 2(SP),4(SP), to 2*NN(SP). Args,
if pushed before the JSR, are at 2*NN+4(SP), 2*NN+6(SP),
etc. - 2*NN+2(SP) contains the saved R5 value.)
JMP (SP) ;Return by executing the MARK instruction
;on the stack.
Note what the MARK instruction does:
SP<-PC+2*NN ;Cancel the words claimed for locals, plus
;the MARK itself (since the value of PC used
;is that AFTER the increment over the MARK.)
;SP is now where the JSR left it.
PC<-R5 ;Restore PC from the linkage register, where
;the JSR put it.
R5<-(SP)+ ;Restore the linkage register value saved by
;the JSR.
Simple, no? (Right.)
The real problem with MARK was two-fold:
a) It implemented a convention that was ALMOST what people wanted
to use, but usually not exactly right; and it didn't gain
much in performance over doing it yourself anyway. Besides,
MARK wasn't available on most PDP-11's, and it's a little
tough to build portable code around a non-portable calling
convention.
b) MARK HAD to execute off the stack to work. However, this was
inherently impossible in a system running with an I/D space
split.
In general, the PDP-11 has a fairly tight set of op codes; just about every-
thing was useful, and actually got used. The MARK was a glaring exception.
(The Commercial Instruction Set extensions also never caught on in any big
way, mainly because they came along too late.)
It's amusing to look for analogous things in other architectures. Some
Interdata machine - probably the 6/32 - had a large set of op codes to
transfer from user state to system state, with all sorts of variations on
how arguments were passed, and so on. (This is second hand; I'd give
more details if I knew them.) In fact, only one of the variations was
ever used.
-- Jerry
More information about the Comp.unix.wizards
mailing list