2.  CALL ABSOLUTE

Back Home Up Next

In order to actually use an assembly routine, you have to be able to cause the CPU to access it.  QBASIC does make provisions for this.

Using assembly from QBASIC

QBASIC offers only one method for calling assembly routines or, in general, anything outside of standard QBASIC code.  This is CALL ABSOLUTE.

What you learn about CALL ABSOLUTE will be useful in the various Quick BASIC compilers, too.  (QBASIC itself is not a compiler.)  Those compiler products also support it.  However, there are also much better methods for integrating assembly language code when you are using a real compiler tool.  So unless you intend to maintain backward compatibility with the QBASIC interpreter, the process of writing and using assembly language programs for Microsoft's BASIC compilers is a bit different.

When CALL ABSOLUTE is used, QBASIC simply transfers control to a given memory location.  QBASIC doesn't have any way of verifying if there is a valid subroutine there, so you must be sure that things are properly set up and that you specify the address (memory location) correctly.  Otherwise, a system crash is almost always the inevitable result.

Also, correctly starting a valid subroutine isn't everything.  That routine must take care to understand the details which QBASIC sets up and it must correctly return control back to QBASIC when it is finished.  Getting these details correct is the larger part of a satisfying session of assembly programming with QBASIC.

Getting there

The essence of correctly calling the assembly code with CALL ABSOLUTE is to properly tell QBASIC the information it needs.  In DOS, there are two pieces required to make up a complete, segmented address:  the segment and the offset.  These are each, in effect, INTEGER values.  QBASIC provides methods for figuring out the right values so that you can tell it where it needs to begin, when you want to call an assembly program.

QBASIC doesn't just know, by intuition or extra-sensory perception, where your assembly program is at.  Just typing raw numbers into DATA statements or placing them into an array isn't enough.  QBASIC needs you to be explicit and accurate, down to the last detail.  So the job is yours.

QBASIC provides several features related to notifying QBASIC where your assembly program is located.  The VARSEG() function in QBASIC allows you to find out the segment portion of the address for arrays.  The VARPTR() function allows you to find out the offset portion, too.  Between these two functions in QBASIC, you can get both pieces needed before you can correctly use CALL ABSOLUTE.

Once you have them, you need to tell QBASIC that you intend to use them.  You do this with two statements in QBASIC.  The first is DEF SEG, which is used to tell QBASIC the value of the segment portion of the address of your program.  The second is CALL ABSOLUTE, itself, which allows you to supply many parameters but for which the last parameter is always used to tell QBASIC the value of the offset portion of the address of your program.  (QBASIC could have let you do all this in a single statement, but that's not how they did it.  So you just have to live with using both.)

So, DEF SEG will be associated with values you extract using the VARSEG() function and CALL ABSOLUTE will be associated with values you extract using the VARPTR() function.  At least, that gets the address set up correctly so that you can get to the subroutine.  Of course, there is much more than that in order understand enough of the process to make useful programs.  But this is a start.

Let's now take a look at another aspect of using CALL ABSOLUTE, how to pass parameters to your assembly subroutines and return calculated values back to your QBASIC code.

 

Last updated: Thursday, June 17, 2004 19:28