Path: utzoo!utgpu!attcan!uunet!cbmvax!carolyn From: carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) Newsgroups: comp.sys.amiga.tech Subject: Re: Parameters to Librhcr Keywords: Say, haven't I seen you before at the foo bar? Message-ID: <4473@cbmvax.UUCP> Date: 11 Aug 88 02:04:00 GMT References: <3716@hcr.UUCP> Reply-To: carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) Organization: Commodore Technology, West Chester, PA Lines: 97 In article <3716@hcr.UUCP> edwin@hcr.UUCP (Edwin Hoogerbeets) writes: > >I am working on interfacing C routines to Amiga shared librhcr, and I >need some help. > >A certain function is declared like this in C: > >LONG foo (alpha, bravo, charlie, delta) >LONG alpha, charlie; >struct boing *bravo, *delta; > >where 'struct boing' is some random structure unimportant to this >question. This function is actually an assembler routine in a library >that will take parameters as this declaration suggests. > >However, if I have the routine _foo in my library, in which registers >can I expect the Exec to put the parameters to _foo when calling it in >the library? The reason I want to know this is so that I may push these >values on to the stack again to call a C routine. > >I have looked in the RKM's and found nothing specific about that, but >from observation it seems that pointers are in the a[0|1] registers and >values go in the d[0|1] registers. What happens if there are more than 4 >parameters? 1. A0|1 and D0|1 are used alot for parameter passing because these registers are allowed to be trashed when you call a system routine. Programs can count on D2-D7 and A2-A7 being preserved when they call a system routine. Therefore, if any system routine requires args in any of these registers, the interface code in Amiga.lib must save these registers, pass the args in them, then restore them before returning. 2. It's kind of weird, but here's how it works if you have a C function calling a C routine in a run-time shared library: (hypothetical graphics.library BltOverEasy call) C program does OpenLibrary of graphics.library and stores Base address in globally visible GfxBase variable. C program calls BltOverEasy(lots,of,weird,things,and,more) which causes the args to be pushed on the stack as longs Assembler _BltOverEasy stub in Amiga.lib saves A6 and any untrashable registers needed for passing args to system BltOverEasy code, loads up the appropriate (individual to each function) registers with the arguments from the stack, puts GfxBase in A6, does jsr _LVOBltOverEasy(a6) (_LVOBltOverEasy being a negative hex word constant defined in Amiga.lib, and being the negative offset of the BltOverEasy entry in the GfxBase library jump table - note that these jump tables exist in memory preceding the library Base structure). The jsr hits the jump table which does (generally) a JMP to the rom (or ram) location of the actual library function code, at least the beginning of which is in assembler. Then, if the bulk of the library function happens to be in C, the assembler portion takes the args OUT of the registers, pushes them back on the stack, and jsr's to the C part of the library function. Then fixes the stack pointer when it returns. When all is done, the library function does an RTS with the result in d0. This returns to the stub code in Amiga.lib, which restores all untrashable registers, leaving the result in d0, and does an RTS which returns you to the C program. Note that this may seem like a lot of swapping around, but since the library calls expect their parameters in registers, it means that an assembler program calling a system function can just put the library base in A6, the args in registers, and jsr _LVOBltOverEasy. The current Amiga compilers provide methods for bypassing the Amiga.lib step, instead generating inline code to put your args directly in the appropriate registers and call the _LVO. I believe Manx does this via hard-coded interface code of their own, while Lattice does it via pragma files which are similar to include files but define which register should receive each argument. NOTE - See the couple of pages of text right before the library autodocs in the RKM (any version) for an example of the type of stub code in Amiga.lib. It's enough info to write your own mylib.lib linker lib for calling your own run-time library functions from C. -- ========================================================================== Carolyn Scheppner -- CATS Commodore Amiga Technical Support PHONE 215-431-9180 UUCP ...{uunet,allegra,rutgers}!cbmvax!carolyn Pad with zeros for a light, airy program. ==========================================================================