Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site decwrl.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!bellcore!decvax!decwrl!dec-rhea!dec-rani!leichterj From: leichterj@rani.DEC Newsgroups: net.unix-wizards Subject: The PDP-11 MARK instruction Message-ID: <788@decwrl.UUCP> Date: Wed, 27-Feb-85 21:37:07 EST Article-I.D.: decwrl.788 Posted: Wed Feb 27 21:37:07 1985 Date-Received: Sat, 2-Mar-85 03:20:45 EST Sender: daemon@decwrl.UUCP Organization: DEC Engineering Network Lines: 106 Gary Ansok writes: Newsgroups: net.unix-wizards Path: decwrl!decvax!genrad!panda!talcott!harvard!seismo!brl-tgr !tgr!geacc022%timevx@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,-(SP) is a PUSH; MOV (SP)+, 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