-
1
4.
DEFINISANJE PODATAKA
MASM definie tzv. unutranje tipove podataka (intrinsic data
types), od kojih svaki
opisuje skup vrednosti koje se mogu dodeliti promenljivama i
izrazima datog tipa. Osnovna
osobina svakog tipa je njegova veliina u bitovima: 8, 16, 32,
48, 64 i 80. Druge osobine (kao
to su znak, pokaziva ili zapis u pokretnom zarezu) su opcioni i
uglavnom slue programerima
kao podsetnici o tipu podataka koji je smeten u promenljivoj. Na
primer, promenljiva koja je
deklarisana kao DWORD, uglavnom sadri neoznaene 32-bitne cele
brojeve. Meutim, ona
moe da sadri i oznaeni 32-bitni ceo broj, 32-bitni realni broj
jednostruke preciznosti ili 32-
bitni pokaziva. Asembler nije case-sensitive, tako da se
direktiva DWORD moe pisati kao
dword, Dword, dWord, itd.
U tabeli 1, svi tipovi podataka, osim poslednja tri, se odnose
na cele brojeve. Kod
poslednja tri tipa, IEEE notacija se odnosi na standardizovane
formate realnih brojeva koje je
doneo IEEE Computer Society.
Tabela 1. Unutranji tipovi podataka
Tip podatka Opis
BYTE 8-bitni neoznaeni ceo broj; B je skraeno od bajt
SBYTE 8-bitni oznaeni ceo broj; S je skraeno od signed (sa
znakom)
WORD 16-bitni neoznaeni ceo broj
SWORD 16-bitni oznaeni ceo broj
DWORD 32-bitni neoznaeni ceo broj; D je skraeno od double
(dvostruki)
SDWORD 32-bitni oznaeni ceo broj; SD je skraeno od signed double
(oznaeni dvostruki)
FWORD 48-bitni ceo broj (F je skraeno od far pointer)
QWORD 64-bitni ceo broj (Q je skraeno od quad)
TBYTE 80-bitni ceo broj (T je skraeno od Ten-byte)
REAL4 32-bitni IEEE kratki (short) realan broj
REAL8 64-bitni IEEE dugaak (long) realan broj
REAL10 80-bitni IEEE proireni (extended) realan broj
-
2
2.1 Iskazi za definisanje podataka
Iskazi za definisanje podataka alociraju memoriju za
promenljivu, sa opcionim imenom.
Iskazi za definisanje podataka kreiraju promenljivu na osnovu
unutranjih tipova podataka
(tabela 1). Definicija podataka ima sledeu sintaksu:
[ime] direktiva inicijalizator [, inicijalizator]
Sledi primer iskaza za definisanje podatka:
count DWORD 12345
Ime
Opciono ime koje se dodeljuje promenljivoj mora biti kreirano
prema pravilima za
identifikatore.
Direktiva
Direktiva u iskazu za definisanje podataka moe da bude BYTE,
WORD, DWORD, ili
bilo koja druga prikazana u tabeli 1. Dodatno, moe biti bilo
koja od nasleenih direktiva za
definisanje podataka, prikazanih u tabeli 2, koje podrava
Netwide Assembler (NASM) i Turbo
Assembler (TASM).
Tabela 2. Nasleene direktive za tipove podataka
Direktiva Opis
DB 8-bitni ceo broj
DW 16-bitni ceo broj
DD 32-bitni ceo ili realan broj
DQ 64-bitni ceo ili realan broj
DT 80-bitni ceo broj
Inicijalizator
Najmanje jedan inicijalizator je neophodan u definiciji podatka,
ak iako je jednak nuli.
Ako postoje dodatni inicijalizatori, razdvajaju se zarezima. Za
cele brojeve, inicijalizator je
celobrojna konstanta ili izraz koji odgovara veliini tipa
podatka promenljive, kao to su BYTE
ili WORD. Ako elite da ostavite promenljivu neinicijalizovanu
(dodelite joj nasuminu
vrednost), simbol ? se moe koristiti kao inicijalizator.
Nezavisno od njihovih formata, svi
inicijalizatori se konvertuju u binarne podatke od strane
asemblera. Inicijalizatori kao to su
00110010b, 32h i 50d, svi na kraju bivaju konvertovani u istu
binarnu vrednost.
-
3
2.1.1 Definisanje BYTE i SBYTE podataka
BYTE (definisani bajt) i SBYTE (definisani oznaeni bajt)
direktive alociraju memoriju
za jednu ili vie oznaenih ili neoznaenih vrednosti. Svaki
inicijalizator mora da se smesti u
memoriju od 8 bita. Na primer:
value1 BYTE 'A' ; karakter
value2 BYTE 0 ; najmanji neoznaeni bajt
value3 BYTE 255 ; najvei neoznaeni bajt
value4 SBYTE 128 ; najmanji oznaeni bajt
value5 SBYTE +127 ; najvei oznaeni bajt
Inicijalizator znak pitanja (?) ostavlja promenljivu
neinicijalizovanu, to znai da e joj
se dodeliti vrednost u vreme izvravanja:
value6 BYTE ?
Opciono ime je labela koja oznaava ofset promenljive od poetka
okruujueg segmenta.
Na primer, ako je value1 locirana na ofsetu 0000 u segmentu
podataka i zauzima jedan bajt
memorije, value2 je automatski locirana na ofsetu 0001:
value1 BYTE 10h
value2 BYTE 20h
Direktiva DB takoe moe da definie 8-bitnu promenljivu, oznaenu
ili neoznaenu:
val1 DB 255 ; neoznaeni bajt
val2 DB -128 ; oznaeni bajt
Viestruki inicijalizatori
Ako se vie inicijalizatora koristi u istoj definiciji podataka,
njihove labele ukazuju jedino
na ofset od prvog inicijalizatora. U sledeem primeru,
pretpostavimo da je promenljiva list
locirana na ofsetu 0000. U tom sluaju, vrednost 10 je na ofsetu
0000, 20 je na ofsetu 0001, 30
je na ofsetu 0002, a 40 je na ofsetu 0003:
list BYTE 10,20,30,40
Na slici 1 je prikazana promenljiva list kao sekvenca bajtova,
svaki sa sopstvenim
ofsetom.
Ofset Vrednost
0000: 10
0001: 20
0002: 30
0003: 40
Slika 1. Izgled memorije za sekvencu bajtova
-
4
Ne zahtevaju sve definicije podataka labele. Da bismo nastavili
sa nizom podataka koji
poinju sa promenljivom list, na primer, moemo definisati dodatne
bajtove na sledeim
linijama:
list BYTE 10,20,30,40
BYTE 50,60,70,80
BYTE 81,82,83,84
Unutar jedne definicije podatka, inicijalizatori mogu koristiti
razliite osnove. Karakteri
i stringovi se mogu slobodno meati. U sledeem primeru, list1 i
list2 imaju isti sadraj:
list1 BYTE 10, 32, 41h, 00100010b
list2 BYTE 0Ah, 20h, 'A', 22h
Definisanje stringova
Kako bi se definisao string karaktera, treba da uokviriti sa
jednostrukim ili dvostrukim
navodnicima. Najei tip stringa se zavrava sa null bajtom (koji
sadri 0). Stringovi ovog tipa
se nazivaju stringovi koji se zavravaju sa null (null-terminated
strings) i koriste se u mnogim
programskim jezicima:
greeting1 BYTE "Good afternoon",0
greeting2 BYTE 'Good night',0
Svaki karakter zauzima jedan bajt memorije. Stringovi su
izuzetak od pravila da vrednosti
bajtova moraju biti razdvojene zarezima. Bez ovog izuzetka,
greeting1 bi morao da se definie
kao:
greeting1 BYTE 'G','o','o','d'....itd.
String se moe podeliti na vie linija bez potrebe da se navodi
labela za svaku liniju:
greeting1 BYTE "Welcome to the Encryption Demo program "
BYTE "created by Kip Irvine.",0dh,0ah
BYTE "If you wish to modify this program, please "
BYTE "send me a copy.",0dh,0ah,0
Heksadecimalni kodovi 0Dh i 0Ah se nazivaju CR/LF
(carriage-return line-feed) ili
karakteri zavretka linije. Kada se ispiu na standardnom izlazu,
oni pomeraju kursor na poetak
linije koja se nalazi ispod trenutne linije.
Karakter za nastavljanje linije (\) spaja dve linije koda u
jedan iskaz. Mora biti poslednji
karakter u liniji. Sledei iskazi su ekvivalentni:
greeting1 BYTE "Welcome to the Encryption Demo program "
i
greeting1 \
BYTE "Welcome to the Encryption Demo program "
-
5
Operator DUP
Operator DUP alocira memoriju za vie podataka, koristei
konstantni izraz kao broja.
Posebno je od koristi kada se alocira prostor za stringove ili
nizove i moe se koristiti sa
inicijalizanovim ili neinicijalizovanim podacima:
BYTE 20 DUP(0) ; 20 bajtova, svi jednaki nuli
BYTE 20 DUP(?) ; 20 bajtova, neinicijalizovani
BYTE 4 DUP("STACK") ; 20 bajtova: "STACKSTACKSTACKSTACK"
2.1.2 Definisanje WORD i SWORD podataka
WORD (definisana re) i SWORD (definisana oznaena re) direktive
alociraju
memoriju za jedan ili vie 16-bitnih celih brojeva:
word1 WORD 65535 ; najvea neoznaena vrednost
word2 SWORD -32768 ; najmanja oznaena vrednost
word3 WORD ? ; neinicijalizovana, neoznaena vrednost
Nasleena DW direktiva se takoe moe koristiti:
val1 DW 65535 ; neoznaena
val2 DW -32768 ; oznaena
Niz rei
Kreira se niz rei navoenjem njegovih elemenata ili koristei
operator DUP. Sledei niz
sadri niz vrednosti:
myList WORD 1,2,3,4,5
Na slici 3 je prikazan dijagram izgleda niza u memoriji, pod
pretpostavkom da myList
poinje sa ofsetom 0000. Adrese se uveavaju za dva zato to svaka
vrednost zauzima dva bajta.
Ofset Vrednost
0000: 1
0002: 2
0004: 3
0006: 4
0008: 5
Slika 3. Izgled memorije za niz 16-bitnih rei
Operator DUP daje pogodan nain za inicijalizaciju niza rei:
array WORD 5 DUP(?) ; 5 vrednosti, neinicijalizovane
2.1.3 Definisanje DWORD i SDWORD podataka
DWORD (definisana dvostruka re) i SDWORD direktive omoguavaju
pamenje
jednog ili vie 32-bitnog celog broja:
-
6
val1 DWORD 12345678h ; neoznaeni
val2 SDWORD 2147483648 ; oznaeni
val3 DWORD 20 DUP(?) ; neoznaeni niz
Nasleena DD direktiva se takoe moe koristiti:
val1 DD 12345678h ; neoznaeni
val2 DD 2147483648 ; oznaeni
DWORD se moe koristiti za deklaraciju promenljive koja sadri
32-bitni ofset od druge
promenljive. U primeru ispod, pVal sadri ofset od val3:
pVal DWORD val3
Niz dvostrukih rei
Kreira se niz dvostrukih rei eksplicitnim navoenjem svakog od
elemenata ili koristei
DUP operator. Sledei niz sadri specificirane neoznaene
vrednosti:
myList DWORD 1,2,3,4,5
Na slici 4 je prikazan izgled niza u memoriji, pod pretpostavkom
da myList poinje sa
ofsetom 0000. Ofset se uveava za 4.
Ofset Vrednost
0000: 1
0004: 2
0008: 3
000C: 4
0010: 5
Slika 4. Izgled memorije za niz 32-bitnih dvostrukih rei
2.1.4 Definisanje pakovanih binarno kodovanih decimalnih
podataka (TBYTE)
Intel smeta pakovane binarno kodovane decimalne (BCD) cele
brojeve u pakete od 10
bajtova. Svaki bajt (osim najvieg) sadri dve decimalne cifre.
Kod niih 9 bajtova, svaki
polubajt sadri jednu decimalnu cifru. U najviem bajtu, bit
najvee teine oznaava znak broja.
Ako je najvii bajt jednak 80h, broj je negativan, a ako je
jednak 00h, broj je pozitivan. Raspon
celih brojeva je od -999.999.999.999.999.999 do
+999.999.999.999.999.999.
Primer
U sledeoj tabeli su prikazani heksadecimalni bajtovi koji se
memoriu za pozitivan i
negativan decimalni broj 1234, poevi od bajta najvee teine do
bajta najmanje teine.
Decimalna vrednost Bajtovi koji se memoriu
+1234 00 00 00 00 00 00 00 00 12 34
-1234 80 00 00 00 00 00 00 00 12 34
-
7
MASM koristi TBYTE direktivu za deklarisanje pakovanih BCD
promenljivih.
Konstantni inicijalizatori moraju biti heksadecimalni zato to
asembler ne prevodi automatski
decimalne konstante u BCD format. Sledea dva primera pokazuju
ispravan i pogrean nain
predstavljanja decimalnog broja -1234:
intVal TBYTE 800000000000001234h ; ispravno
intVal TBYTE -1234 ; pogreno
Razlog zbog kojeg je drugi primer pogrean je taj to MASM kodira
ove konstante kao
binarne cele brojeve umesto pakovane BCD cele brojeve.
Ako elite da kodirate realne brojeve kao pakovane BCD brojeve,
prvo ih morate uitati
u stek registar za brojeve u pokretnom zarezu sa instrukcijom
FLD, a potom koristiti FBSTP
instrukciju za konvertovanje u pakovani BCD format. Ova
instrukcija zaokruuje vrednost na
najblii ceo broj:
posVal REAL8 1.5
bcdVal TBYTE ?
.code
fld posVal ; uitaj u stek za brojeve u pokretnom zarezu
fbstp bcdVal ; zaokruuje na 2 kao pakovani BCD broj
2.1.5 Definisanje realnih brojeva
REAL4 definie 4-bajtnu realnu promenljivu jednostruke
preciznosti. REAL8 definie 8-
bajtnu realnu promenljivu dvostruke preciznosti, a REAL10
definie 10-bajtnu realnu
promenljivu dvostruke proirene preciznosti. Svaka od njih
zahteva jedan ili vie konstantnih
inicijalizatora:
rVal1 REAL4 -1.2
rVal2 REAL8 3.2E-260
rVal3 REAL10 4.6E+4096
ShortArray REAL4 20 DUP(0.0)
U tabeli 3 su prikazani svi standardni tipovi realnih podataka,
zajedno sa najmanjim
brojem znaajnih cifara i priblinim opsegom.
Tabela 3. Standardni tipovi realnih brojeva
Tip podatka Znaajne cifre Priblini opseg
Kratki realan 6 Od 1,18 x 10-38 do 3,4 x 1038
Dugi realan 15 Od 2,23 x 10-308 do 1,79 x 10308
Realan proirene preciznosti
19 Od 3,37 x 10-4932 do 1,18 x 104932
-
8
Realni brojevi se mogu deklarisati i direktivama DD, DQ i
DT:
rVal1 DD -1.2 ; kratak realan
rVal2 DQ 3.2E-260 ; dugi realan
rVal3 DT 4.6E+4096 ; realan proirene preciznosti
2.2 Little Endian redosled
Procesori x86 familije smetaju i uzimaju podatke iz memorije
koristei little endian
redosled (od najnieg do najvieg). Bajt najmanje teine se smeta
na prvoj memorijskoj adresi
koja je alocirana za podatak. Ostali bajtovi se smetaju u
sledeim sukcesivnim memorijskim
lokacijama. Posmatrajmo dvostruku re 12345678h. Ako je smetena u
memoriji na ofsetu
0000, 78h e biti smeteno u prvom bajtu, 56h u drugom, a ostali
bajtovi e biti na ofsetima
0002 i 0003, kao to je prikazano na slici 5.
0000: 78
0001: 56
0002: 34
0003: 12
Slika 5. Little Endian predstava broja 12345678h
Pojedini drugi raunarski sistemi koriste big endian redosled (od
najvieg do najnieg).
Na slici 6 je prikazan primer broja 12345678h smetenog u big
endian redosledu na ofsetu 0.
0000: 12
0001: 34
0002: 56
0003: 78
Slika 5. Big Endian predstava broja 12345678h
2.3 Dodavanje promenljivih u AddSub program
Koristei AddSub program sa prethodnih vebi, dodat je segment
podataka koji sadri
nekoliko promenljivih duine dvostruke rei.
TITLE Add and Subtract, Version 2 (AddSub2.asm)
; Ovaj program vri sabiranje i oduzimanje 32-bitnih
neoznaenih
; celih brojeva i sumu pamti u promenljivoj.
INCLUDE Irvine32.inc
.data
val1 DWORD 10000h
val2 DWORD 40000h
val3 DWORD 20000h
finalVal DWORD ?
.code
main PROC
mov eax,val1 ; poinje sa 10000h
add eax,val2 ; dodaje se 40000h
-
9
sub eax,val3 ; oduzima se 20000h
mov finalVal,eax ; smeta se rezultat (30000h)
call DumpRegs ; prikazuje se sadraj registara
exit
main ENDP
END main
U ovom programu koristimo biblioteku Irvine32.inc, u kojoj se
nalaze potrebne definicije
i podeavanja programa. Iz nje se kopiraju sledei delovi
koda:
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD
DumpRegs PROTO
Takoe, u odnosu na raniji program, ovde se umesto poziva
procedure ExitProcess sa:
INVOKE ExitProcess,0
koristi makro exit, definisan u Irvine32.inc biblioteci, koji
poziva predefinisanu MS-Windows
funkciju koja zaustavlja rad programa.
Program radi tako to se najpre broj sadran u promenljivoj val1
premeta (kopira) u
registar EAX:
mov eax,val1 ; poinje sa 10000h
Potom se vrednost u val2 dodaje na vrednost u registru EAX:
add eax,val2 ; dodaje se 40000h
Potom se od vrednosti u registru EAX oduzima val3:
sub eax,val3 ; oduzima se 20000h
Na kraju se vrednost iz registra EAX kopira u finalVal:
mov finalVal,eax ; smeta se rezultat (30000h)
2.4 Deklaracija neinicijalizovanih podataka
Direktiva .DATA? deklarie neinicijalizovane podatke. Kada se
definie veliki blok
neinicijalizovanih podataka, direktiva .DATA? smanjuje veliinu
kompajliranog programa. Na
primer, sledei kod je efikasno deklarisan:
.data
smallArray DWORD 10 DUP(0) ; 40 bajtova
.data?
bigArray DWORD 5000 DUP(?) ; 20.000 bajtova,
neinicijalizovani
Sa druge strane, sledeim kodom se kreira kompajlirani program
koji je vei za 20.000
bajtova:
.data
smallArray DWORD 10 DUP(0) ; 40 bajtova
bigArray DWORD 5000 DUP(?) ; 20.000 bajtova
-
10
2.5 Meanje koda i podataka
Asembler omoguava menjanje izmeu koda i podataka u programu. Na
primer, moete
deklarisati promenljivu koja se koristi samo unutar
lokalizovanog prostora programa. Sledei
primer ubacuje temp promenljivu izmeu dva code iskaza:
.code
mov eax,ebx
.data
temp DWORD ?
.code
mov temp,eax
. . .
Iako se ini da deklaracija promenljive temp naruava tok
izvravanja instrukcija, MASM
smeta temp u segment podataka, odvojeno od segmenta koji sadri
kompajlirani kod. U isto
vreme, meanje .code i .data direktiva moe dovesti do teke
itljivosti programa.
2.6 Simbolike konstante
Simbolika konstanta (ili simbolika definicija) se kreira
povezivanjem identifikatora
(simbola) sa celobrojnim izrazom ili nekim tekstom. Simboli ne
alociraju memorijski prostor.
Asembler ih koristi samo kada uitava program i ne mogu se
menjati u trenutku izvravanja. U
sledeoj tabeli su sumirane njihove razlike.
Simbol Promenljiva
Zauzima memoriju? Ne Da
Vrednost se menja u
trenutku izvravanja?
Ne Da
2.6.1 Direktiva znak jednakosti
Direktiva znak jednakosti povezuje ime simbola sa celobrojnim
izrazom. Sintaksa je:
ime = izraz
Obino, izraz je 32-bitna celobrojna vrednost. Kada se program
asemblira, sve instance
ime-na se menjaju sa izrazom tokom pretprocesiranja.
Pretpostavimo da se sledei izraz nalazi
blizu poetka izvornog koda:
COUNT = 500
Nadalje, pretpostavimo da se sledei iskaz nalazi deset linija
nakon gornjeg:
mov eax, COUNT
Kada se fajl asemblira, MASM pregleda izvorni fajl i kreira
odgovarajue linije koda:
mov eax, 500
-
11
Zato koristiti simbole?
Mogli smo da preskoimo navoenje COUNT simbola i da direktno
napiemo MOV
instrukciju sa literalom 500, ali praksa je pokazala da se
programi lake itaju i odravaju ako
se koriste simboli. Pretpostavimo da se COUNT koristi mnogo puta
u programu. Moemo lako
redefinisati njegovu vrednost:
COUNT = 600
Pod pretpostavkom da se izvorni fajl opet asemblira, sve
instance COUNT-a e se
automatski zameniti sa vrednou 600.
2.6.2 Broja trenutne lokacije
Jedan od najvanijih simbola je broja trenutne lokacije ($). Na
primer, sledei iskaz
deklarie promenljivu po imenu selfPtr i inicijalizuje je sa
sopstvenim brojaem lokacije:
selfPtr DWORD $
Definicije kodova sa tastature
Programi esto definiu simbole koji identifikuju koriene numerike
kodove tastature.
Na primer, 27 je ASCII kod za Esc taster:
Esc_key = 27
Kasnije u programu, bolje je koristiti simbol umesto neposredne
vrednost, radi lake
itljivosti. Tako, treba koristiti
mov al,Esc_key ; dobar stil
umesto
mov al,27 ; lo stil
Upotreba DUP operatora
Brojai koje koristi DUP operator treba da budu simbolike
konstante, kako bi se olakalo
odravanje programa. U sledeem primeru, ako je COUNT definisan,
moe se koristiti u
sledeoj definiciji podatka:
array DWORD COUNT DUP(0)
Redefinisanje
Simbol definisan sa = se moe redefinisati unutar istog programa.
Sledei primeri
pokazuju kako asembler evaluira COUNT kako mu se menja
vrednost:
COUNT = 5
mov al,COUNT ; AL = 5
COUNT = 10
mov al,COUNT ; AL = 10
-
12
COUNT = 100
mov al,COUNT ; AL = 100
Raunanje veliine nizova i stringova
Sledei primer koristi konstantu ListSize kako bi se deklarisala
veliina promenljive list:
list BYTE 10,20,30,40
ListSize = 4
Eksplicitno navoenje veliine niza moe dovesti do greaka u
programiranju, posebno
ako kasnije ubacujete ili uklanjate elemente iz niza. Bolji nain
za deklarisanje veliine niza je
da se dozvoli asembleru da sam izrauna njegovu veliinu. Operator
$ vraa ofset koji je
povezan sa trenutnim programskim iskazom. U sledeem primeru,
ListSize se rauna
oduzimanjem ofseta promenljive list od trenutnog brojaa lokacije
($):
list BYTE 10,20,30,40
ListSize = ($ - list)
ListSize mora slediti odmah posle list. Na primer, u sledeem
primeru se dobija suvie
velika vrednost (24) za ListSize, jer je memorijski prostor koji
zauzima var2 uticao na
udaljenost izmeu brojaa trenutne lokacije i ofseta promenljive
list:
list BYTE 10,20,30,40
var2 BYTE 20 DUP(?)
ListSize = ($ - list)
Umesto runog raunanja duine stringa, prepustite taj posao
asembleru:
myString BYTE "This is a long string, containing"
BYTE "any number of characters"
myString_len = ($ myString)
Nizovi rei i dvostrukih rei
Kada se rauna broj elemenata u nizu koji se sastoji iz vrednosti
koje nisu veliine bajta,
uvek treba podeliti ukupnu veliinu niza (u bajtovima) sa
veliinom pojedinanog elementa
niza. Na primer, u sledeem kodu, adresni opseg se deli sa 2 zato
to svaka re u nizu zauzima
dva bajta (16 bitova):
list WORD 1000h,2000h,3000h,4000h
ListSize = ($ list) / 2
Na slian nain, svaki element niza dvostrukih rei je duine 4
bajta, tako da ukupna
duina mora biti podeljena sa 4 kako bi se dobio broj elemenata u
nizu:
list DWORD 10000000h,20000000h,30000000h,40000000h
ListSize = ($ list) / 4
-
13
2.6.3 Direktiva EQU
Direktiva EQU povezuje simbolino ime sa celobrojnim izrazom ili
nekim tekstom.
Postoje tri formata:
ime EQU izraz
ime EQU simbol
ime EQU
U prvom formatu, izraz mora biti validan celobrojni izraz. U
drugom formatu, simbol je
ime postojeeg simbola, koji je ve definisan sa = ili EQU. U
treem formatu, tekst se navodi
izmeu zagrada . Kada asembler naie na ime u programu, zamenjuje
ga sa celobrojnom
vrednou ili tekstom.
EQU moe biti korisno kada se definie vrednost koja se ne
evaluira kao ceo broj. Na
primer, realna konstanta se moe definisati korienjem EQU:
PI EQU
Primer 1. Sledei primer povezuje simbol sa stringom. Potom se
kreira promenljiva koristei
simbol:
pressKey EQU
.
.
.data
prompt BYTE pressKey
Primer 2. Pretpostavimo da elimo da definiemo simbol koji broji
broj elija u matrici celih
brojeva dimenzije 10 x 10. Definisaemo simbole na dva razliita
naina, najpre kao celobrojni
izraz, a potom kao tekst. Ova dva simbola se kasnije koriste
prilikom definicije podataka:
matrix1 EQU 10 * 10
matrix2 EQU
.data
M1 WORD matrix1
M2 WORD matrix2
Asembler kreira razliite definicije podataka za M1 i M2.
Celobrojni izraz u matrix1 se
evaluira i dodeljuje M1. Sa druge strane, tekst u matrix2 se
direktno kopira u definiciju podatka
za M2:
M1 WORD 100
M2 WORD 10 * 10
Nema redefinisanja
Za razliku od direktive =, simbol definisan sa EQU se ne moe
redefinisati u istom
izvornom fajlu. Ova zabrana spreava da se postojeem simbolu
nenamerno dodeli nova
vrednost.
-
14
2.6.4 Direktiva TEXTEQU
Direktiva TEXTEQU je slina sa EQU, a kreira tekstualni makro.
Postoje tri razliita
formata: prvi dodeljuje tekst, drugi dodeljuje sadraj postojeeg
tekstualnog makroa, a trei
dodeljuje konstantni celobrojni izraz:
ime TEXTEQU
ime TEXTEQU tekstmakro
ime TEXTEQU %konstIzraz
Na primer, promenljiva prompt1 koristi continueMsg tekstualni
makro:
continueMsg TEXTEQU
.data
prompt1 BYTE continueMsg
Tekstualni makroi se mogu praviti jedan nad drugim. U sledeem
primeru, count je
setovan na vrednost celobrojnog izraza koji ukljuuje rowSize.
Potom se simbol move definie
kao mov. Na kraju, setupAL se kreira od move i count:
rowSize = 5
count TEXTEQU %(rowSize * 2)
move TEXTEQU
setupAL TEXTEQU
Prema tome, iskaz
setupAL
e se asemblirati kao
mov al,10
Simbol definisan sa TEXTEQU se moe redefinisati.
Zadatak 1. Napisati program koji oduzima tri 16-bitna cela broja
koristei samo registre.
Pozvati DumpRegs proceduru za prikaz vrednosti registara.
TITLE Zadatak 1
INCLUDE Irvine32.inc
.code
main PROC
mov ax,4000h
mov bx,1000h
mov cx,1500h
sub ax,bx
sub ax,cx
call DumpRegs
exit
main ENDP
END main
-
15
Zadatak 2. Napisati program koji sadri definicije svakog tipa
podatka koji je naveden.
Inicijalizovati svaku promenljivu sa odgovarajuom vrednou.
TITLE Zadatak 2
INCLUDE Irvine32.inc
.data
var1 BYTE 10h
var2 SBYTE -14
var3 WORD 2000h
var4 SWORD +2345
var5 DWORD 12345678h
var6 SDWORD -2342423
var7 FWORD 0
var8 QWORD 1234567812345678h
var9 TBYTE 1000000000123456789Ah
var10 REAL4 -1.25
var11 REAL8 3.2E+100
var12 REAL10 -6.223424E-2343
.code
main PROC
exit
main ENDP
END main
Zadatak 3. Napisati program koji definie simbolike konstante za
sve dane u nedelji. Kreirati
niz promenljivih koji koristi simbole kao inicijalizatore.
TITLE Zadatak 3
INCLUDE Irvine32.inc
Ponedeljak = 0
Utorak = 1
Sreda = 2
Cetvrtak = 3
Petak = 4
Subota = 5
Nedelja = 6
.data
myDays BYTE Ponedeljak, Utorak, Sreda, Cetvrtak,
Petak, Subota, Nedelja
.code
main PROC
exit
main ENDP
END main
-
16
Zadatak 4. Napisati program koji definie simbolika imena za
nekoliko stringova. Iskoristiti
svaki od simbola u definiciji promenljive.
TITLE Zadatak 4
INCLUDE Irvine32.inc
sym1 TEXTEQU
sym2 TEXTEQU
sym3 TEXTEQU
sym4 TEXTEQU
.data
msg1 BYTE sym1
msg2 BYTE sym2
msg3 BYTE sym3
msg4 BYTE sym4
.code
main PROC
exit
main ENDP
END main