Q(uick)BASIC Keyword: ABSOLUTE
Quick View
ABSOLUTE Keyword
CALL ABSOLUTE - a statement that transfers control to a machine-language procedure
Worth knowing
Useful and cross-version information about the programming environments of QBasic and QuickBasic.
Syntax
- CALL ABSOLUTE ([argumentlist,] offset%)
Description/Parameter(s)
argumentlist | Arguments passed to a machine-language procedure as offsets from the current data segment. |
offset% | The offset from the current code segment, set by DEF SEG, to the starting location of the procedure. |
Example
Calls routine for printing the screen to a local printer.
DIM a%(2)
DEF SEG = VARSEG(a%(0))
FOR i% = 0 TO 2
READ d%
POKE VARPTR(a%(0)) + i%, d%
NEXT i%
DATA 205, 5, 203 : ' int 5 retf 'Machine-language code
'for printing screen.
CALL ABSOLUTE(VARPTR(a%(0)))
DEF SEG
See also:
Syntax
- CALL ABSOLUTE ([argumentlist,]integervariable)
Description/Parameter(s)
argumentlist | Optional arguments passed to a machine-language procedure. |
integervariable | An integer variable containing a value that is the offset from the beginning of the current code segment, set by DEF SEG, to the starting location of the procedure. The integervariable argument is not passed to the procedure. Your program may need to execute a DEF SEG statement before executing CALL ABSOLUTE to set the code segment for the called routine. |
Using a noninteger value for integervariable produces unpredictable results. |
Arguments in argumentlist are passed to the machine-language program as offsets (near pointers) from the current data segment. Although arguments are passed as offsets, the machine-language program is invoked with a far call.
Note: | The CALL ABSOLUTE statement is provided to maintain compatibility with earlier versions of BASIC. Mixed-language programming using the CALL statement extensions and the new DECLARE statement provide a simpler way to use assembly language with BASIC. |
Also, in order to use CALL ABSOLUTE you must start QuickBASIC with the correct Quick library, link your program with QB.LIB, or use the QB.QLB Quick library. See the disk-contents list for the locations of these files. |
Differences from BASICA
- Assembly-language programs that are invoked from BASICA and that have string arguments must be changed because string descriptors are now four bytes long. The four bytes are the low byte and high byte of the string length followed by the low byte and high byte of the string address.
Example
The following example uses CALL ABSOLUTE to execute a machine-language program stored in an array:
CONST nASMBYTES=14
' This program prints a message indicating whether or not
' a math coprocessor is installed.
' It uses a machine-language program stored in an array
' to get the information from the operating system.
'AsmBytes is a label; nASMBYTES is a symbolic constant.
DEFINT A-Z
DIM AsmProg(1 TO (nASMBYTES/2))
' The machine-language program stored as data to read into
' the array.
AsmBytes:
DATA &H55 :'PUSH BP Save base pointer.
DATA &H8B, &HEC :'MOV BP,SP Get our own.
DATA &HCD, &H11 :'INT 11H Make the ROM-BIOS call.
DATA &H8B, &H5E, &H06 :'MOV BX,[BP+6] Get argument address.
DATA &H89, &H07 :'MOV [BX],AX Save list in argument.
DATA &H5D :'POP BP Restore base pointer.
DATA &HCA, &H02, &H00 :'RET 2 Pop argument off stack
' and make far return.
' Get the starting offset of the array.
P=VARPTR(AsmProg(1))
' Poke the machine-language program into the array.
DEF SEG=VARSEG(AsmProg(1)) ' Change the segment.
Restore AsmBytes
FOR I=0 TO nASMBYTES-1
READ J
POKE(P+I),J
NEXT I
' Execute the program. The program expects a single integer argument.
CALL ABSOLUTE(X%,VARPTR(AsmProg(1)))
DEF SEG ' Restore the segment.
' X% now contains bit-encoded equipment list returned by DOS.
' Mask off all but the coprocessor bit (bit 2).
CoProcessor=X% AND &H2
' Print the appropriate message.
IF CoProcessor=2 THEN
PRINT "Math coprocessor present."
ELSE
PRINT "No math coprocessor."
END IF
END
See also:
Syntax
- CALL ABSOLUTE ([argumentlist,] integervariable%)
Description/Parameter(s)
argumentlist | Arguments in argumentlist are passed to the machine-language program as offsets (near pointers) from the current data segment. Although arguments are passed as offsets, the machine-language program is invoked with a far call. |
integervariable% | The integervariable% is not passed to the procedure. Your program may need to execute a DEF SEG statement before executing Absolute to set the code segment for the called routine. |
Using a noninteger value for integervariable% produces unpredictable results. |
Important
- To use the Absolute routine in the QBX environment, use the QBX.QLB Quick library. To use Absolute outside the QBX environment, link your program with the QBX.LIB file.
- The QBX.BI header file contains the necessary declarations for the Absolute routine.
- The Absolute routine is provided to maintain compatibility with earlier versions of BASIC. Mixed-language programming using the CALL and DECLARE statements provide a simpler way to use assembly language with BASIC.
Programming with OS/2
- When using the Absolute routine in OS/2 protected mode, be careful not to refer to an illegal memory address. Before it executes the Absolute routine, BASIC attempts to get an executable- code-segment alias for the code you wish to access. If this operation fails, BASIC generates the error message, "Permission denied." A safe place to store user-written machine code is in memory allocated for a conventional BASIC object, such as an array.
Differences from BASICA
- Assembly-language programs that are invoked from BASICA and that have string arguments must be changed because string descriptors are now 4 bytes long. For a near-string descriptor, the 4 bytes are the low byte and high byte of the string length followed by the low byte and high byte of the string address. Far-string descriptors are also 4 bytes long, but their structure is proprietary. For more information on using far-string descriptors, see "Mixed-Language Programming" and "Advanced Programming with Far Strings" in the Programmer's Guide.
- The Absolute routine replaces the BASICA CALL statement.
Example
The following example uses the Absolute routine to execute a machine-language program stored in an array. The program prints a message indicating whether or not a math coprocessor is installed. Note: To use the Absolute routine, you must load the Quick library QBX.QLB using the /L switch when you begin QBX.
'AsmBytes is a label; nASMBYTES is a symbolic constant.
CONST nASMBYTES = 14
DEFINT A-Z
DIM AsmProg(1 TO (nASMBYTES / 2))
'The machine-language program stored as data to read into the array.
AsmBytes:
DATA &H55 : 'PUSH BP Save base pointer.
DATA &H8B, &HEC : 'MOV BP,SP Get our own.
DATA &HCD, &H11 : 'INT 11H Make the ROM-BIOS call.
DATA &H8B, &H5E, &H06 : 'MOV BX,[BP+6] Get argument address.
DATA &H89, &H07 : 'MOV [BX],AX Save list in argument.
DATA &H5D : 'POP BP Restore base pointer.
DATA &HCA, &H02, &H00 : 'RET 2 Pop argument off stack
' and make far return.
'Get the starting offset of the array.
P = VARPTR(AsmProg(1))
'Poke the machine-language program into the array.
DEF SEG = VARSEG(AsmProg(1)) 'Change the segment.
FOR I = 0 TO nASMBYTES - 1
READ J
POKE (P + I), J
NEXT I
'Execute the program. The program expects a single integer argument.
CALL Absolute(X%, VARPTR(AsmProg(1)))
DEF SEG ' Restore the segment.
'X% now contains bit-encoded equipment list returned by DOS.
'Mask off all but the coprocessor bit (bit 2).
CoProcessor = X% AND &H2
'Print the appropriate message.
IF CoProcessor = 2 THEN
PRINT "Math coprocessor present."
ELSE
PRINT "No math coprocessor."
END IF
END
See also: