home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sys.mac.programmer
- Path: sparky!uunet!pageworks.com!world!eff!sol.ctr.columbia.edu!spool.mu.edu!agate!apple!mumbo.apple.com!gallant.apple.com!seuss.apple.com!user
- From: absurd@apple.apple.com (Tim Dierks, software saboteur)
- Subject: Re: help calling assembly from C
- Sender: news@gallant.apple.com
- Message-ID: <absurd-260193143226@seuss.apple.com>
- Date: Tue, 26 Jan 1993 22:57:21 GMT
- Distribution: usa
- References: <2B6198C1.22487@news.service.uci.edu> <keith-240193173019@kip-50.taligent.com>
- Organization: MacDTS Marauders
- Followup-To: comp.sys.mac.programmer
- Lines: 75
-
- In article <keith-240193173019@kip-50.taligent.com>, keith@taligent.com
- (Keith Rollin) wrote:
- >
- > In article <2B6198C1.22487@news.service.uci.edu>, eapg070@orion.oac.uci.edu
- > (Caroll Elke Pohl) wrote:
- > >
- > > i wonder if someone out there can assist me with a small problem.
- > > i'm using MPW (3.2) and want to call an assembly language subroutine
- > > i wrote from a C program _however_ i want to pass the parameters in
- > > A0 and A1 instead of using the stack (much like certain memory
- > > manager traps). how can i get the C compiler to recognize this fact?
- >
- > You came really close to answering your own question. You know that there
- > are Mac OS functions that work like this, so why don't you declare your
- > function the same way they are? For instance:
- >
- > #pragma parameter DisposePtr(__A0)
- > pascal void DisposePtr(Ptr p);
- >
- > This is an example of a function that simply takes a parameter in A0.
- > Here's a more complex example:
- >
- > #pragma parameter __D0 HoldMemory(__A0,__A1)
- > pascal OSErr HoldMemory(void *address,unsigned long count);
- >
- > HoldMemory takes the first parameter ("address") in A0, and the second
- > parameter ("count") in A1. It returns its result in D0 (which will be
- > treated like a short, because the function is declared to return an OSErr).
- >
- > -----
- > Keith Rollin
- > Phantom Programmer
- > Taligent, Inc.
-
- Unfortunately, MPW doesn't currently work this way (please correct me
- if I'm wrong). While it does use the #pragma register syntax to specify
- register passing, I believe it only works for hex inlined functions;
- i.e., it's only useful for specifying Toolbox calls or other code
- that doesn't require linking, because you can't specify symbols.
- This means that if your assembly routine is short (or even if it's not),
- you can assemble it, convert it to a bunch of hex constants, and
- define it in the same way MPW defines inline code:
-
- #pragma parameter __D0 MyWackyFunction(__A0)
- long MyWackyFunction(char *data) = {0xDEAD, 0xFACE, 0xBABE};
-
- or whatever your hex constants are. This should work as long as your
- assembly routine doesn't call other routines or refer to global
- variables; i.e., any routine which is entirely self-contained.
- Also, your function needs to take its arguments in particular
- registers: #pragma parameter can only pass arguments or get
- results in the "scratch" registers: D0, D1, D2, A0, and A1.
-
- This approach obviously isn't for all code. You've got two alternatives:
- the best one is just to write a little routine in assembly which pulls
- the arguments for the function off of the stack and puts them into
- registers, then calls the function, or convert your function so it
- takes its parameters on the stack. An alternative is to use a hex
- inlined function which takes its destination in a register and JSRs
- to it:
-
- #pragma parameter __D0 CallMyWackyFunction(__A0,__A1)
- long CallMyWackyFunction(char *data,void *myWackyFunctionPtr) = 0x4E91;
-
- (0x4E91 is the hex opcode for a JSR (A1)). You can call this like so:
-
- result = CallMyWackyFunction(data,MyWackyFunction);
-
- By passing a pointer to the routine you wish to call, this avoids the
- problem that the hex inline can't call the function itself because
- it can't contain symbols that need to be linked.
-
- Hope all this helps;
- Tim Dierks
- MacDTS, but I speak for myself
-