[<<Previous Entry]
[^^Up^^]
[Next Entry>>]
[Menu]
[About The Guide]
How FORCE Passes Parameters
--------------------------------------------------------------------
Before I answer the questions coming up, I think we should
have a quick discussion on how FORCE passes parameters. Understand-
ing of this is crucial to mixing ASM and FORCE effectively, so here
we go:
FORCE passes parameters in two different ways: by reference
and by value. When you pass by reference, FORCE passes the address
of the parameter rather than pushing the entire parameter on to the
stack, as is done when you pass by value. That is, when you pass
by value, you pass a copy of the original, and when you pass by
reference, you pass a pointer to the original.
FORCE decides on how to pass parameters by looking at the
function prototypes, and checking to see whether the "PARAMETERS"
part of the function prototype has the modifiers VALUE or CONST.
Make sense? Clear as mud, right? Here's code to say what I mean:
FUNCTION INT hash PROTOTYPE
PARAMETERS VALUE INT && will pass the actual integer, say 5
FUNCTION INT hash2 PROTOTYPE
PARAMETERS INT && will pass the full address, say 023A:0004
How to pass parameters from FORCE functions to ASM functions
--------------------------------------------------------------------
Q: What is involved in writing ASM routines for FORCE?
A: Writing ASM routines for FORCE is fairly straightforward, if you
know assembly language. I'm afraid a quick ASM tutor is beyond the
scope of this FAQ list, so if you don't know ASM, go learn it, and
then come back (see you in a bit). And, if you haven't read the
above section on "How FORCE Passes Parameters," do so now.
When writing ASM routines for FORCE, follow two rules of thumb:
1) All calls and pointers are far.
2) You must save DS, SI, ES, and DI for each routine.
What that translates to is that when you declare your "procs," you
can't declare them as NEAR (unless they are not called by FORCE),
and when you reference pointers from the stack, you must grab not
only the offset, but also the segment. Using the simplified segment
directive ".model large" can save you some work for the former, but
you have to do the latter by hand. Here's a quick little code segment
to say what I mean (and you seasoned ASM programmers, please refrain
from laughing at my code for a few minutes; ASM isn't my primary
language):
The force prototype looks like this:
FUNCTION INT hash PROTOTYPE
PARAMETERS char, value int
and the assembly would begin like this:
_hash proc far ; not near!
push bp ; set up our stack ref
mov bp,sp
push ds ; save the segment registers
push si
mov ax,word ptr ss:[ bp+8 ] ; grab the string's segment
mov ds,ax
mov ax,word ptr ss:[ bp+6 ] ; grab the string's offset
mov si,ax
mov dx,word ptr ss:[ bp+10] ; grab the hashvalue
... etc ...
pop si ; restore the segment registers
pop ds ; (we didn't use es or di)
pop bp
ret
_hash endp
Short and sweet as it is, that little code segment shows
both of the two "rules of thumb" I stated above, 1) that procedures
must be FAR, and 2) you must preserve the values of the DS:SI and
ES:DI segment:offset registers.
Recall from the section "How FORCE Passes Parameters" that
FORCE will pass the address of any parameter unless that parameter
is modified with the CONST of VALUE modifiers.
Therefore, when you write your assembler routines, be sure that
their corresponding FORCE prototypes are correct, or you'll destroy
your stack. For example, if the prototype for the function hash()
above looked like this:
FUNCTION INT hash PROTOTYPE
PARAMETERS VALUE char, VALUE int
FORCE would load the entire 255 (or whatever) characters of the
string on to the stack and then call your hash() function. If you
were expecting the address instead, you'd end up referencing a
string god-knows-where in memory, probably at 'lm':'Ho' or some-
thing like that.
If you stick with the two rules of thumb stated above, you'll
be okay. For anything more complicated than that, leave me a
message on the board and I'll take care of you there.
See Also:
General
Compatibility
This page created by ng2html v1.05, the Norton guide to HTML conversion utility.
Written by Dave Pearson