home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1990
/
03
/
hyde.lst
< prev
next >
Wrap
File List
|
1990-02-13
|
12KB
|
557 lines
OBJECT-ORIENTED PROGRAMMING IN ASSEMBLY LANGUAGE
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