Category : Files from Magazines
Archive   : DDJ-9003.ZIP
Filename : HYDE.LST
Output of file : HYDE.LST contained in archive : DDJ-9003.ZIP
by Randall L. Hyde
[LISTING ONE]
[LISTING ONE]
page 62, 132
;
;****************************************************************************
; OBJECTS.ASM -- This program demonstrates object-oriented programming
; techniques in 8086 assembly language.
;
dseg segment byte public 'data'
;
; Unsigned Data Type:
Unsigned struc
Value dw 0
_Get_ dd ? ;AX = This
_Put_ dd ? ;This = AX
_Add_ dd ? ;AX = AX + This
_Sub_ dd ? ;AX = AX - This
_Eq_ dd ? ;Zero flag = AX == This
_Lt_ dd ? ;Zero flag = AX < This
Unsigned ends
;
; UVar lets you (easily) declare an unsigned variable.
UVar macro var
var Unsigned <,uGet,uPut,uAdd,uSub,uEq,uLt>
endm
;
; Signed Data Type:
Signed struc
dw 0
dd ? ;Get method
dd ? ;Put method
dd ? ;Add method
dd ? ;Sub method
dd ? ;Eq method
dd ? ;Lt method
Signed ends
;
; SVar lets you easily declare a signed variable.
SVar macro var
var Signed <,sGet, sPut, sAdd, sSub, sEq, sLt>
endm
;
; BCD Data Type:
BCD struc
dw 0 ;Value
dd ? ;Get method
dd ? ;Put method
dd ? ;Add method
dd ? ;Subtract method
dd ? ;Eq method
dd ? ;Lt method
BCD ends
;
; BCDVar lets you (easily) declare a BCD variable.
BCDVar macro var
var BCD <,bGet, bPut, bAdd, bSub, bEq, bLt>
endm
;
; Declare variables of the appropriate types (For the sample pgm below):
; Also declare a set of DWORD values which point at each of the variables.
; This provides a simple mechanism for obtaining the address of an object.
UVar u1
U1Adr dd U1 ;Provide convenient address for U1.
;
UVar u2
U2Adr dd U2 ;Ditto for other variables.
;
SVar s1
S1Adr dd s1
;
SVar s2
S2Adr dd s2
;
BCDVar b1
B1Adr dd b1
;
BCDVar b2
B2Adr dd b2
;
; Generic Pointer Variables:
Generic1 dd ?
Generic2 dd ?
;
dseg ends
;
cseg segment byte public 'CODE'
assume cs:cseg, ds:dseg, es:dseg, ss:sseg
;
_This equ es:[bx] ;Provide a mnemonic name for THIS.
;
; Macros to simplify calling the various methods
_Get macro
call _This._Get_
endm
;
_Put macro
call _This._Put_
endm
;
_Add macro
call _This._Add_
endm
;
_Sub macro
call _This._Sub_
endm
;
_Eq macro
call _This._Eq_
endm
;
_Lt macro
call _This._Lt_
endm
;
;****************************************************************************
; Methods for the unsigned data type:
uGet proc far
mov ax, _This
ret
uGet endp
;
uPut proc far
mov _This,ax
ret
uPut endp
;
uAdd proc far
add ax, _This
ret
uAdd endp
;
uSub proc far
sub ax, _This
ret
uSub endp
;
uEq proc far
cmp ax, _This
ret
uEq endp
;
uLt proc far
cmp ax, _This
jb uIsLt
cmp ax, 0 ;Force Z flag to zero.
jne uLtRtn
cmp ax, 1
uLtRtn: ret
;
uIsLt: cmp ax, ax ;Force Z flag to one.
ret
uLt endp
;
;****************************************************************************
; Methods for the unsigned data type.
sPut equ uPut ;Same code, why duplicate it?
sGet equ uGet
sAdd equ uAdd
sSub equ uSub
sEq equ uEq
;
sLt proc far
cmp ax, _This
jl sIsLt
cmp ax, 0 ;Force Z flag to zero.
jne sLtRtn
cmp ax, 1
sLtRtn: ret
;
sIsLt: cmp ax, ax ;Force Z flag to one.
ret
sLt endp
;
;****************************************************************************
; Methods for the BCD data type
bGet equ uGet ;Same code, don't duplicate it.
bPut equ uPut
bEq equ uEq
bLt equ uLt
;
bAdd proc far
add ax, _This
daa
ret
bAdd endp
;
bSub proc far
sub ax, _This
das
ret
bSub endp
;
;****************************************************************************
; Test code for this program:
TestSample proc near
push ax
push bx
push es
;
; Compute "Generic1 = Generic1 + Generic2;"
les bx, Generic1
_Get
les bx, Generic2
_Add
les bx, Generic1
_Put
;
pop es
pop bx
pop ax
ret
TestSample endp
;
; Main driver program
MainPgm proc far
mov ax, dseg
mov ds, ax
;
; Initialize the objects:
; u1 = 39876. Also initialize Generic1 to point at u1 for later use.
les bx, U1Adr
mov ax, 39876
_Put
mov word ptr Generic1, bx
mov word ptr Generic1+2, es
;
; u2 = 45677. Also point Generic2 at u2 for later use.
les bx, U2Adr
mov ax, 45677
_Put
mov word ptr Generic2, bx
mov word ptr Generic2+2, es
;
; s1 = -5.
les bx, S1Adr
mov ax, -5
_Put
;
; s2 = 12345.
les bx, S2Adr
mov ax, 12345
_Put
;
; b1 = 2899.
les bx, B1Adr
mov ax, 2899h
_Put
;
; b2 = 195.
les bx, B2Adr
mov ax, 195h
_Put
;
; Call TestSample to add u1 & u2.
call TestSample
;
; Call TestSample to add s1 & s2.
les bx, S1Adr
mov word ptr Generic1, bx
mov word ptr Generic1+2, es
les bx, S2Adr
mov word ptr Generic2, bx
mov word ptr Generic2+2, es
call TestSample
;
; Call TestSample to add b1 & b2.
les bx, B1Adr
mov word ptr Generic1, bx
mov word ptr Generic1+2, es
les bx, B2Adr
mov word ptr Generic2, bx
mov word ptr Generic2+2, es
call TestSample
;
mov ah, 4ch ;Terminate process DOS cmd.
int 21h
;
;
MainPgm endp
cseg ends
;
sseg segment byte stack 'stack'
stk dw 0f0h dup (?)
endstk dw ?
sseg ends
;
end MainPgm
[Example 1]
struct
{
int i;
int j;
char *c;
} S;
[Example 2]
SType struc
i dw ?
j dw ?
c dd ?
SType ends
[Example 3]
class Sc
{
int i;
int j;
char *c;
};
Sc *pS;
Tc *pT;
Tclass Tc:Sc
{
int k;
char *d;
};
[Example 4]
struct Tc Tc struc
{ i dw ?
int i; j dw ?
int j; c dd ?
char *c; k dw ?
int k; d dd ?
char *d Tc ends
};
[Example 5]
ScItems macro
i dw ?
j dw ?
c dd ?
endm
;
TcItems macro
ScItems
k dw ?
d dd ?
endm
;
Sc struc
ScItems
Sc ends
;
Tc struc
TcItems
Tc ends
[Example 6]
Sc struc
i dw ?
j dw ?
c dd ?
Sc ends
Tc struc
i dw ?
j dw ?
c dd ?
k dw ?
d dd ?
Tc ends
[Example 7]
Sc struc
i dw ?
j dw ?
c dd ?
Sc ends
Tc struc
dw ?
dw ?
dd ?
k dw ?
d dd ?
Tc ends
S Sc
T Tc
[Example 8]
Sc struc
i dw ?
j dw ?
c dd ?
Sc ends
Tc struc
db (size Sc) dup (?)
k dw ?
d dd ?
Tc ends
Uc struc
db (size Tc) dup (?)
e dw ?
Uc ends
S Sc
T Tc
U Uc
[Example 9]
class Sc
{
int i,j;
char *c;
public:
int geti() {return i}; /* Ignore the fact that C++ */
int getj() {return j}; /* would implement these */
void seti(x) int x; {i = x;}; /* methods in-line. */
void setj(x) int x; {j = x;};
};
[Example 10]
Sc struc
i dw ?
j dw ?
c dd ?
geti dd Sc_geti
getj dd Sc_getj
seti dd Sc_seti
setj dd Sc_setj
Sc ends
S Sc
[Example 11]
_THIS equ es:[bx]
Sc_geti proc far
mov ax, _THIS.i
ret
Sc_geti endp
[Example 12]
mov bx, seg S1
mov es, bx
mov bx, offset S1
call S1.geti ;Assuming S1 is in the data seg.
[Example 13]
;
; Inline expansion of geti to improve efficiency:
;
_Geti macro
mov ax, _THIS.i
endm
;
; Perform actual call to routines which are too big to
; expand in-line in our code:
;
_Printi macro
call _THIS.Printi
endm
.
.
.
_Geti ;Get i into AX.
.
.
.
_Printi ;Call Printi routine.
[Example 14]
Shape struc
ulx dw ? ;Upper left X coordinate
uly dw ? ;Upper left Y coordinate
lrx dw ? ;Lower right X coordinate
lry dw ? ;Lower right Y coordinate
Draw dd Shape_Draw ;Default (overridden) DRAW routine
Shape ends
;
Rect struc
dw 4 dup (?) ;Reserve space for coordinates
dd Rect_Draw ;Draw a rectangle
Rect ends
;
Circle struc
dw 4 dup (?) ;Reserve space for coordinates
dd Circle_Draw ;Draw a circle
Circle ends
[Example 15]
mov cx, size rect
call alloc
mov word ptr MyRectPtr, bx
mov word ptr MyRectPtr+2, es
[Example 16]
mov ax, offset rectDRAW
mov _this.DRAW, ax
mov ax, seg rectDRAW
mov _this.DRAW+2, ax
[Example 17]
mov cx, size circle
call CreateCircle
mov word ptr CircVarPtr, bx
mov word ptr CircVarPtr+2, es
;
mov cx, size rect
call CreateRect
mov word ptr RectVarPtr, bx
mov word ptr RectVarPtr+2, es
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/