[futurebasic] Re: Inline Assembly - assem. newbie Question

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : December 1997 : Group Archive : Group : All Groups

From: Chris.Young@...
Date: Fri, 5 Dec 1997 09:39:03 -0600
To add to the excellent info which Rick already provided, here is another 
message from Rick detailing asm Toolbox trap translation into FB.

hth

Chris

================================================================================
John wrote:
>So I guess the next question is, how on earth did you 
>come up with the assembly code?

Mainly from looking at the C and/or Pascal header files that 
Apple publishes.  I get them on CD regularly because I subscribe 
to their Developer Program.  My guess is that you can also find 
them somewhere in the Developer section(s) of Apple's web sites.
When I look in the header file "Files.h", for example, I find this:

pascal OSErr FSMakeFSSpec(short vRefNum,long dirID,ConstStr255Param fileName,
 FSSpecPtr spec)
 = {0x303C,0x0001,0xAA52}; 

Pascal functions (on the Mac) work by first reserving space on the 
"stack" for the function result (in this case, a value of type "OSErr", 
which is always 2 bytes).  This is done in assembly like so:

`    clr.w -(sp)    ;clear a word (2 bytes) on the stack

Pascal functions next "push" each of their parameters onto the stack. 
Each parameter is either 2 bytes or 4 bytes long.  Any data which is 
longer than this (such as a string) is always passed as a 4-byte 
_pointer_ to the data.  To "push" data onto the stack in assembly, 
you do statements like this:

`    move.w  ^vRefNum%,-(sp)
`    move.l  ^dirID&,-(sp)
`    move.l  ^filenamePtr&,-(sp)
`    move.l  ^specPtr&,-(sp)

Next you look at the "guts" of the Pascal call, which in this case is:

 = {0x303C,0x0001,0xAA52}; 

These are just literal machine language instructions.  The easiest 
way to do them in FB is with the 'dc.w' directive:

`    dc.w $303C,$0001,$AA52

..but if you want your code to look prettier, you can figure out just 
how "0x303C,0x0001,0xAA52" translates into assembly opcodes.
The way I do that is to drop into MacsBug and type "dh 303C 0001 AA52". 
MacsBug tells me that this means:

   MOVE.W  #$0001, D0
   _FSMakeFSSpec

I can add that first line as-is into my FB assembly code.  The second 
line is MacsBug's intelligent way of translating "AA52", which is a
so-called "trap word" and not really a valid machine language instruction. 
The way I'd write these lines in FB is:

`    move.w  #$0001,d0
`    dc.w $AA52

Finally, a Pascal function gets its return value by "popping" it off of the 
stack.  To emulate this in assembly:

`    move.w  (sp)+,^OSErr

and that's that.  I'm led to believe that FBIII will allow us to define 
local functions which automatically manipulate the stack using
Pascal conventions: in that case, the whole function would just 
look something like this:

LOCAL PASCAL FN FSMakeFSSpec(vRefNum%,dirID&,namePtr&,specPtr&) 
`    move.w  #$0001,d0
`    dc.w $AA52
END FN

>And why can't FB support the whole toolbox?  I can't wait 
>until FB III (and PowerMac native code), when this inline assembly code 
>is going to start dying...

Well, if Apple would just stop coming up with brand new Toolbox 
calls, maybe FB _could_ support the whole toolbox  :-)  I think FB 
probably supports all the TB routines that existed at the time FB 
was written, and I'd imagine that FBIII will support all the new 
ones that have come into existence since then, but as long as Apple 
continues to create new API's, I can't see assembly stuff going 
away.  If it's any consolation, C and Pascal programmers have to 
implement _all_ the Toolbox routines in assembly code; they just 
don't "notice" it, because Apple has kindly written it all in header 
files which said programmers must include when they compile.
At least FB has some _built-in_ support, which few other languages 
offer.

And finally, I _like_ having the option of doing some stuff in 
assembly.  Occasionally I'll have a need to do some fairly simple 
but very, very repetitive algorithm: writing it in assembly code 
has given me some dramatic speed improvements in such cases.

- Rick