On 2016-01-05 18:43, Ronald Natalie<ron(a)ronnatalie.com> wrote:
Just never figured out how to make good use of the MARK instruction on the PDP-11.
Not surprising. As others noted, few ever did. And apparently none
responding actually do either.
It *is* a stupid instruction in many ways. And it's not for multiple
returns either.
It's an odd way of handling stack cleanup without a frame pointer.
It's extremely bad, since it actually requires the stack to be in
instruction space. And yes, you are expected to execute on the stack.
The idea is that the caller pushes arguments on the stack, but the
cleanup of the stack is implicitly done in the subroutine itself, and at
the same time you get an argument pointer.
Example:
Calling:
MOV R5,-(SP) ; Save old R5
MOV <argn>,-(SP)
MOV <argn-1>,-(SP)
.
MOV <arg1>,-(SP)
MOV #MARKN,-(SP) ; Where the N in MARK N is the number of
arguments you just pushed.
MOV SP,R5
JSR PC,SUB
.
.
In the subroutine you then have the arguments available relative to R5.
So that arg1 is available at 2(R5) for example.
SUB: .
.
.
RTS R5
There is a lot going on at this point. The trick is to note that the
code does an RTS R5 to return. If people remember what happens at that
point, PC gets loaded with R5, while R5 gets loaded with the PC that we
actually would like to return to (since that's what is at the top of the
stack).
And R5 is pointing into the stack, at the MARK instruction, so execution
continues with actually performing the MARK.
MARK, in turn, will case SP <- PC + 2*N, thus restoring the stack
pointer to point to the place where the original R5 was stored.
Next, it does a PC <- R5, so that we now have the PC point to where we
actually want to return.
Next it does a R5 <- (SP)+, meaning we actually restored the original R5.
And so we have cleaned up the stack, preserved R5, and returned to the
caller again.
Also notice that the subroutine could have pushed any amount of data on
the stack before the return, and I suspect the idea was that the process
would not have needed to clean that up either. However, that fails,
since the RTS needs the return address at the top. But you can
essentially solve that by pushing -2(R5) before returning.
Ugly, isn't it? :-)
Johnny