CALL ABSOLUTE Hang; Assembly Must Use CB Return Instruction (42465)
The information in this article applies to:
- Microsoft QuickBASIC 4.0
- Microsoft QuickBASIC 4.0b
- Microsoft QuickBASIC 4.5
This article was previously published under Q42465 SUMMARY
An assembly-language routine accessed with CALL ABSOLUTE must use a
machine-language return instruction of CB hex (a far return), instead
of C3 hex (a near return).
The two programs shown below demonstrate that a program hangs if it
uses CALL ABSOLUTE on an assembly-language routine that returns with a
return instruction of C3 (Hex). To correct this problem, you must use
a return instruction of CB (hex).
This information applies to QuickBasic Versions 4.00, 4.00b, and 4.50
for MS-DOS, Microsoft Basic Compiler Versions 6.00 and 6.00b for
MS-DOS and MS OS/2, and Microsoft Basic PDS Version 7.00 for MS-DOS
and MS OS/2.
MORE INFORMATION
The far-return instruction CB (hex) correctly pops 4 bytes off the
stack for a segment and offset to return. Near-return C3 (hex) pops
only 2 bytes off the stack for an offset, which is inappropriate.
The following is a good reference for the machine instructions in the
Intel 8086 family of microprocessors: "The 80386 Book: Assembly
Language Programmer's Guide for the 80386," by Ross Nelson (published
by Microsoft Press, 1988).
The following program is TEST1.BAS. It calls an assembly-language
routine that prints an "A" on the screen. It uses the correct return
code of CB.
DIM ASMROUTINE(1 TO 6) AS INTEGER
DATA &H55 : ' PUSH BP Save base pointer
DATA &H8B,&HEC : ' MOV BP,SP Get our own
DATA &HB4,2 : ' MOV AH,2 Function 2 - print to screen
DATA &HB2,65 : ' MOV DL,65 Character 'A'
DATA &HCD,&H21 : ' INT 21H Make ROM BIOS call
DATA &H5D : ' POP BP Restore base pointer
DATA &HCB,0 : ' RET Far Return (correct) <-----
OFFSET = VARPTR(ASMROUTINE(1))
DEF SEG = VARSEG(ASMROUTINE(1))
' Poke assembly routine into memory:
FOR I = 0 TO 11
READ ASMCODE
POKE (OFFSET + I), ASMCODE
NEXT I
CALL ABSOLUTE(VARPTR(ASMROUTINE(1))) ' call routine we poked in
DEF SEG
END
The following program, TESTS.BAS, uses the incorrect return code and
hangs the machine:
DIM ASMROUTINE(1 TO 6) AS INTEGER
DATA &H55 : ' PUSH BP Save base pointer
DATA &H8B,&HEC : ' MOV BP,SP Get our own
DATA &HB4,2 : ' MOV AH,2 Function 2 - print to screen
DATA &HB2,65 : ' MOV DL,65 Character 'A'
DATA &HCD,&H21 : ' INT 21H Make ROM-BIOS call
DATA &H5D : ' POP BP Restore base pointer
DATA &HC3,0 : ' RET Near Return (incorrect) <-----
OFFSET = VARPTR(ASMROUTINE(1))
DEF SEG = VARSEG(ASMROUTINE(1))
' Poke assembly routine into memory:
FOR I = 0 TO 11
READ ASMCODE
POKE (OFFSET + I), ASMCODE
NEXT I
CALL ABSOLUTE(VARPTR(ASMROUTINE(1))) ' call routine we poked in
DEF SEG
END
Modification Type: | Minor | Last Reviewed: | 1/8/2003 |
---|
Keywords: | KB42465 |
---|
|