|
|
|
Page 1 of 1
|
[ 7 posts ] |
|
Author |
Message |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2095 Location: Canada
|
I was thinking about the concept of “call target” instructions which could prevent jumping or calling into the middle of a block of code. The way they work is they are placed at subroutine entry points. The subroutine call instruction then checks the target address to make sure a call target instruction is placed at the target address. If it isn’t a call target instruction then an exception is raised. Effectively the call has to land on a call target instruction. Has this been tried before ? What would drawbacks be ?
_________________Robert Finch http://www.finitron.ca
|
Tue Dec 20, 2016 9:00 am |
|
![](./styles/serenity/theme/images/spacer.gif) |
BigEd
Joined: Wed Jan 09, 2013 6:54 pm Posts: 1783
|
That's new to me! The only drawbacks I can think of are the obvious - a small time penalty and a small space penalty.
Thinking about it, in a machine with a Branch Target Buffer, you could perhaps arrange that only first calls would have a penalty - if the address is found in the BTB then it is already known, and blessed. Execution can proceed directly to the next instruction.
|
Tue Dec 20, 2016 1:21 pm |
|
![](./styles/serenity/theme/images/spacer.gif) |
Tor
Joined: Tue Jan 15, 2013 10:11 am Posts: 114 Location: Norway/Japan
|
The Norsk Data ND-500/ND-5000 32-bit supermini implemented that. It had two different CALL instructions, one which used the full set of 28 addressing modes (CALLG) and another with just an absolute address target (CALL). But both had the same constraint, quoting from the manual: "The subroutine address is a [direct|general] operand and it must refer to an entry point instruction. Otherwise an instruction-sequence error-trap condition occurs." The 'entry point instructions' were a set of instructions (ENTM/ENTD/ENTS/ENTSN/ENTF/ENTFN/ENTT/ENTB) which did local data initialisation for the subroutine, what it did depended on which ENT* instruction the programmer selected. ENTS, for example, had as argument the stack size required for the function. So these would be the 'call target' instructions, but they did useful stuff for the subroutine. The architecture relied on local stacks and optionally local data areas.
|
Tue Dec 20, 2016 2:12 pm |
|
![](./styles/serenity/theme/images/spacer.gif) |
BigEd
Joined: Wed Jan 09, 2013 6:54 pm Posts: 1783
|
That's nice, making the call entry instruction do some useful preamble work!
|
Tue Dec 20, 2016 2:31 pm |
|
![](./styles/serenity/theme/images/spacer.gif) |
Tor
Joined: Tue Jan 15, 2013 10:11 am Posts: 114 Location: Norway/Japan
|
However, it did not prevent jumping or branching into the middle of a function (I see now that Rob mentioned 'jumping' as well). The call/enter functionality was locked to each other, but you were free to jump into a function. When that function hit 'RET' (of which there were various variants) it would restore various registers, and stack frame set by the previous ENT* function, which would be from the function the jump came from, not from the local ENT* of the function you jumped into. But that was okay, the RET* functions would access the 'B' register (bottom of stack pointer) and pick various stored data from that stack frame. Which is where you actually came from. This would be similar to jumping into the middle of a function from another function, on a 6502. The return would work as excpected. What you can't do on the ND-500/5000 is to call a function, with parameters, and not hit an ENT* instruction. This makes sense when you have actual CALL instructions which take arguments for the subroutine you're calling. That machine had pretty high-level instructions, even the equivalent of strcmp().
|
Tue Dec 20, 2016 3:11 pm |
|
![](./styles/serenity/theme/images/spacer.gif) |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2095 Location: Canada
|
One idea to make the target instruction useful. If the target instruction were to load a register with the start address and length of a routine. Branches could be made offset from the target instruction (offset from the start of the routine). New addressing mode: target offset branches. The benefit of this mode would be that branches are restricted to branching only within the current subroutine. If the branch offset is greater than the current length in the target register then an exception could be raised. This does require a target register to be loaded and saved across subroutine calls though (part of the function prolog epilog code).
_________________Robert Finch http://www.finitron.ca
|
Fri Dec 23, 2016 6:07 am |
|
![](./styles/serenity/theme/images/spacer.gif) |
NorthWay
Joined: Thu Jan 17, 2013 4:38 pm Posts: 53
|
I've had this same thing in mind for a pie-in-the-sky design in the back of my head. But I have another factor I want to include: The MMU could keep status bits that maps pages so that if you do a jump into code from a less privileged page and it is not a FROM-TO pair then you get an exception. This for library and OS calls (not going through those rather expensive exception-type calls and not changing mappings etc - i.e. for SASOS inspired stuff).
|
Mon Jan 02, 2017 10:15 pm |
|
|
|
Page 1 of 1
|
[ 7 posts ] |
|
Who is online |
Users browsing this forum: No registered users and 5 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|