Objektumosztályok
Az assembly nyelvben a STRUC kulcsszóval lehet objektumosztályokat létrehozni. Egy osztálynak lehetnek mezői, és műveletei, és az osztályok között lehetséges egyszeres öröklődés.
STRUC osztálynév [módosító][ősosztály]METHOD[eljárások]
mezők
ENDS [osztálynév]
A fentiek részletesebben:
[módosító] értéke lehet:
GLOBAL - az osztály publikus, mindenhonnan elérhető és exportálható
NEAR - az osztály címe egy offsetcím, csak a szegmensen belül elérhető
FAR - az osztály címe egy szegmens+offset pár, vagyis a definiáló szegmensen kívülről is elérhető
[ősosztály]
Csak egyszeres öröklődés létezik, tehát ide egy osztály neve kerülhet, aminek a mezőit és eljárásait a leszármazott osztály örökli.
[eljárások]
Kétféle eljárása lehet egy osztálynak, statikus és virtuális. A statikus eljárások ugyanolyan eljárásoknak minősülnek, mint a hagyományos eljárások. A public kulcsszóval publikussá kell őket tenni, hogy más forrásfile-okból is látni lehessen. Ahonnan el akarjuk érni, ott az extrn kulcsszóval ezt jelezni kell. A virtuális eljárásokat a virtual kulcsszóval kell megkülönböztetni. Ezeknek a címét kívülről nem közvetlenül, hanem a VMT (virtual method table) segítségével lehet elérni. A VMT-t a TBLINIT, TBLINST, TBLPTR kulcsszavakkal érhetjük el egy osztályból.
TBLINST
Létrehoz egy bejegyzést a VMT-ben a legutoljára definiált osztály számára.
TBLINIT
Egy pointer regiszter értékét beállítja az adott osztály VMT-beli bejegyzésére. Az osztály eljárásaiban lehet használni.
Példa: ESI pointer regiszter beállítása az osztály VMT bejegyzésére.
TBLINIT (Osztálynév ESI)
TBLPTR
A mezők között lehet elhelyezni. Létrehoz egy @Mptr_osztálynév mezőt az adott osztálynak, ami az adott osztály VMT-beli bejegyzésére mutat. A használata nem kötelező, alapértelmezésben az összes mező után az assembler mindenképpen elhelyezi ezt a mezőt. A TBLPTR használatával csupán a mező elhelyezését határozzuk meg. A @Mptr_osztálynév mezőre egyáltalán nincs szükség, ha az osztály nem rendelkezik virtuális metódusokkal. Ebben az esetben a TBLINST, TBLINIT, TBLPTR kulcsszavak egyike sem generál semmiféle kódot.
mezők
Ugyanazon a módon lehet mezőket megadni, mint a rekord típus esetén
Egy eljárás hívása az alábbi módon történik:
CALL objektum METHOD [osztálynév:] eljárásnév
"objektum" legyen egy a megfelelő objektumra mutató pointer, az eljárásnév pedig a meghívott eljárás neve. Gyakran előfordul, hogy a pointerről nem lehet eldönteni, hogy milyen osztályra mutat, erre az esetre az eljárásnév előtt egy : jellel a végén meg lehet adni az osztálynevet.
Egy példa objektumok használatára:
; publikusak a függvények
global pelda_Init :proc
global pelda_Done :proc
global pelda_pelda1 :proc
global pelda_pelda2 :proc
; az osztály deklarációja
STRUC pelda METHOD {
Init :CODEPTR = pelda_Init ; statikus metódusok
Done :CODEPTR = pelda_Done
VIRTUAL pelda1 :CODEPTR = pelda_pelda1 ; virtuális metódusok
VIRTUAL pelda2 :CODEPTR = pelda_pelda2
} ; metódusok rész vége
TBLPTR ; VMT pointer
field1 dd ? ; Private mezők
Reserved dd ?
field2 dd ? ; Public mezők
ENDS pelda
[...]
include "pelda.aso"
CONST
TBLINST ; VMT létrehozása és inicializálása
CODESEG
[...]
; az osztály konstruktora
proc pelda_Init
arg pObj:DATAPTR
uses esi
mov esi, [pObj] ; példány pointere esi regiszterbe
; adattagok inicializálása
TBLINIT (pelda esi) ; VMT pointer beállítása
mov [(pelda esi).field1], ertek1 ;alapértékek megadása
mov [(pelda esi).field2], ertek2
mov eax, 1
RET
endp
; különféle szerepeket láthat el, ez az osztály destruktora
proc pelda_Done
[...]
mov eax, 1
RET
endp
END
proc pelda1
[...]
endp
proc pelda2
[...]
endp
[...]
include "pelda.asm"
CODESEG
[...]
; objektum létrehozása
UDATASEG
peldany pelda {}
CODESEG
[...]
; konstruktor meghívása
CALL peldany METHOD Init, offset(peldany)
; DS:ESI az objektum címére
lea esi, [peldany]
; az osztály műveleteinek használata
[...]
CALL (pelda esi) METHOD pelda1
CALL (pelda esi) METHOD pelda2
; az objektum "megszüntetése"
[...]
CALL (pelda esi) METHOD Done USES ds:ecx
[...]
END