-
Notifications
You must be signed in to change notification settings - Fork 5
/
DMTH.ASM
95 lines (71 loc) · 1.49 KB
/
DMTH.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
; *******************************************************
; * *
; * Turbo Pascal Run-time Library *
; * Dynamic Method Call Dispatcher *
; * *
; * Copyright (c) 1989,92 Borland International *
; * *
; *******************************************************
TITLE DMTH
INCLUDE SE.ASM
; Virtual method table layout
vmtInstSize EQU (WORD PTR 0)
vmtInstCheck EQU (WORD PTR 2)
vmtDMTPtr EQU (WORD PTR 4)
vmtReserved EQU (WORD PTR 6)
vmtEntryTable EQU (DWORD PTR 8)
; Dynamic method table layout
dmtParent EQU (WORD PTR 0)
dmtCacheIndex EQU (WORD PTR 2)
dmtCacheEntry EQU (WORD PTR 4)
dmtEntryCount EQU (WORD PTR 6)
dmtEntryTable EQU (WORD PTR 8)
CODE SEGMENT BYTE PUBLIC
ASSUME CS:CODE
; Externals
EXTRN HaltError:NEAR
; Publics
PUBLIC FindMethod,CallMethod
; Find dynamic method
FindMethod:
CALL GetMethod
RETF
; Call dynamic method
CallMethod:
CALL GetMethod
JMP DWORD PTR [DI]
; Find dynamic method
; In AX = Dynamic method index
; DI = Virtual method table pointer
; Out DI = Pointer to method vector
GetMethod:
MOV BX,[DI].vmtDMTPtr
CMP AX,[BX].dmtCacheIndex
JNE @@1
MOV DI,[BX].dmtCacheEntry
RET
@@1: MOV SI,DS
MOV ES,SI
MOV SI,BX
CLD
@@2: MOV CX,[BX].dmtEntryCount
MOV DX,CX
LEA DI,[BX].dmtEntryTable
REPNE SCASW
JE @@3
MOV BX,ES:[BX].dmtParent
OR BX,BX
JNE @@2
POP AX
MOV AX,210
JMP HaltError
@@3: DEC DX
SHL DX,1
SUB DX,CX
SHL DX,1
ADD DI,DX
MOV [SI].dmtCacheIndex,AX
MOV [SI].dmtCacheEntry,DI
RET
CODE ENDS
END