home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
FOXPRO
/
FFAQ
/
INTER_A.FAQ
< prev
next >
Wrap
Text File
|
1992-04-11
|
8KB
|
181 lines
FORCE FAQ (Frequently Asked Questions) (inter_a 1.1) 1
--------------------------------------------------------------------
Topic: INTERFACING WITH Assembler Author: David Holmes
What you'll find here:
( ) General discussion and easy FAQ answers
( ) How to pass parameters from FORCE to ASM functions
( ) Other, miscellaneous but frequently asked ASM/FORCE questions
Examples: A_EXMPL1.ZIP
General discussion and easy FAQ answers:
-------------------------------------------------------------------
The FORCE compiler and it's FORCE library were written in assembler
(those of you championing ASM clap now), so FORCE partakes of all
the advantages and disadvantages of writing in Assembler. Let's
outline those, just for fun:
The advantages: FORCE offers incredible control over the DOS
environment. The function "more_handles()" is a good example.
Assembly allows FORCE to generate the fastest run-time code of all
the xbase compilers, while still generating (usually by far) the
smallest and tightest run-time code.
The disadvantages: Non-portability being the primary one. We
can't just port the compiler to a Mac or UNIX environment by using
#ifdefs and huge Makefiles. Support is a little more difficult
also, when you have support personnel for whom 86 assembler is a
second or third or fourth language (comme moi-meme).
However, those are moot points, because FORCE is here, and
it has a lot of time and code invested in making it the quick and
tight compiler that it is. So lets look no further at advantages
or disadvantages and get on to the business at hand.
Compatibility:
-------------------------------------------------------------------
Q: Is FORCE compatible with XxX brand assembler?
A: Given the unique nature of Assembly Language, FORCE should be
compatible with nearly all Assemblers. However, I can only say for
sure that FORCE is compatible with MicroSoft's MASM and Borland's
TASM, the reason being that those are the only assemblers with
which I've tested (also, all of FORCE and its library were
developed with those two assemblers).
Q: Is FORCE compatible with XxX brand assembler linkers?
A: Of linkers, I can only say that MicroSoft's LINK.EXE
(versions 3.65 and lower) and Borland's TLINK.EXE (versions 2.0 and
lower) will work with FORCE. Blink Inc's BLINKer works also, and
I've heard that Zortech's BLINK.EXE (no relation to Blink Inc) works
also, but I can't confirm that last. Any others, and you're on your
own, though I can tell you that Borland's TLINK version 3.0 and 4.0
will NOT work.
-------------------------------------------------------------------
1
FORCE FAQ (Frequently Asked Questions) 2
-------------------------------------------------------------------
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 straight-forward,
if you know assembly language. I'm afraid a quick ASM tutorial
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.
(unless you don't trash them in your code).
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):
; FUNCTION INT hash PROTOTYPE
; PARAMETERS char, value int
-------------------------------------------------------------------
2
FORCE FAQ (Frequently Asked Questions) 3
-------------------------------------------------------------------
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.
P.S. One final note. Apparently, Borland's Turbo Assembler
(TASM) will generate non-standard code if you include the segment
directive DOSSEG. Your FORCE code won't work with your assembler
files if you have this directive in your assembly code and you
link with TASM.
-------------------------------------------------------------------
3