View unanswered posts | View active topics It is currently Mon Oct 23, 2017 4:20 am



Reply to topic  [ 7 posts ] 
 Call target instructions 
Author Message

Joined: Sat Feb 02, 2013 9:40 am
Posts: 448
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
Profile WWW

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 800
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
Profile

Joined: Tue Jan 15, 2013 10:11 am
Posts: 94
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
Profile

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 800
That's nice, making the call entry instruction do some useful preamble work!


Tue Dec 20, 2016 2:31 pm
Profile

Joined: Tue Jan 15, 2013 10:11 am
Posts: 94
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
Profile

Joined: Sat Feb 02, 2013 9:40 am
Posts: 448
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
Profile WWW

Joined: Thu Jan 17, 2013 4:38 pm
Posts: 43
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
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 7 posts ] 

Who is online

Users browsing this forum: No registered users and 1 guest


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

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software