From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <11c3f7123799c7bb2fb4637fc62a10f8@coraid.com> To: 9fans@cse.psu.edu Subject: Re: [9fans] Non-stack-based calling conventions From: Brantley Coile Date: Fri, 15 Feb 2008 19:23:22 -0500 In-Reply-To: <9f3897940802151547u69c34d7dr1e1b26d36501f71e@mail.gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Topicbox-Message-UUID: 57362daa-ead3-11e9-9d60-3106f5b1d025 Early Control Data machines, like many machines of the era, used the return address to fine the parameters. This meant that you put he parameters in the instruction stream right after the call to the subroutine. Here's the calling convention for your entertainment. 1) The calling program would put the parameters into memory locations just past the call to the subroutine. 2) Do a return-jump to the subroutine. This puts the return address in the first word of the subroutine and begins to execute the second word. 3) Parameters are accessed by using and incrementing the return address. 4) With the return address now safely stored in the first word of the subroutine, we can now return to the calling routine just by doing a indirect jump thru the first word of the routine. All this might not make sense to you so here is some code. This is CDC 1830 assembler, the best I can remember it. CDC 6600 works the same, but the code would be more confusing to the unfamiliar. . . * call sub(p1, p2) ena parm1 put the parameter into the A register sta p1 save it in the instruction stream right after the rtj ena parm2 we have two parameters. sta p2 rtj sub save RA at sub, begin executing at sub+1 p1 bss 1 p2 bss 1 jmp error * first address to return to . . . sub bss 1 place to keep the return address ldq sub lda (q) inq 1 point to next parameter lda (q) inq 2 point to last parameter and no error stq sub put parameter back jmp (sub) jmp indirect thru sub--return By convention there we would follow the parameters with a jump to an error handler and have the subroutine increment the RA another time in case the subroutine had no error. The IBM 7094 did a similar trick only it put the return address, or I should say the 2's complement of it, in an index register before it jumped to the subroutine. Parameters were picked up using the index register. (7094 indexes seem strange to us now, but they were *subtracted* from the base address in the instruction.) The subroutine used a form of the transfer instruction that added the number of words to the return address, er, I mean subtracted, to return to the caller. All the memory you would need was known as compile time. Writing assembler meant watching for trying to execute parameters as instructions. This does wonders for the design of the instruction cache. :)