-
Notifications
You must be signed in to change notification settings - Fork 2
/
ABSOLUTE.ASM
118 lines (106 loc) · 4.19 KB
/
ABSOLUTE.ASM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
TITLE ABSOLUTE - helper for assembly routines
;***
; ABSOLUTE - Helper for calling BASIC interpreter assembly routines
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
; Allow a BASIC program to call a routine which is located at an
; absolute memory address in the DEF SEG.
;
; The form of the call is:
;
; CALL ABSOLUTE(<param>,...,<loc>)
;
; where
; <param>,... - zero or more parameters for the assembly routine
; <loc> - an Integer variable that contains the
; location in the DEF SEG of the start of
; the assembly routine
;
; The location parameter will be removed, and the routine at DEF SEG:<loc>
; will be called with the remaining parameters.
;
; Notes:
; - The parameters are not checked or verified before being passed
; to the assembly routine.
; - CALL must be used. CALLS will cause execution to jump to a
; random location.
; - The DOSSEG, .MODEL, .CODE, and .DATA? directives are part of
; the simplified segment system of MASM 5.0. If you have an
; earlier version of MASM, you must modify the source to define
; the segments required by Microsoft high-level languages. These
; segments are discussed in Appendix C of "Learning and Using
; QuickBASIC."
;
;******************************************************************************
;
DOSSEG ;requires MASM 5.0 or higher
.MODEL medium
; Define the routine as public.
PUBLIC ABSOLUTE
; Define the seg segment
.DATA?
EXTRN b$seg:WORD ;seg segment
;***
; ABSOLUTE - Call absolute address
;
;Purpose:
; Routine which can be directly called from the basic level which in turn
; calls an absolute address.
;
;Entry:
; The actual number of parameters is variable, and depends on the routine
; that ABSOLUTE will in turn call. The LAST parameter pushed MUST be the DS
; offset of an integer variable containing the offset of the routine to be
; called. The current DEF SEG is used as the segment for the call.
;
;Exit:
; Whatever the called routine elects. We do NOT return here.
;
;Uses:
; This routine follows convention, but does no saving or checking of the code
; actually called.
;
;Notes:
; The called routine receives control with all parameters passed to ABSOLUTE,
; except the offset integer, on the stack in Pascal convention. The return
; address present is back to the BASIC level code which CALLed ABSOLUTE.
;
; Stack on call to ABSOLUTE:
;
;
; \ Variable number of parameters \
; | to routine to be CALLed |
; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
; | Near pointer to I2 var containing |
; | the offset of the routine to CALL |
; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
; |CS |
; + Far return address to caller of ABSOLUTE +
; [SP] -> |IP |
; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;
; Stack on transfer to called routine:
;
; \ Variable number of parameters \
; | to routine to be CALLed |
; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
; |CS |
; + Far return address to caller of ABSOLUTE +
; [SP] -> |IP |
; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;
;******************************************************************************
.CODE
ABSOLUTE PROC FAR
POP AX ;return offset
POP DX ;return segment
POP BX ;get pointer to routine address
PUSH DX ;restore return address
PUSH AX
PUSH [b$seg] ;stack DEF SEG segment
PUSH [BX] ;stack routine offset
RET ;jump to ABSOLUTE routine
ABSOLUTE ENDP
END