Preuzmi kao *
Transcription
Preuzmi kao *
ELEKTROTEHNIČKI FAKULTET UNIVERZITETA U SARAJEVU mr Ribić Samir, dipl.el. ing PROJEKTOVANJE SISTEMSKOG SOFTVERA (radna skripta) (treće izdanje) Sarajevo, 2005 2 3 1. VRSTE SISTEMSKOG SOFTVERA Prije učenja razvoja sistemskog softvera potrebno je upoznati se sa osnovnim vrstama sistemskog softvera 1.1. Sistemski softver Sistemski softver je svaki softver namijenjen za izvršenje aplikativnih programa, ali koji nije specifičan ni za jednu posebnu aplikaciju. Sistemski softver tipično uključuje operativne sisteme za kontrolu izvršenja programa, softver za korisničko okruženje kao što su interpretatori komandne linije, prozorski sistemi i desktopi, razvojne alate kao što su asembleri, kompajleri, linkeri biblioteke, interpreteri, generatori unakrsnih referenci, kontrolori verzija, make programi, debageri, profajleri i softver za praćenje te pomoćne alatke za sortiranje, štampanje i editovanje i mnogi drugi softver. 1.2. Sistemski softver za kontrolu izvršenja programa - Operativni sistemi Operativni sistem je softver koji kontroliše izvršenje računarskih programa i pruža pored toga različite servise. - BIOSi i ROM monitori Softver koji se obično nalazi u fiksnoj memoriji ROM i omogućuje minimalni rad računara zaključno sa učitavanjem operativnog sistema dijeli se na BIOSe i monitore. BIOS obično sadrži samo pasivne rutine koje operativni sistemi koriste i koje omogućuju rad sa osnovnim periferijskim uređajima, dok ROM monitori imaju i neke primitivne metode za interakciju s korisnicima. - Loaderi Loader (punilac) smješta korisnički program smješten na periferijskom uređaju u fizičku memoriju obavljajući pri tome relokaciju programa na odgovarajuće adrese i učitavanje dinamičkih biblioteka ako ih program koristi. - Simulatori Simulator je mašina ili program koji simulira željeno okruženje (može biti drugi računar, hemijski proces, sociološki sistem ili bilo šta drugo) u svrhu učenja ili istraživanja. - Emulatori Specijalizovani simulator koji simulira drugu mašinu i arhitekturu u odnosu na onu na kojoj se izvršava omogućivši upotrebu gotovo svog softvera namijenjenog za drugu mašinu naziva se emulator. - Drajveri Drajver je program koji određuje kako će kompjuter komunicirati sa periferijskim uređajem u svrhu standardiziranog rada aplikativnih programa sa periferijskim uređajima. - DBMS Serveri Programi koji brinu o centralizovanom čuvanju podataka u cilju brzog dobivanja podataka nazivaju se serveri za upravljanje bazom podataka (DataBase Management Server) - Spuleri Vrše raspoređivanje slanja podataka na printere kako bi se izbjeglo miješanje podataka na papiru - Mrežni serveri Programi koji omogućavaju pristup raznim vrstama informacija preko mreže 1.3. Softver za korisničko okruženje - Interpreteri komandne linije Interpreter komandne linije je program koji čita tekstualne komande od strane korisnika ili iz datoteke i izvršava. Neke od ovih komandi se izvršavaju unutar samog interpretera, dok druge izazivaju startovanje drugih datoteka. - Grafički sistemi prozora Grafički sistem prozora je softver koji omogućuje da se ekran radne stanice podijeli u pravougaona područja koja se ponašaju kao odvojeni ulazno/izlazni uređaji pod kontrolom različitih aplikativnih programa, što daje korisniku mogućnost da vidi izlaz iz različitih procesa istovremeno i odabere koji će primati ulaz, obično pokazavši na njega mišem. 1.4. Razvojni alati - Asembleri Asembleri prevode program u asemblerskom jeziku u mašinski jezik. - Kompajleri Kompajler dekodira instrukcije napisane u jeziku višeg nivoa i proizvodi program u asemblerskom ili mašinskom jeziku. - Linkeri Linkeri kombinuju jednu ili više datoteka koje sadrže objektni kod iz separatno prevedenih modula u jedinstvenu datoteku koja sadrži učitljiv ili izvršni kod. Ovaj proces zahtijeva razrješenje referenci među modulima i popravku informacija o relokaciji koje koristi jezgro operativnog sistema prilikom učitavanja datoteke u memoriju radi izvršenja programa koji je u njoj. - Parseri Parseri su programi koji dijele kod u funkcionalne komponente. Obično su sastavni dio kompajlera. - Kompajler kompajleri 4 Kompajler kompajleri su alatke koje generišu izvorni kod parsera, interpretera ili kompajlera iz navedenog opisa jezika (obično u BNF formi) - Disasembleri Disasembleri prevode program u mašinskom jeziku u program u asemblerskom jeziku. - Dekompajleri Dekompajleri prevode program u mašinskom jeziku ili pseudomašinskom kodu u jezik visokog nivoa. - Kros asembleri Krosasembleri su asembleri koji se izvršavaju na drugoj vrsti računarske arhitekture od one čiji se mašinski kod generiše. - Kros kompajleri Krosakompajleri su kompajleri koji se izvršavaju na drugoj vrsti računarske arhitekture od one čiji se mašinski kod generiše. - Interpreteri Interpreteri su programi koji prevođenje izvornog jezika i izvršavanje prevedenog koda obavljaju u istom ciklusu obično obrađujući po jednu liniju u vremenu. - Pseudokompajleri Pseudokompajleri su varijanta kompajlera koja ne generiše pravi mašinski kod, nego pseudomašinski kod koji je nižeg nivoa od izvornog jezika, ali zahtijeva poseban interpreter za svoje izvršavanje. - Pseudoasembleri Pseudoasebmleri su varijanta asemblera koja ne generiše pravi mašinski kod, nego pseudomašinski kod koji je nižeg nivoa od izvornog jezika, ali zahtijeva poseban interpreter za svoje izvršavanje. - Profajleri i monitori performansi Profajleri mjere vrijeme provedeno u pojedinačnim dijelovima korisničkog programa u svrhu poboljšanja brzine aplikacije. Monitori performansi mjere zauzeće raznih vrsta resursa (procesora, memorije, diska, mreže...) u sistemu. - Generatori unakrsnih referenci Generatori unakrsnih referenci prikazuju odnose između različitih procedura u različitim modulima. - Kontrolori verzija Da bi se izbjegli konflikti između različitih programera koji rade nad istim datotekama izvornog koda, uvode se kontrolori verzija koji čuvaju centralizovano sve datoteke iz navedenog projekta uključivo i njihove ranije verzije. - Translatori izvornog koda Translatori izvornog koda prevode program napisan u jednom programskom jeziku višeg nivoa u drugi programski jezik višeg nivoa. - Generatori izvornog koda i CASE alati Generatori izvornog koda automatski generišu izvorni kod u višem programskom jeziku ili asemblerskom jeziku na bazi navedenih parametara. Integrisani sa softverom za projektovanje čine CASE alate (Computer Aided Software Engineering) - make Make je program koji određuje, zavisno od vremena zadnje izmjene datoteka, da li je potrebno pokretati asemblere, kompajlere i linkere nad određenim datotekama. - Debageri Debageri su programi koji pomažu u lociranju i ispravci grešaka u programima. Mogu da prate programe na nivou izvornog i izvršnog koda - Biblioteke Skup potprograma namijenjenih programerima koji obavljaju određene funkcije 1.5. Pomoćne alatke - Editori Programi koji obavljaju funkcije uređivanja, modifikacije i brisanja podataka zovu se editori. Editori mogu biti specijalizovani za tekstualne ili binarne podatke. - Sortirači Sortirači su programi za uređivanje podataka određenim redoslijedom - Backup programi Backup programi kopiraju podatke na pomoćni medij radi njihovog čuvanja u slučaju gubitka - Kriptografski programi Kriptografski programi šifriraju podatke u nečitljiv oblik radi sprečavanja neovlaštene analize - Kompresioni programi Kompresioni programi konvertuju podatke u formate koji zauzimaju manje memorijskih resursa - Mrežni klijenti Mrežni klijenti koriste usluge mrežnih servera u svrhu prijema i obrade podataka 1.6. Rezime poglavlja Navedeno je dosta definicija različitih vrsta sistemskog softvera koji obuhvata softver za kontrolu izvršenja programa, korisničko okruženje, razvojne i pomoćne alatke. 5 2. PROCESOR I OPERATIVNI SISTEM ZA KOJE SE GENERIŠE KÔD Intelov Pentium je danas apsolutno dominantan mikroprocesor, pa će se i u navedenim primjerima on koristiti u razvoju kompajlera. Slijedi upoznavanje sa najvažnijim registrima i instrukcijama ovog procesora: 2.1. Registri Za aplikativne programe na mikroprocesorima 486 i Pentium bitni su sljedeći 32 bitni registri: • EAX, donjih 16 bita se zove AX, donjih 8 bita se zove AL • EBX, donjih 16 bita se zove BX, donjih 8 bita se zove BL • ECX, donjih 16 bita se zove CX, donjih 8 bita se zove CL • EDX, donjih 16 bita se zove DX, donjih 8 bita se zove DL • ESI, donjih 16 bita se zove SI • EDI, donjih 16 bita se zove DI • ESP, donjih 16 bita se zove SP • EBP, donjih 16 bita se zove BP • EFLAGS koji se sastoji od flegova (jednobitnih vrijednosti), od kojih su najvažniji: CF – postavlja se na 1 ako se desio aritmetički prijenos, ZF - postavlja se na 1 ako je rezultat operacije jednak 0, DF – određuje da li će se registri SI i DI uvećavati ili umanjivati nakon svake instrukcije koje operišu sa memorijskim blokovima (MOVS, SCAS itd), OF – postavlja se na 1 ako je rezultat operacije između dva predznačena broja broj netačnog predznaka, SF – postavlja se na 1 ako je rezultat operacije negativan broj • 2.2. FP koprocesor posjeduje osam 128 bitnih registara koji su organizovani u formi kružnog bafera i zovu se ST(0), ST(1) , ST(2) , ST(3) , ST(4) , ST(5) , ST(6) , ST(7) . Adresni režimi • Ako se u instrukciji navodi samo ime registra, tada se pristupa vrijednosti koju on sadrži, npr. INC EAX. • Navodi li se ime registra u uglastoj zagradi, uz eventualni pomak, npr. MOV ESI,[EBP+12] , pristupa se vrijednosti koja se nalazi na adresi koju bi pokazivao navedeni registar kada bi bio uvećan za navedeni pomak. Ako je pomak jednak 0, tada se on ne navodi, npr. ADD ECX,[EBX] • Umjesto apsolutnih adresa, mogu se u asemblerskom kodu navoditi labele, npr. MOV GLOBALV[20],EAX • Za distinkciju veličine varijable navode se modifikatori BYTE PTR, WORD PTR , DWORD PTR i QWORD PTR, koji predstavljaju 8, 16, 32 ili 64 bit. • Dekadne konstante se navode jednostavno, npr. MOV EDX,1221. Heksadekadne konstante imaju znak h naveden iza konstante. Ako instrukcije imaju dva operanda, rezultantni je obično prvi navedeni operand i on ne može biti konstanta. Nisu dopuštene ni instrukcije koje operišu između dvije memorijske lokacije. Moraju se u tim slučajevima koristiti registri za međurezultate. 2.3. Instrukcije U tabeli na slici Sl. 2.3.1 dat je spisak korištenih instrukcija. Argumenti instrukcija su navedeni kao $C1 i $C2 i umjesto njih se navode imena registara ili memorijske lokacije kao u podpoglavlju 2.2. Opšti oblik Opis Primjer ADD $C1,$C2 Sabira $C1 sa $C2 i rezultat smješta u $C1 ADD EAX,[ESI] AND $C1,$C2 Logički konjuguje bit po bit $C1 sa $C2 i rezultat smješta u $C1 AND SI,3 CALL $C1 Poziva potprogram na navedenoj adresi CALL PODPROGRAM CDQ Predznačno proširuje EAX u EDX. Najviši bit registra EAX se kopira u sve bite registra EDX. CDQ CLD Briše directional flag, potrebno za instrukcije blokova CLD 6 CMP $C1,$C2 Poredi $C1 sa $C2 i ažurira flegove CMP EAX,PODATAK[8] FADD Sabira dva broja na vrhu FP steka i rezultat smješta na vrh FP steka umjesto njih FADD FCHS Mijenja predznak broju na vrhu FP steka FCHS FCOMPP Poredi dva broja na vrhu FP steka, briše ih, a postavlja flegove koprocesora FCOMPP FDIVR Dijeli broj ispod vrha FP steka sa brojem na vrhu FP steka i rezultat stavlja umjesto njih FDIVR FILD $C1 Cjelobrojnu vrijednost sa memorijske lokacije stavlja na vrh FP steka FILD DWORD PTR [EBX] FINIT Inicijalizira matematički koprocesor FINIT FISTP $C1 FISTP DWORD PTR [ESP] FLD $C1 Vrijednost sa vrha FP steka konvertuje u cjelobrojnu i stavlja u navedenu memorijsku lokaciju FP vrijednost iz memorije stavlja na vrh steka FMUL Množi dva broja na vrhu steka i rezultat smješta na vrh steka umjesto njih. FMUL FSTP $C1 Vrijednost sa vrha FP steka stavlja u navedenu memorijsku lokaciju FSTP REZULTAT FSTSW AX Flegove koprocesora prebacuje u AX registar FSTSW AX FSUBR Od broja ispod vrha FP steka oduzme broj na vrhu FP steka i rezultat stavlja umjesto njih FSUBR IDIV $C1 Predznačno dijeli 64 bitni broj čija je viša riječ u EDX a niža u EAX sa navedenim 32 bitnim registrom ili sadržajem memorijske lokacije, rezultat stavlja u EAX, ostatak u EDX IDIV ECX IMUL $C1 IMUL ECX JMP $C1 Predznačno množi EAX sa navedenim registrom. Viša riječ 64-bitnog rezultata je u EDX a niža u EAX Program nastavlja izvršavanje od adrese navedene. JNE $C1 Skače na navedenu adresu ako Zero flag nije jednak 1 JNE NETACNO LEA $C1,$C2 U registar $C1 se smješta adresa operanda $C2 LEA EAX,[ESI+5] MOV $C1,$C2 U registar $C1 se smješta vrijednost operanda $C2 MOV ECX,EDI MUL $C1 MUL ESI NEG $C1 Nepredznačno množi EAX sa navedenim registrom. Viša riječ 64-bitnog rezultata je u EDX a niža u EAX Mijenja predznak cijelog broja NOT $C1 OR $C1,$C2 Logički invertuje sve bitove cijelog broja Logička disjunkcija bit po bit $C1 sa $C2 i rezultat smješta u $C1 NOT DWORD PTR [EDI] OR EAX,EDX POP $C1 POP ESI PUSH $C1 Sa adrese koju pokazuje ESP uzima vrijednost, smješta je u navedeni registar i uveća ESP za 4 Umanji ESP za 4 i na adresu koju pokazuje ESP smješta navedenu vrijednost REP MOVSB Prebacuje blok velik ECX bajtova sa adrese navedene u ESI na adresu koju pokazuje EDI REP MOVSB RET $N1 RET 8 SAHF Smjesti broj sa vrha steka u programski brojač, čime se vraća iz potprograma i uveća ESP za navedenu vrijednost Prebacuje bite iz AH u Flag registar SAL EAX,$N1 Pomjera ulijevo EAX za navedeni broj bita SAL EAX,4 SETA AL Postavlja AL na 1 ako je CF =1, ZF=0 , inače AL postaje 0 SETA AL SETB AL Postavlja AL na 1 ako je CF =1, ZF=0 , inače AL postaje 0 SETB AL SETE AL Postavlja AL na 1 ako je ZF=1 , inače AL postaje 0 SETE AL SETG AL Postavlja AL na 1 ako je SF<>OF, ZF=0, inače AL postaje 0 SETG AL SETL AL Postavlja AL na 1 ako je SF =OF, ZF=0 , inače AL postaje 0 SETL AL SETNE AL Postavlja AL na 1 ako je CF =1, ZF=0 , inače AL postaje 0 SETNE AL SUB $C1,$C2 Oduzima $C2 od $C1 i rezultat smješta u $C1 SUB ECX,2 XOR $C1,$C2 Logička ekskluzivna disjunkcija $C1 sa $C2 i rezultat smješta u $C1 XOR EAX,8 Sl. 2.3.1. 2.4. FLD QWORD PTR [EBP+2] JMP LABELA2 NEG EAX PUSH EBP SAHF Instrukcije Intel Pentium korištene u generisanju koda Operativni sistem Operativni sistem za koji se generiše kôd u kompajleru koji slijedi je 32 bitni Windows. Generisani programi su predviđeni da rade na njegovim verzijama počevši od Windows 3.1 sa Win32s, Windows 95, 98, ME, NT (sve verzije – 3.1, 3.5, 3.51 i 4.0),Windows 2000 i Windows XP. Generisani kôd je za korisnički režim rada i omogućava pozive izuzetno velikog broja sistemskih funkcija. Na ovaj način, jezik ima bogatu podršku u bibliotekama procedura. Sistemske funkcije se nalaze u dinamičkim DLL datotekama. 2.5. Rezime poglavlja Intelovi mikroprocesori 486 i Pentium imaju veliki broj instrukcija i umjeren broj registara. U ovom poglavlju su navedene samo one instrukcije i adresni režimi koje su zaista korištene u generisanju asemblerskog koda. Generisani kôd je predviđen za korisnički režim rada pod operativnim sistemom Windows-32. 7 3. UOBIČAJENI PRISTUPI U RAZVOJU KOMPAJLERA Osoba zainteresovana za pisanje novog ili analizu postojećeg kompajlera, bilo opisanog u udžbenicima, bilo iz izvornog kôda, uglavnom ima na raspolaganju četiri pristupa: 3.1. • Iterativni pristup • Primjena generatora koda • Analiza gotovog kompajlera • Crenshawova netehnička metoda Iterativni pristup Ovaj pristup je najčešće opisan u udžbenicima. Kompajler se dijeli na glavne cjeline: leksički analizator, sintaksni analizator, semantički analizator, virtuelna mašina, generator koda, interpreter virtuelne mašine i optimizator koda. Cijeli programski jezik i kompajler se prethodno projektuju, a zatim se razvijaju cjeline navedene gornjim redoslijedom, uz objašnjenje teoretskih osnova parsiranja. Prednosti pristupa su • Ovaj pristup je vrlo sistematičan i uglavnom ne divergira od izvorne ideje kako bi konačna verzija jezika trebala da izgleda. Konačna verzija je najčešće podskup nekog klasičnog programskog jezika. • Pristup je primjenjiv za širok dijapazon kompajlera za razne programske jezike, ali i razvoj drugih sistemskih programa: interpretera, translatora, asemblera, uljepšivača izvornog koda, itd. Mane pristupa su: • Nepogodan je za kratke kurseve. Ono čemu kompajler služi, generisanje koda, dolazi tek na kraju knjige ili kursa, pa je potrebno preći oko 150-200 strana ili gotovo cijeli semestar da bi cijela tema imala smisla. • Već u startu se operiše sa velikim listinzima, jer je odmah zamišljeno praćenje sintakse cijelog jezika. • Obično se generiše kôd za virtuelnu, a ne realnu mašinu. Virtuelne mašine zahtijevaju poseban interpreter (uz to nepreglednog) pseudo koda, što umanjuje kvalitet kompajlera (spor i odvojen od sistema prevedeni program). Te mašine su obično stek orijentisane, za razliku od realnih mašina koje su registarski orijentisane. • Realizacija pojedinih jezičkih koncepata nije u skladu sa njihovim prioritetima. Koncept slogova je manje bitan od koncepta cijelih brojeva, ali se ovim pristupom oba uče istovremeno. 3.2. Primjena generatora koda Vrlo su popularni programi koji se zovu kompajler-kompajleri. Ovi programi (LEX, YACC, Bison, COCO/R) iz Bacus-Naurove forme generišu izvorni kôd leksičkog i sintaksnog analizatora koji se kasnije ručno proširuje. Prednosti ovog pristupa su: • Skraćeno vrijeme razvoja, jer su dvije faze kompajliranja, leksička i semantička analiza, korektno već urađene. • Prednosti iterativnog pristupa su zadržane. Mane pristupa su: • Automatski generisani kôd može biti prilično nepregledan, pa je potrebno vrijeme za njegovo shvaćanje. • Upotrebom ovih alata se ne nauči kako se piše kompajler, nego kako se koriste ti alati. • Prevelika je razlika između veličine kompaktne BNF forme i generisanog sintaksnog analizatora nastalog iz te BNF forme. • Ostaje problem jezičkih koncepata različitog prioriteta. 3.3. Analiza gotovog kompajlera Mnogi kompajleri se mogu naći na Internetu sa kompletnim izvornim kodom, a često i propratnom knjigom koja objašnjava rad kompajlera. Najpoznatiji takvi programi su GNU C i Small C. Izvorni kôd se može slobodno analizirati i modifikovati, mada se iz njega obično ne smiju praviti komercijalni kompajleri. Prednosti pristupa su: • Mnogi besplatni kompajleri predstavljaju pune implementacije programskih jezika po ISO ili ANSI standardima. • 8 Gotovi kompajleri su posebno upotrebljivi za brzi razvoj kros-kompajlera (koji generišu kôd za druge platforme) ili popravak optimizatora koda. Mane pristupa su: • Odštampani listinzi ovih kompajlera zauzimaju nekoliko stotina strana. Praćenje takvih listinga je izuzetno teško. • Veliki listing ne daje mnogo informacija o tome kojim putem je on nastao. • Ostaje problem jezičkih koncepata različitog prioriteta. 3.4. Crenshaw-ova netehnička metoda Ova metoda je predložena u seriji članaka na Internetu “Let’s build a compiler”, autora dr Jacka Crenshawa u periodu 1988-1993. Kreće se sa daleko manjim ambicijama, npr. varijable su jednoslovne i nema ključnih riječi, ali se odmah ide u generisanje koda, dok se sam jezik postepeno razvija. Prednosti pristupa su: • Ako je vremenski faktor problem, čitalac može da odustane dosta rano, a da je ipak naučio suštinu procesa. • Jezički koncepti se uvode prema svom značaju. • Listinzi su u početku vrlo mali i jezgroviti (100-200 linija) a rastu dosta linearno. • Odmah se razvija kôd za realnu mašinu i to generisanjem preglednog asemblerskog koda umjesto nepreglednog mašinskog koda ili pseudokoda. Mane pristupa su • Može doći do divergencije u razvoju. U originalnoj seriji članaka se to i dogodilo zbog zauzetosti autora i velikog vremenskog trajanja serije članaka, tako da serija nije dovedena do kraja, a tri puta se počinjalo iz početka. • Ponekad prelazak u narednu fazu implementacije nije moguć zbog koncepata koje je nametnula prethodna faza. Na primjer, ako je prethodna faza jezika definisala da se varijable deklarišu na određeni način, koji nije kompatibilan s tipom podataka planiranom za uvođenje u narednoj fazi, tada treba ili odustati od tog tipa ili nanovo napisati dio koda koji implementira deklaraciju varijabli. • Originalna metoda, ne podržava neke bitne elemente savremenih programskih jezika, kao što su slogovi, nizovi, višedimenzionalni nizovi i veze s operativnim sistemom. • Metoda ne podržava optimizaciju koda i oporavak od grešaka. Pristup objašnjen u ovom radu je, u osnovi, Crenshaw-ov pristup, ali doveden do kraja, bez divergiranja, sa logičnim koracima iz faze u fazu, te sa originalnim programskim jezikom koji se razvija u fazama. Sam kompajler je pisan bez korištenja Crenshawov-og izvornog koda i pruža znatno veće mogućnosti. 3.5. Waterfall i spiralni pristup razvoju informacionih sistema Klasične“waterfall” metodologije razvoja zasnivaju se na lancu: Analiza, Dizajn, Programiranje, Testiranje, Održavanje, Napuštanje( Sl. 3.5.1), Analiz a Dizajn D Sl. 3.5.1. Progra m Test T Održa va Napušt a Klasični “Waterfall” pristup razvoju softvera Spiralni pristupi (Sl. 3.5.2) podrazumijevaju da se ove faze obavljaju svaki put kada se razvija nova verzija programa, proizišla iz stare. Tako se razvija sve moćniji i moćniji softver. Geometrijska forma spirale vjerno predstavlja ovo širenje softvera. 9 A O T D O P A T D P A P Sl. 3.5.2. 3.6. D O T Spiralni pristup u razvoju softvera Programski jezik u kome se razvija kompajler Pošto je svrha razvoja kompajlera za FILDZAN-32 njegova primjena u nastavi, odlučeno je da se sam kompajler piše u programskom jeziku Pascal. Ta odluka danas zvuči neobično, jer se sistemski softver obično piše u jezicima C ili C++, ali bitna prednost Pascala je u njegovoj preglednosti, što je od velike važnosti za nastavu. Treba reći da za Pascal već postoji mnogo dobrih komercijalnih i besplatnih kompajlera kao što su Delphi, Kylix, FreePascal, TurboPascal, Virtual Pascal 2 i P2C. Kompajler za FILDZAN-32 je napisan tako da se lako prevodi bilo kojim od navedenih Pascal-skih kompajlera. 3.7. Hardversko i softversko okruženje za koje se razvija kompajler Jedan od glavnih ciljeva ove metode je razvoj kompajlera koji generiše kôd za konkretno, a ne virtuelno okruženje. S obzirom da na našem i svjetskom tržištu prevladavaju PC računari sa Intel 486 i Intel Pentium procesorima, izbor ovih mikroprocesora za generisanje koda je sasvim logičan. Ovi procesori uključuju i instrukcije za rad sa realnim brojevima. Između dva vodeća operativna sistema za ove procesore, Windows i Linux, izabran je Windows kao, u ovom trenutku, popularniji. Potrebne modifikacije kompajlera da generiše kôd za Linux su male. Očekuje se da će operativni sistemi bazirani na kompatibilnosti s Microsoft Windows platformama i Intelovim mikroprocesora biti aktuelni bar do 2010 godine. 3.8. Rezime poglavlja Uobičajeni pristupi, koji se mogu naći u literaturi, za učenje razvoja kompajlera su iterativni pristup, analiza gotovih kompajlera, primjena generatora koda i Crenshaw-ov netehnički pristup. Svi pristupi imaju svojih prednosti i nedostataka. Za kratke kurseve, koji trebaju da brzo daju konkretne rezultate najpogodniji je Crenshaw-ov pristup, ali je on često nepotpun. U ovom prikazu razvoja kompajlera je korištena unapređena Crenshawova metoda. 10 4. PROSTI ARITMETIČKI IZRAZI Svaki programer koji je imao iskustva u radu s asemblerskim i višim programskim jezicima prvo uočava drastičnu razliku u pristupu računanju aritmetičkih izraza. U višim programskim jezicima se oponaša klasična forma matematičkih izraza, kakva je u upotrebi još od 18. vijeka. Ova forma je, doduše, prilagođena računarskim tastaturama (kosa crta umjesto razlomačke i zvjezdica umjesto podrazumijevanog množenja), ali su prioriteti računanja sačuvani. Unutar jednog izraza množenje ima prioritet nad sabiranjem, a zagrade nad ostalim operacijama. 4.1. Struktura tipičnih aritmetičkih izraza Asemblerski jezici (ali i neki viši programski jezici kao što su FORTH, Lisp, Befunge i rane verzije COBOL-a), s druge strane, imaju instrukcije za istovremeno obavljanje samo jedne aritmetičke operacije nad dva argumenta. Programer mora sam da odredi redoslijed izvršavanja ovakvih instrukcija da bi se dobio tačan rezultat izraza. Međurezultati se moraju čuvati u registrima, memorijskim lokacijama ili na steku. Koliko ovo može biti komplikovano, svjedoči činjenica da je značenje imena prvog višeg programskog jezika FORTRAN zapravo skraćenica od “prevodilac formula”. Stoga se i u ovom pristupu razvoju kompajlera kreće od prevođenja aritmetičkog izraza sa prioritetima u asemblerski program. Dva su uobičajena načina rješavanja ovog problema, nerekurzivni i rekurzivni. Nerekurzivni način podrazumijeva prevođenje iz aritmetičke (infiksne) u obrnutu poljsku notaciju (postfiksnu). U ovom radu je primijenjen rekurzivni način, jer on dovodi do kraćih listinga programa i konzistentniji je sa opisom sintakse jezika u proširenoj BNF formi ili sintaksnim dijagramima. Nakon gledanja jednog tipičnog aritmetičkog izraza 2+3*4-8+(7-6*2) sa jednocifrenim brojevima, ali sa prioritetima i zagradama, uočavaju se cjeline prikazane na slici Sl. 4.1.1. C1=2 C5=8 C2=3 C6=7 C3=4 C7=6 C8=2 C9=C7*C8 C11=(C10-C9) C4=C2*C3 C10=7 C12=C1+C4-C5+C11 Sl. 4.1.1. Cjeline u aritmetičkom izrazu 2+3*4-8+(7-6*2) Pogledavši cjelinu C12 (cijeli izraz) uočava se da se izraz sastoji od jednog ili više članova razdvojenih znakovima plus ili minus. Primjećuje se da i izraz C11 unutar zagrada ima istu strukturu. Uočena struktura aritmetičkog izraza se predstavlja sintaksnim dijagramom na slici Sl. 4.1.2. Okruglim ili ovalnim znakovima predstavljaju se simboli koji se dalje ne razrađuju (terminalni) a četvrtastim oni simboli koji se razrađuju (neterminalni). Izraz Član Član + Sl. 4.1.2. Izraz Gledajući cjeline C1, C4, C5, i C11, te C10 i C9, uočava se da se član izraza sastoji od jednog ili više faktora, razdvojenih zvjezdicom ili kosom crtom. Sam faktor je cifra ili, kao u cjelini C11, kompletan aritmetički izraz koji počinje otvorenom zagradom. Na slikama Sl. 4.1.3 i Sl. 4.1.4 prikazani su sintaksni dijagrami pojmova Član i Faktor. Član * Faktor Faktor / Sl. 4.1.3. Član 11 Faktor 0 1 9 ( Izraz ) Sl. 4.1.4. 4.2. Faktor Sintaksna analiza aritmetičkih izraza Prateći sintaksne dijagrame, lako je sintaksno analizirati izraze. Svaki od dijagrama može se izdvojiti u posebnu Pascal-sku proceduru, ili predstaviti odgovarajućim pseudokodom. Čvorišta u sintaksnim dijagramima gdje se pojam razdvaja u više podslučaja se mapiraju u uslovna grananja u pseudokodu, a vraćanja na već pročitani simbol u dijagramu se mapiraju u petlje u pseudokodu. Stoga procedure Izraz , Faktor i Član izgledaju u pseudokodu kao na slici Sl. 4.2.1. Izraz: Pozovi Član Sve dok je naredni simbol “+“ ili “- “ ,pozovi Član Član: Pozovi Faktor Sve dok je naredni simbol “*” ili “/“ , pozovi Faktor Faktor: Ako je naredni simbol cifra, faktor je u redu, Ako je naredni simbol “(“pozovi Izraz, zatim očekuj simbol “)” 4.2.1. U ostalim slučajevima,Sl. prijavi grešku. Pseudokod: Izraz, Član, Faktor 4.3. Generisanje koda za računanje aritmetičke izraze Intelovi 32 bitni procesori imaju umjeren broj procesorskih registara. Stoga, nije moguće cijeli aritmetički izraz držati u registrima, ali ga nema smisla ni u potpunosti držati na steku ili memorijskim lokacijama. Pošto je prethodnim operacijama izraz razložen na njegove sastavne komponente, uglavnom se operiše sa glavnim registrom, EAX i pomoćnim registrom EBX. Trenutni međurezultat se uvijek čuva u registru EAX, u kome je i jedan od operanada. Drugi operand je u registru EBX. Lako je prevesti faktor koji se sastoji od jedne konstante. Dovoljno je izvršiti odgovarajuću komandu MOV EAX,NN da se konstanta smjesti u registar EAX. Npr. konstanta 3 se prevodi u MOV EAX,3 Kada su u pitanju prevođenja izraza ili članova, na primjer, čuvanje u registrima postaje nedovoljno. Stoga se pri uočavanju sabiranja, oduzimanja, množenja ili dijeljenja, registar EAX mora sačuvati na steku, jer će poziv procedure za račun drugog operanda promijeniti sadržaj ovog registra. Po okončanju ove procedure, vrijednost sa steka se stavlja u EBX registar za komutativne operacije. Za nekomutativne operacije registar EAX se prebaci u EBX, a zatim vrijednost sa steka stavlja u EAX registar. Preostaje još da se obavi odgovarajuća ADD, SUB, IMUL ili IDIV instrukcija, čime registar EAX ponovo sadrži međurezultat. Tako se sabiranje prevodi u Pozovi Član Sve dok slijedi znak sabiranja, generiši naredne instrukcije PUSH EAX Pozovi Član POP EBX ADD EAX,EBX 12 Pozivom procedure Član uvijek se dobija međurezultat u EAX. Instrukcijom POP EBX se u EBX registar smješta vrijednost sa vrha steka. Ako se sa stekom pažljivo postupa, što će se raditi u cijelom procesu razvoja, na vrhu steka se nalazi sadržaj EAX registra nakon računanja prvog sabirka. Stoga će registar EBX imati vrijednost prvog sabirka, a registar EAX vrijednost drugog sabirka. Posljednjom instrukcijom dobija se zbir u registru EAX. Kako je i množenje komutativno generisani kôd za množenje je sličan. IMUL instrukcija će uzgred pokvariti sadržaj EDX registra, ali se bitan dio međurezultata čuva u EAX registru. Pozovi Faktor Sve dok slijedi znak množenja, generiši naredne instrukcije PUSH EAX Pozovi Faktor POP EBX IMUL EBX Oduzimanje nije komutativno, pa se mora prvi operand smjestiti u EAX, a drugi u EBX. Stoga generisani kôd može izgledati ovako: Pozovi Član Sve dok slijedi znak oduzimanja, generiši naredne instrukcije PUSH EAX Pozovi Član MOV EBX,EAX POP EAX SUB EAX,EBX Dakle, instrukcijom MOV EBX,EAX u registar EBX smiješta se drugi operand, dok će instrukcija POP EAX pokupiti prvi operand sa steka. Dijeljenje, pored toga što nije komutativno, zahtijeva da se u EDX nalazi predznačno proširen EAX registar, što se radi instrukcijom CDQ. Predznačno proširenje predstavlja kopiranje najvišeg bita EAX registra u sve bite EDX registra. Pozovi Faktor Sve dok slijedi znak dijeljenja, generiši naredne instrukcije PUSH EAX Pozovi Faktor MOV EBX,EAX POP EAX CDQ IDIV EBX Nakon cijele rutine, registar EAX će sadržati količnik, a EDX ostatak pri dijeljenju. 4.4. Prva verzija kompajlera Nakon analize strukture aritmetičkog izraza i pseudokoda za sintaksnu analizu dijelova izraza te generisanja mašinskog koda, može se pristupiti pisanju prve verzije kompajlera u Pascalu. Na slici Sl. 4.4.1 data je prva verzija kompajlera, koji je prosti prevodilac prostog aritmetičkog izraza koji se unosi sa tastature i prikazuje na ekranu. 13 Sl. 4.4.1. Prevodilac izraza program Kompajler; var pozicija: integer; znak: char; linija: string; procedure Emit(st: string); begin WriteLn(st); end; procedure Novi; begin pozicija := pozicija + 1; if pozicija <= Length(linija) then znak := linija[pozicija] else Halt; end; function UzmiKonstantu: integer; var rezultat: integer; begin rezultat := ord(znak) - ord('0'); Novi; UzmiKonstantu := rezultat; end; procedure Izraz; forward; procedure Faktor; var rezultat: integer; st: string; begin case znak of '0'..'9': begin rezultat := UzmiKonstantu; Str(rezultat, st); Emit(' MOV EAX,' + st); end; '(': begin Novi; Izraz; Novi; end else WriteLn('Greska'); end; end; procedure Clan; var z: char; begin Faktor; while (znak in ['*', '/', '%']) do begin z := znak; Emit(' PUSH EAX'); Novi; Faktor; case z of '*': begin Emit(' POP EBX'); Emit(' IMUL EBX'); end; '/': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); Emit(' CDQ'); Emit(' IDIV EBX'); end; end; end; end; procedure Izraz; var z: char; begin Clan; while (znak in ['+', '-']) do begin Emit(' PUSH EAX'); z := znak; Novi; Clan; case z of '+': begin Emit(' POP EBX'); Emit(' ADD EAX,EBX'); end; '-': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); Emit(' SUB EAX,EBX'); end; end; end; end; begin pozicija := 0; ReadLn(linija); Novi; Izraz; end. Iz listinga se uočava da pored procedura pored procedura Izraz, Clan i Faktor, koje su prikazane u pseudokodu postoje i procedure Emit, Novi i UzmiKonstantu. Procedura Emit je prosti ispis stringa na ekranu. Procedura Novi je najznačajnija procedura. Ona varijablu pozicija uvećava za 1 i zatim dohvati odgovarajući znak iz unesene linije u varijablu znak. Ta varijabla sadrži sljedeći simbol. Procedura UzmiKonstantu dohvata jednocifreni broj i koristeći funkciju ord dolazi do njegove numeričke vrijednosti. 4.5. Testni primjer Sa tastature se unosi sljedeći izraz: 2+3*4-8+(7-6*2); Kada ovaj primjer prođe kroz kompajler, dobije se asemblerski listing na slici Sl. 4.5.1. (Zadnji simbol u primjeru može biti tačka-zarez, ali i bilo koji drugi jer se ignoriše). Uz asemblerski listing dat je komentar sadržaja registara i steka nakon izvršenja svake od instrukcija MOV EAX,2 PUSH EAX MOV EAX,3 PUSH EAX MOV EAX,4 POP EBX IMUL EBX POP EBX ADD EAX,EBX PUSH EAX MOV EAX,8 MOV EBX,EAX POP EAX SUB EAX,EBX EAX=2, EBX=?, EAX=2, EBX=?, EAX=3, EBX=?, EAX=3, EBX=?, EAX=4, EBX=?, EAX=4, EBX=3, EAX=12, EBX=3, EAX=12, EBX=2, EAX=14, EBX=2, EAX=14, EBX=2, EAX=8, EBX=2, EAX=8, EBX=8, EAX=14, EBX=8, EAX=6, EBX=8, Sl. 4.5.1. stek =() stek =(2) stek =(2) stek =(3,2) stek =(3,2) stek =(2) stek =(2) stek =() stek =() stek =(14) stek =(14) stek =(14) stek =() stek =() PUSH EAX MOV EAX,7 PUSH EAX MOV EAX,6 PUSH EAX MOV EAX,2 POP EBX IMUL EBX MOV EBX,EAX POP EAX SUB EAX,EBX POP EBX ADD EAX,EBX EAX=6, EBX=8, stek =(6) EAX=7, EBX=8, stek =(6) EAX=7, EBX=8, stek =(7,6) EAX=6, EBX=8, stek =(7,6) EAX=6, EBX=8, stek =(6,7,6) EAX=2, EBX=8, stek =(6,7,6) EAX=2, EBX=6, stek =(7,6) EAX=12, EBX=6, stek =(7,6) EAX=12, EBX=12, stek =(7,6) EAX=7, EBX=12, stek =(6) EAX=-5, EBX=12, stek =(6) EAX=-5, EBX=6, stek =() EAX=1, EBX=6, stek =() Asemblerski listing prevedenog koda sa tokom izvršavanja Dakle, kao rezultat izvršenja programa sa slike Sl. 4.5.1 dobiva se 1, što se slaže sa vrijednošću aritmetičkog izraza. Naravno da bi ručno pisani asemblerski program bio daleko kraći. No, računar gleda ulaz sekvencijalno i ne može odmah pojednostaviti program, jer ne vidi unaprijed da li je uopšte potrebno npr. sačuvati EAX registar. U ovom trenutku optimizacija koda ima niži prioritet jer se može i bez nje. Daleko je bitniji problem što su izrazi samo sa jednocifrenim brojevima, nema varijabli i kontrolnih struktura, niti unarnih operatora. No, najveći nedostatak sadašnje verzije kompajlera 14 je što ona prevodi samo jednu jedinu liniju sa tastature na ekran. Prevedeni kôd se još uvijek ne može asemblirati, i njegovo izvršavanje se simulira na papiru. 4.6. Rezime poglavlja Razvoj kompajlera kreće od prevodioca prostog aritmetičkog izraza. U strukturi jednog tipičnog aritmetičkog izraza sa zagradama i prioritetima uočavaju se određene cjeline, Izraz, Član i Faktor koje se definišu sintaksnim dijagramima i realizuju odgovarajućim procedurama. U realizacija četiri osnovne aritmetičke operacije se koriste odgovarajuće instrukcije mikroprocesora, a međurezultati se uvijek čuvaju u EAX. Prva verzija kompajlera prevodi samo uneseni aritmetički izraz, s jednocifrenim brojevima sa tastature. Testni primjer za prvu verziju kompajlera je uspješan, no programski jezik u ovom trenutku nema nikakvih kontrolnih struktura, niti mogućnost prevođenja iz datoteka. 15 5. PREVOĐENJE IZ DATOTEKA, BLOKOVI, VIŠECIFRENI BROJEVI Prva verzija kompajlera prevodi samo jedan jedini aritmetički izraz u asemblerski jezik. Aritmetički izraz se ne može sačuvati na disku nego se svaki put mora ponovo unositi. Izlazne asemblerske naredbe se takođe ne mogu direktno proslijediti asembleru u cilju generisanja izvršnog koda. 5.1. Format instrukcija Da bi se ovaj prevodilac mogao zvati kompajlerom višeg programskog jezika a ne prevodiocem jednog izraza, neophodno je omogućiti da se izvorni kod iz jedne datoteke prevodi u asemblerski ili mašinski kod u drugoj datoteci. Iako postoje kompajleri koji sve rade u memoriji, ipak su oni koji prevode iz datoteke u datoteku neuporedivo upotrebljiviji. Pored ovoga, ulazni program treba da se sastoji od više naredbi ili aritmetičkih izraza, da bi se uopšte moglo govoriti o programu. U ovom trenutku donosi se jedna ključna odluka u izboru koncepcije programskog jezika vezano za format pisanja njegovih naredbi. U praksi postoje tri takva formata. Bajtovski format (mašinski jezik, Befunge, Forth) definiše da jedna naredba zauzima jedan bajt ili svega nekoliko njih. Linijski format (asemblerski jezik, Fortran, BASIC, XBASE) određuje da se jedna naredba (ponekad i više od jedne) sadrži u jednoj liniji izvornog koda. Slobodni format (Pascal, Lisp, C, Java) dopušta da se naredbe pišu u više redova. Kako je slobodni format ujedno i najpraktičniji, bit će primijenjen i u programskom jeziku koji se sada razvija. Odluka o izboru slobodnog formata povlači sljedeću odluku: Da li za oznake početka i kraja grupe naredbi koristiti ključne riječi (kao u Pascalu) ili simbole (kao u C-u). Prepoznavanje simbola je jednostavnije od prepoznavanja ključnih riječi, pa će ovaj jezik više podsjećati na C nego na Pascal, iako će kasnije imati elemenata i jednog i drugog jezika. Osim toga, ključne riječi će biti uvedene znatno kasnije. 5.2. Blokovi Skup naredbi se zove blok i uokviren je vitičastim zagradama. Ipak, iz praktičnih razloga prepoznavanja simbola, prva vitičasta zagrada je sastavni dio drugih struktura. Iza svake naredbe unutar bloka se nalazi simbol tačka-zarez (;). Program se sastoji od vitičaste zagrade i jednog bloka. To se može predstaviti sintaksnim dijagramima na slikama Sl. 5.2.1 i Sl. 5.2.2. Program: Blok { Sl. 5.2.1. Program Blok Izraz ; } Sl. 5.2.2. Blok Pseudokod za realizaciju bloka izgleda kao na slici Sl. 5.2.3 Sve dok ne slijedi “}” izvrši Izraz i pokupi simbol “;” Pokupi simbol “}” Sl. 5.2.3. 5.3. Pseudokod, relizacija blokova Modifikacije procedura kompajlera zbog prevođenja iz datoteke Procedura Novi treba da sada čita znakove iz ulazne datoteke, ignorišući blankove kao i neprintabilne znakove (ASCII <32) i nove redove. Stoga je ona sada složenija. U pseudokodu procedura Novi izgleda ovako: Početak sekvence Uvećaj pokazivač unutar linije za 1 Ako je pokazivač prešao kraj linije Uvećaj brojač linija za 1, učitaj novu liniju s diska i pokazivač postavi na 1 Varijabli znak dodijeli slovo linije na poziciji pokazivača. Ako je linija prazna, dodijeli varijabli znak blanko Ponavljaj sve dok je znak blanko ili neprintabilan, a nije kraj ulazne datoteke Sl. 5.3.1. Pseudokod, procedura Novi 16 Procedura IdiDo ima kao argument karakter. Ona treba da prijavi grešku ukoliko znak koji slijedi iz ulazne datoteke nije onaj koji je naveden kao argument ove procedure. Procedura Greska čiji je argument string, prikazuje tekst greške na ekranu, zatvara datoteke i prekida izvršenje kompajlera. Ovo može zvučati prilično nepraktično, jer ovako dizajnirani kompajler prevodi samo do prve greške. Sa današnjim računarima i interaktivnim radom to ne mora biti problem, što dokazuje uspjeh Turbo Pascala koji je sve do svoje desete verzije (Delphi 2) potpuno zanemarivao oporavak od grešaka. Oporavak od grešaka zahtijeva dosta dodatnog koda što smanjuje razumljivost rada kompajlera. Procedura Emit se nije mnogo izmijenila. Umjesto na ekran, izlaz se šalje u izlaznu datoteku. 5.4. Modifikacije kompajlera zbog generisanja datoteka sa asemblerskim kodom Nije dovoljno samo prevedene aritmetičke izraze usmjeriti u datoteku. Dobijeni asemblerski program treba prevesti nekim 32-bitnim asemblerom, kakvi su MASM, TASM ili NASM. Osim toga, mora postojati i određeni kôd da se program uspješno završi i vrati kontrolu operativnom sistemu. U programerskom žargonu taj dio koda se zove entry stub ili ulazni kôd i on izgleda kao na slici Sl. 5.4.1 . U suštini je ovim rečeno asembleru da generiše 32 bitni mašinski program, prilagođen Windows operativnom sistemu. Nakon generisanog programa se nalazi poziv rutine za završetak procesa i rezervisano mjesto za 26 varijabli. .386 .MODEL FLAT,STDCALL OPTION CASEMAP:NONE EXTRN ExitProcess@4:NEAR .CODE ULAZ: JMP GLAVNI GLAVNI: ..... generisani program ..... PUSH 0 CALL ExitProcess@4 .DATA GLOBALV DD 26 DUP(0) END ULAZ Sl. 5.4.1. Entry stub – standardni asemblerski ulazni kôd Procedura Prevedi emituje ovaj ulazni kôd i poziva proceduru Blok. Procedura Prevedi se poziva iz procedure Glavni, koja otvara ulaznu i izlaznu datoteku. Imena ovih datoteka se navode kao argumenti komandne linije prilikom poziva kompajlera koristeći, npr.: KOMP32V2 PRIMJER.JEZ PRIMJER.ASM Iako većina današnjih programa koristi menije umjesto komandne linije, zbog kratkoće programa i koncentracije na proces kompajliranja a ne na korisnički interfejs, ovaj kompajler je realizovan u formi komande iz komandne linije. 5.5. Proširenja aritmetičkih izraza Napravljene su određene izmjene i u samim aritmetičkim izrazima. Najvažnije je što numeričke konstante nisu više jednocifrene. Dohvatanje konstante se može izvesti algoritmom sa slike Sl. 5.5.1 Uzmi konstantu Rezultat postavi na 0 Sve dok je znak koji slijedi između 0 i 9 rezultat postavi na 10 * rezultat + vrijednost cifre znaka, pa uzmi novi znak Ako je znak blanko dohvati novi Sl. 5.5.1. Promijenjeni algoritam za dohvatanje konstante Lako je dodati operaciju ostatka pri dijeljenju koja se, u skladu sa konvencijom iz C-a, označava znakom %. Dovoljno je obaviti operaciju dijeljenja i nakon nje izvršiti jedno MOV AX,DX 17 U skladu sa uvođenjem operacije ostatka pri dijeljenju mijenja se sintaksa jezičkog pojma član i ona sada izgleda kao na slici Sl. 5.5.2. Nema potrebe pisati pseudokod, jer je modifikacija odgovarajuće procedure član trivijalna. Član % Faktor Faktor * / Sl. 5.5.2. Član Jezički pojam Faktor (čija je nova verzija prikazana na slici Sl. 5.5.3) i odgovarajuća procedura proširuju se unarnim minusom. Implementacija unarnog minusa rekurzivno poziva Faktor, a nakon tog pozva dodaje se naredba NEG EAX . Faktor: Faktor - Numerička konstanta ( Izraz ) Sl. 5.5.3. Faktor U prilogu 2 na kraju rada dat je listing druge verzije kompajlera. Tamnijom bojom slova su označene izmjene u odnosu na prvu verziju. 5.6. Testni primjer Na slici Sl. 5.6.1 primjer malog programa. Treba kreirati datoteku ulaz2.jez sa sljedećim sadržajem: { 2+3*8; 6*8*(4-2); } Sl. 5.6.1. Primjer za testiranje prve verzije kompajlera Iza zadnje vitičaste zagrade potrebno je preći u novi red. Nakon kompajliranja ovog primjera sa KOMP32V2 ULAZ2.JEZ ULAZ2.ASM dobije se asemblerski listing prikazan na slici Sl. 5.6.2: .386 .MODEL FLAT,STDCALL OPTION CASEMAP:NONE EXTRN ExitProcess@4:NEAR .CODE ULAZ: JMP GLAVNI ;{ ; 2+3*8; GLAVNI: MOV EAX,2 PUSH EAX MOV EAX,3 PUSH EAX MOV EAX,8 POP EBX IMUL EBX POP EBX ADD EAX,EBX ; 6*8*(4-2); MOV EAX,6 PUSH EAX MOV EAX,8 POP EBX IMUL EBX PUSH EAX MOV EAX,4 PUSH EAX MOV EAX,2 MOV EBX,EAX POP EAX SUB EAX,EBX POP EBX IMUL EBX ;} ;} PUSH 0 CALL ExitProcess@4 .DATA GLOBALV DD 26 DUP(0) END ULAZ Sl. 5.6.2. Asemblerski listing dobijen kompajlerom Prilikom generisanja listinga dodano je da se linija izvornog koda šalje u asemblerski program kao komentar. Iza te linije obično slijede asemblerske linije koje implementiraju navedenu liniju koda u višem programskom jeziku. Asemblerski listing još uvijek nije pravi mašinski program. Da bi se on preveo u mašinski program, treba pokrenuti asembler, na primjer Microsoftov MASM 6.14 komandom ml /c /coff /Fl ulaz2.asm 18 što znači da se prevodi bez linkovanja u Common object file format (coff) uz generisanje listinga. Kao rezultat ovog asembliranja dobijaju se datoteke ulaz2.obj i ulaz2.lst. Datoteku u OBJ formatu sada treba povezati sa drugim takvim datotekama ili bibliotekama rutina koje se nalaze u LIB datotekama. To se radi programom koji se zove linker. Kao primjer uzima se Microsoftov LINK 5.12 i pokreće sa link /defaultlib:kernel32.lib /subsystem:console ulaz2.obj Ovo znači da se ulaz2.obj povezuje sa bibliotekom funkcija kernel32.lib praveći ulaz2.exe Program ULAZ2.EXE može se pokrenuti, neće pasti, nego se samo uspješno završava ne prikazujući ništa na ekranu. To je i za očekivati, pošto se rezultati izraza samo smještaju u AX po njihovom izvršenju. Program bi se eventualno mogao pratiti korak po korak koristeći debager. Na slici Sl. 5.6.3 dati su izgled LST datoteke koja daje heksadekadni prikaz generisanog mašinskog koda uz odgovarajući asemblerski kôd, izgled objektne (OBJ) te izvršne (EXE) datoteke. Mnogi kompajleri direktno prevode u objektnu ili izvršnu datoteku. Formati OBJ i EXE datoteka su, međutim, dosta složeni, nepregledni i glomazni i njihov opis je izvan opsega ovog rada. No, poredeći prevedeni kôd u LST datoteci i posebno označene bajtove u OBJ i EXE datotekama na slici Sl. 5.6.3 prepoznaje se da je program korektno preveden u mašinski jezik. Ostatak datoteke OBJ sadrži tabele za relociranje u slučaju spajanja različitih modula. EXE datoteka, pored mašinskog koda testnog programa, sadrži i dio koda koji sprječava izvršavanje programa pod 16-bitnim MS DOS-om, spisak dinamičkih biblioteka i rutina iz njih koje se uvezuju sa korisničkim programom te relokacione tabele . Turbo Dump 000000: 000010: 000020: 000030: 000040: 000050: 000060: 000070: 000080: 000090: 0000A0: 0000B0: 0000C0: 0000D0: 0000E0: 0000F0: 000100: 000110: 000120: 000130: 000140: 000150: 000160: 000170: 000180: 000190: 0001A0: 0001B0: 0001C0: 0001D0: 0001E0: 0001F0: 000200: 000210: 000220: 4C 00 00 00 61 D8 40 00 00 00 F7 5B D8 00 00 00 00 00 00 00 2D 65 61 40 03 00 00 00 00 00 5A 72 0C 00 73 Version 5.0.16.4 Copyright (c) 1988, 1998 Borland International Display of File ULAZ2.OBJ 01 00 00 00 00 00 00 00 00 00 EB F7 58 00 00 00 00 00 00 00 65 00 7A 63 00 00 00 00 00 00 00 65 00 00 73 03 00 00 00 00 00 30 00 00 00 5B EB 2B 07 00 00 00 00 00 00 6E 00 32 6F 2E 03 00 02 00 00 00 63 00 13 40 00 00 00 00 00 00 C0 00 00 50 03 50 C3 00 00 00 00 00 00 00 74 00 2E 6D 74 01 00 00 00 00 00 74 00 00 34 36 2E 42 01 42 00 2E 0C 00 B8 C3 B8 5B 00 00 00 00 00 00 00 72 00 61 70 65 42 00 00 00 00 00 76 00 00 00 5F 74 00 00 00 00 64 00 00 03 B8 04 F7 00 00 00 00 00 00 00 79 00 73 2E 78 00 00 00 00 00 00 65 00 00 00 84 65 00 00 00 00 72 00 00 00 06 00 EB 14 00 00 00 00 00 00 3A 00 6D 69 74 00 2E 03 00 00 00 00 00 5F 00 3D 78 00 00 00 00 65 00 00 00 00 00 6A 00 00 00 00 00 00 00 55 00 00 64 00 00 64 01 00 00 00 00 00 45 00 4C 74 8C 20 00 00 63 40 00 00 00 00 00 00 00 00 00 00 00 00 4C FE 00 FC 00 01 61 68 00 20 01 00 00 78 00 01 00 00 00 00 00 74 01 0A 50 00 50 E8 00 00 00 00 00 00 00 41 FF 00 20 00 00 74 00 00 00 00 00 00 69 00 00 00 00 30 00 00 76 00 00 B8 50 B8 00 00 00 00 00 00 00 00 5A 00 00 12 00 00 61 00 00 02 20 03 00 74 00 00 00 00 60 00 00 65 00 00 08 B8 02 00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 50 00 0B 00 CE 2E 68 00 AA 00 EB 00 08 00 00 00 00 00 00 00 00 00 2E 67 00 FF 00 00 00 00 00 5F 02 00 00 72 00 00 00 00 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 66 01 00 FF 00 00 00 00 00 55 00 00 00 6F 00 00 00 00 61 00 00 00 00 B8 00 00 00 3E 00 00 00 00 00 00 00 69 75 00 00 01 00 00 00 04 4C 2E 03 00 63 00 00 00 00 74 00 00 00 00 02 5B 00 8B 00 00 00 00 00 00 00 00 6C 6C 00 00 00 00 00 00 00 41 64 01 00 65 00 L...6_.=L....... .....text....... ....B........... ........ .0`.dat a...B.......h... ................ @.0..drectve.... ........@....... ................ ...P.....P.....[ ..[.......P..... [..P.....P...... .X+.[..j......>. ................ ................ ................ ................ ................ ................ ................ -entry:ULAZ .fil e...........g.ul az2.asm......... @comp.id. ...... ...text......... ....B........... .......data..... ........h....... ................ ........ ..._ULA Z......... ....d rectve.......... ................ ......_ExitProce ss@4............ Microsoft (R) Macro Assembler Version 6.14.8444 09/15/02 12:21:42 ulaz2.asm Page 1 - 1 .386 .MODEL FLAT,STDCALL OPTION CASEMAP:NONE EXTRN ExitProcess@4:NEAR 00000000 00000000 00000000 EB 00 .CODE ULAZ: JMP GLAVNI ;{ ; 00000002 00000002 00000007 00000008 0000000D 0000000E 00000013 00000014 00000016 00000017 B8 50 B8 50 B8 5B F7 5B 03 00000002 GLAVNI: MOV EAX,2 00000003 MOV EAX,3 00000008 MOV EAX,8 EB IMUL EBX C3 ADD EAX,EBX PUSH EAX PUSH EAX POP EBX POP EBX ; 00000019 0000001E 0000001F 00000024 00000025 00000027 00000028 0000002D 0000002E 00000033 00000035 00000036 00000038 00000039 B8 50 B8 5B F7 50 B8 50 B8 8B 58 2B 5B F7 2+3*8; 00000006 6*8*(4-2); MOV EAX,6 PUSH EAX 00000008 MOV EAX,8 EB IMUL EBX 00000004 MOV EAX,4 00000002 D8 MOV EAX,2 MOV EBX,EAX C3 SUB EAX,EBX EB IMUL EBX POP EBX PUSH EAX PUSH EAX POP EAX POP EBX ;} ;} 0000003B 0000003D 00000000 00000000 6A 00 E8 00000000 E 0000001A [ 00000000 ] PUSH 0 CALL ExitProcess@4 .DATA GLOBALV DD 26 DUP(0) Turbo Dump Version 5.0.16.4 Copyright (c) 1988, 1998 Borland International Display of File ULAZ2.EXE 000000: 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 000010: B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000030: 00 00 00 00 00 00 00 00 00 00 00 00 B0 00 00 00 000040: 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 000050: 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F 000060: 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 000070: 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 000080: 5D 17 1D DB 19 76 73 88 19 76 73 88 19 76 73 88 000090: 19 76 73 88 1D 76 73 88 E5 56 61 88 18 76 73 88 0000A0: 52 69 63 68 19 76 73 88 00 00 00 00 00 00 00 00 0000B0: 50 45 00 00 4C 01 03 00 38 5F 84 3D 00 00 00 00 0000C0: 00 00 00 00 E0 00 0F 01 0B 01 05 0C 00 02 00 00 0000D0: 00 04 00 00 00 00 00 00 00 10 00 00 00 10 00 00 0000E0: 00 20 00 00 00 00 40 00 00 10 00 00 00 02 00 00 0000F0: 04 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 000100: 00 40 00 00 00 04 00 00 00 00 00 00 03 00 00 00 000110: 00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00 000120: 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 000130: 08 20 00 00 28 00 00 00 00 00 00 00 00 00 00 00 000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000180: 00 00 00 00 00 00 00 00 00 20 00 00 08 00 00 00 000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0001A0: 00 00 00 00 00 00 00 00 2E 74 65 78 74 00 00 00 0001B0: 48 00 00 00 00 10 00 00 00 02 00 00 00 04 00 00 0001C0: 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 60 0001D0: 2E 72 64 61 74 61 00 00 54 00 00 00 00 20 00 00 0001E0: 00 02 00 00 00 06 00 00 00 00 00 00 00 00 00 00 0001F0: 00 00 00 00 40 00 00 40 2E 64 61 74 61 00 00 00 000200: 68 00 00 00 00 30 00 00 00 02 00 00 00 08 00 00 000210: 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 000220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0002A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0002B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0002C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0002D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0002E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0002F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0003A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0003B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0003C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0003d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0003E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0003F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000400: EB 00 B8 02 00 00 00 50 B8 03 00 00 00 50 B8 08 000410: 00 00 00 5B F7 EB 5B 03 C3 B8 06 00 00 00 50 B8 000420: 08 00 00 00 5B F7 EB 50 B8 04 00 00 00 50 B8 02 000430: 00 00 00 8B D8 58 2B C3 5B F7 EB 6A 00 E8 00 00 000440: 00 00 FF 25 00 20 40 00 00 00 00 00 00 00 00 00 000450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........................................................ 0005D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0005E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0005F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000600: 38 20 00 00 00 00 00 00 30 20 00 00 00 00 00 00 000610: 00 00 00 00 46 20 00 00 00 20 00 00 00 00 00 00 000620: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000630: 38 20 00 00 00 00 00 00 75 00 45 78 69 74 50 72 000640: 6F 63 65 73 73 00 4B 45 52 4E 45 4C 33 32 2E 64 000650: 6C 6C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ....................................................... 0009D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0009E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0009F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 END ULAZ Sl. 5.6.3. Izgled OBJ, LST i EXE datoteka MZ.............. ........@....... ................ ................ ........!..L.!Th is program canno t be run in DOS mode....$....... ]....vs..vs..vs. .vs..vs..Va..vs. Rich.vs......... PE..L...8_.=.... ................ ................ . ....@......... ................ .@.............. ................ ................ . ..(........... ................ ................ ................ ................ ......... ...... ................ .........text... H............... ............ ..` .rdata..T.... .. ................ ....@[email protected]... h....0.......... ............@... ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ ................ .......P.....P.. ...[..[.......P. ....[..P.....P.. .....X+.[..j.... ...%. @......... ................ ................ ................ ................ ................ ................ 8 ......0 ...... ....F ... ...... ................ 8 ......u.ExitPr ocess.KERNEL32.d ll.............. ................ ................ ................ ................ ................ ................ 19 5.7. Rezime poglavlja Format pisanja instrukcija u jeziku koji se razvija u ovom radu je slobodni, a od ove verzije kompajlera moguće je prevoditi iz datoteke u datoteku. Program se više ne sastoji od jednog aritmetičkog izraza, već od bloka naredbi. Novi način prevođenja zahtijeva modifikaciju procedura Novi i Emit, a uvode se procedure IdiDo i Greska. Asemblerski programi zahtijevaju određeni kôd koji se zove Entry stub, pa kompajler generiše i njega. Da bi aritmetički izrazi radili sa višecifrenim brojevima modifikovano je dohvatanje konstante. Dodavanje unarnog minusa i ostatka pri dijeljenju zahtijeva promjenu procedura Faktor i Clan. Iz testnog primjera uspješno se generiše asemblerski listing, a iz asemblerskog listinga se dobijaju objektni i izvršni kôd. Prilog 2: Verzija izvornog koda kompajlera br. 2 program Kompajler; const OCEKIVANO = 'Ocekivano '; GRIZRAZ = 'Izraz'; var ulaz, izlaz: text; pozicija, brojaclinija: integer; znak: char; linija: string; procedure Greska(poruka: string); begin WriteLn(poruka); WriteLn(brojaclinija, ':', linija); Close(ulaz); Close(izlaz); Halt; end; procedure Emit(st: string); begin WriteLn(izlaz, st); end; procedure Novi; begin repeat pozicija := pozicija + 1; if pozicija > Length(linija) then begin brojaclinija := brojaclinija + 1; if not (Eof(ulaz)) then ReadLn(ulaz, linija); Emit(';' + linija); pozicija := 1; end; if Length(linija) > 0 then znak := linija[pozicija] else znak := ' '; until (znak > ' ') or Eof(ulaz) end; procedure IdiDo(z: char); begin if (znak <> z) then Greska(OCEKIVANO + z); Novi; end; function UzmiKonstantu: integer; var rezultat: integer; begin rezultat := 0; while (znak >= '0') and (znak <= '9') do begin rezultat := 10 * rezultat + ord(znak) - ord('0'); Novi; end; if (znak = ' ') or (znak = '`') then Novi; UzmiKonstantu := rezultat; end; procedure Izraz; forward; procedure Faktor; var rezultat: integer; st: string; begin case znak of '-': begin Novi; Faktor; Emit(' NEG EAX'); end; '0'..'9': begin rezultat := UzmiKonstantu; Str(rezultat, st); Emit(' MOV EAX,' + st); end; '(': begin Novi; Izraz; IdiDo(')'); end; else Greska(GRIZRAZ); end; end; procedure Clan; var z: char; begin Faktor; while (znak in ['*', '/', '%']) do begin z := znak; Emit(' PUSH EAX'); Novi; Faktor; case z of '*': begin Emit(' POP EBX'); Emit(' IMUL EBX'); end; '/', '%': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); Emit(' CDQ'); Emit(' IDIV EBX'); if z = '%' then Emit(' MOV EAX,EDX'); end; end; end; end; procedure Izraz; var z: char; begin Clan; while (znak in ['+', '-']) do begin Emit(' PUSH EAX'); z := znak; Novi; Clan; case z of '+': begin Emit(' Emit(' end; '-': begin Emit(' Emit(' Emit(' end; end; end; end; POP EBX'); ADD EAX,EBX'); MOV EBX,EAX'); POP EAX'); SUB EAX,EBX'); procedure Blok; begin while znak <> '}' do begin Izraz; IdiDo(';'); end; IdiDo('}'); end; procedure Prevedi; begin Emit('.386'); Emit('.MODEL FLAT,STDCALL'); Emit('OPTION CASEMAP:NONE'); Emit('EXTRN ExitProcess@4:NEAR'); Emit('.CODE'); Emit('ULAZ:'); Emit(' JMP GLAVNI'); pozicija := 0; Novi; IdiDo('{'); Emit('GLAVNI:'); Blok; Emit(' PUSH 0'); Emit(' CALL ExitProcess@4'); Emit('.DATA'); Emit('GLOBALV DD 26 DUP(0)'); Emit('END ULAZ') end; procedure Glavni; var linija: string; begin Assign(ulaz, paramstr(1)); Assign(izlaz, paramstr(2)); brojaclinija := 0; linija := ''; Reset(ulaz); Rewrite(izlaz); Prevedi; Close(ulaz); Close(izlaz); WriteLn('Prevedeno bez greske'); end; begin Glavni end. 20 6. VARIJABLE, RELACIONI OPERATORI, USLOVI, PETLJE Iako sposobna da generiše asemblerski kod, prethodna verzija kompajlera još uvijek ne liči na prevodilac pravog programskog jezika jer nedostaju dvije izuzetno bitne stvari, mogućnost smještanja međurezultata u varijable i mogućnost grananja programa. Stoga je potrebno uvesti elementarne kontrolne strukture, varijable i proširiti aritmetičke izraze. 6.1. Proširenje aritmetičkih izraza Aritmetički izraz se proširuje relacionim operatorima, operatorom dodjeljivanja, te unarnim operatorima. Za razliku od Pascala, na primjer, dodjeljivanje nije poseban iskaz, nego sastavni dio aritmetičkog izraza (kao u C-u), te je pogodnije za ovu koncepciju razvoja programskog jezika, koja kreće od koncepta izraza. Operator dodjeljivanja će, privremeno, biti dvotačka “:”. Primjer a:b:c:2; dodjeljuje varijabli c vrijednost 2, zatim se varijabla c dodjeli varijabli b, pa varijabla b varijabli a. Ovaj primjer dovodi do pojma lijeve i desne asocijativnosti operatora. Taj pojam odgovara na pitanje koji operandi se prvi računaju kada je prioritet više upotrijebljenih operatora jednak. Za sabiranje, oduzimanje, množenje i dijeljenje korištena je lijeva asocijativnost. Npr. 3+2-4 će prvo izračunati 3, njemu dodati 2 a zatim od toga oduzeti 4. Dodjeljivanje je desno asocijativno, što se vidi iz gore navedenog primjera. Već je u prvoj fazi pokazano da se ponavljanje lijevo asocijativnih operatora realizuju while petljom. Suprotno tome, ponavljanje desno asocijativnih operatora realizuje se rekurzijom unutar obrade desnog operanda. Relacioni operatori su =,>,< i # (različito). Rezultat poređenja dva izraza može biti 0 ako je relacija netačna ili 1 ako je tačna. Ovi operatori nisu asocijativni, jer bi to dovelo do zbunjujućih situacija. Npr. izraz 3>2>1 u matematici je tačan i predstavlja činjenicu da je broj 2 veći od 1 a manji od 3, ali u kontekstu izraza u računaru ima sasvim drugu semantiku. Izraz 3>2 daje vrijednost 1, a zatim se ta vrijednost 1 poredi da li je veća od 1, što nije tačno, pa cijeli izraz vraća vrijednost 0. Pošto takva semantika nije mnogo korisna, neće biti realizovana. Operatori dodjeljivanja i relacioni operatori trebaju da imaju najniži prioritet. To znači da se mora definisati novi jezički pojam Izraz dodjeljivanja. Izraz dodjeljivanja = > < Izraz Izraz # Izraz dodjeljivanja Sl. 6.1.1. Izraz dodjeljivanja Na dijagramu sa slike Sl. 6.1.1 se vidi da neasocijativni operatori (relacioni) sa desne strane imaju pojam Izraz dok se za desno asocijativni operator dodjeljivanja sa desne strane nalazi pojam Izraz dodjeljivanja. : Za realizaciju poređenja pomaže instrukcija SETcc AL, gdje cc predstavlja uslov koji predstavlja testiranje flegova, obično vezano za rezultat prethodne instrukcije. Ova instrukcija postavlja AL na 1 ako je uslov ispunjen odnosno na 0 ako nije, upravo ono što treba, bez korištenja uslovnih skokova. Generisani kôd za relacione operatore izgleda kao na slici Sl. 6.1.2 Pozovi Izraz PUSH EAX Pozovi Izraz POP EBX CMP EBX,EAX SETE AL ili SETG AL ili SETL AL ili SETNE AL (respektivno na =,>,<,#) AND EAX,0FFh Sl. 6.1.2. Generisani kôd za relacione operatore 21 Dakle, analogno operaciji sabiranja, prvi operand se dobija u EBX, a drugi u EAX registru, a poređenje se vrši CMP EBX,EAX instrukcijom. Rezultat poređenja se dobije u fleg registru, a zatim se odgovarajućom SETE, SETG, SETL ili SETNE instrukcijom postavlja AL registar na željenu vrijednost. Pošto preostala tri bajta registra EAX mogu imati slučajnu vrijednost, posljednjom AND EAX,0FFh se oni postavljaju na nule. Kod dodjeljivanja, međutim, nije potrebna vrijednost prvog operanda, nego njegova adresa. Uzima se da se ova adresa nalazi u EBX registru. To je dovoljno generalno rješenje, jer se vrijednost ne dodjeljuje samo varijablama, nego i nekim izrazima (npr. onim koji su rezultati pointerskih operacija). Vrijednost drugog operanda se nalazi u EAX registru. Stoga je generisani kôd za ovu operaciju oblika prikazanog na slici Sl. 6.1.3. Izvrši Izraz PUSH EBX Izvrši Izraz dodjeljivanja POP EBX MOV [EBX],EAX Sl. 6.1.3. Generisani kôd za operator dodjeljivanja U ovoj fazi se još uvijek jednostavnost kompajlera drži u prvom planu. Stoga, imena varijabli, koje se upravo uvode, su jednoslovna i to predstavljena malim slovima. To, u ovom trenutku, ukida potrebu za tabelom imena varijabli i pretraživanjem iste. Umjesto toga, svih 26 varijabli se može držati u statički alociranom prostoru. Statički alociran prostor je deklarisan kao GLOBALV DD 26 DUP(0). Ovo znači da će svaka varijabla zauzimati po 4 bajta. GLOBALV[0]- GLOBALV[3] Varijabla a Sl. 6.1.4. GLOBALV[4]-GLOBALV[7] Varijabla b GLOBALV[8]... Varijabla c Organizacija prostora za globalne varijable Pogledom na sliku Sl. 6.1.4, uočava se da ako se od ASCII koda imena varijable oduzme ASCII kôd slova 'a' i rezultat pomnoži sa 4, dobije se relativni pomak u odnosu na labelu GLOBALV a time i adresa tražene varijable. Nad varijablom se mogu obavljati dvije funkcije. Ona se može čitati, ali joj se može i dodijeliti vrijednost. Stoga je potrebno da nakon pristupa varijabli registar EBX ima njenu adresu, a registar EAX njenu vrijednost. Dosljedno dosadašnjem radu, vrijednost varijable c se može dobiti koristeći LEA EBX,GLOBALV[8] MOV EAX,[EBX] Da bi se uvele varijable potrebna je izmjena jezičkog pojma Faktor. Pored varijabli, u ovoj verziji kompajlera uvode se i novi unarni operatori. Svi oni se realizuju na isti način kao unarni minus uveden u prethodnoj verziji kompajlera, dakle rekurzivnim pozivom procedure Faktor, a zatim generisanjem koda koji modifikuje registar EAX. Unarni operatori su navedeni u tabeli na slici Sl. 6.1.5: Oznaka operatora Značenje operatora Instrukcije koje se generišu nakon poziva procedure Faktor - Aritmetički unarni minus. Promjena predznaka registra EAX NEG EAX ~ Binarna negacija. Pretvaranje svih nula u jedinice a svih jedinica u nule unutar binarnog zapisa registra EAX NOT EAX & Adresa operanda. Vraća adresu izraza koji slijedi (tipično varijabla) MOV EAX,EBX * Pointer/pokazivač. Vraća cijeli broj koji se nalazi na adresi koja se dobije računom izraza MOV EBX,EAX Logička negacija. Ako je EAX jednak 0 on dobija vrijednost 1, inače dobija vrijednost 0 CMP EAX,0 ! MOV EAX,[EBX] SETE AL AND EAX,0FFh Sl. 6.1.5. Unarni operatori 22 Uvođenje unarnih operatora zahtijeva da se promijene sintaksni dijagram za jezički pojam Faktor i odgovarajuća procedura za implementaciju tog jezičkog pojma. Realizacija te procedure data je u okviru listinga u prilozima. Faktor: ~ Faktor & * ! Numerička konstanta ( Izraz dodjeljivanja ) Varijabla Sl. 6.1.6. Faktor Uz dodatak relacionim operatorima, zgodno je uključiti i operatore konjunkcije, disjunkcije i ekskluzivne disjunkcije. Iz C-a se preuzimaju operatori &,| i ^ koji vrše operacije bit po bit, pa su oni upotrebljivi i za maskiranja bitova. Kako su sve tri operacije komutativne, realizacija je analogna sabiranju, sa kojim se dijeli i prioritet operacije. U tu svrhu se jezički pojam Izraz modifikuje da izgleda kao na slici Sl. 6.1.7. - Član + & Član | ^ Sl. 6.1.7. Logičke operacije se prevode u kôd sa slike Sl. 6.1.8: Izraz Pozovi Član PUSH EAX Pozovi Član POP EBX AND EAX,EBX ili OR EAX,EBX ili XOR EAX,EBX Sl. 6.1.8. Generisani kôd za logičke operacije Pošto se ne dodaje novi operator prioriteta množenja i dijeljenja, procedura Clan se ne mijenja. 6.2. Uslovi Za realizovanje programskih struktura uslova i petlje, potrebno je koristiti skokove u asemblerskom jeziku. U ovoj oblasti je generisanje asemblerskog programa jednostavnije od generisanja mašinskog programa, pogotovo kada su u pitanju skokovi unaprijed. To omogućavaju labele. Labele u generisanom listingu imaju oblik L1, L2, L3..., pri čemu je broj iza slova 23 L smješten u cjelobrojnu globalnu varijablu TrenLabela. Procedurom NovaLabela se taj broj uveća za 1 i zatim vrati u formi stringa. Uslov se može predstaviti sintaksnim dijagramom sa slike Sl. 6.2.1 Uslov: ? Izraz dodjeljivan ja Blok { Sl. 6.2.1. { Blok Uslov Jezik još nema ključnih riječi, pa se uslov označava znakom ?, zatim slijedi izraz koji treba da vrati vrijednost 0 ili 1, pa otvorena vitičasta zagrada i blok koji označavaju sekciju koja se izvršava ako je uslov ispunjen. Prethodni znak “?” je prikazan isprekidanim linijama u sintaksnom dijagramu jer se ne prepoznaje u proceduri Uslov koja implementira uslove nego u proceduri Blok. Na kraju jezičkog pojma Uslov nalazi se druga otvorena vitičasta zagrada i sekcija koja se izvršava ako uslov nije ispunjen. ? (a=3 & n>8) { b:8; c:2; } { b:12; } Sl. 6.2.2. Primjer uslova, treća verzija kompajlera Na slici Sl. 6.2.2 dat je primjer uslova koji radi sljedeće: Ako je varijabla a jednaka 3 i varijabla n veća od 8, varijabli b se dodjeljuje vrijednost 8, a varijabli c vrijednost 2. Ako bar jedan od gornjih uslova nije ispunjen, varijabla b dobija vrijednost 12. Uslov se smatra ispunjenim ako je rezultat izraza koji se ispituje različit od nule. Izraz ima rezultat u EAX registru. Stoga se uslov može realizovati kodom sa slike Sl. 6.2.3. Na slici se vidi da je potrebno generisati tri nove labele. Ovdje su one označene sa Londa, Linace i Lkrajuslova, a u praksi mogu biti, na primjer, L11, L12 i L13. Instrukcija CMP EAX,0 postavlja Z fleg na 1 ako je u EAX registru nula, a u protivnom Z fleg se postavi na 0. Stoga instrukcija JNE Londa izaziva skok na labelu Londa ako je EAX=0, a u protivnom se izvrši sljedeća instrukcija koja je bezuslovni skok na labelu Linace. Na kraju bloka koji se izvršava kada je uslov ispunjen, nalazi se skok na labelu Lkrajuslova da bi se preskočila sekcija koja se ne izvršava. Pozovi Izraz dodjeljivanja CMP EAX,0 JNE Londa JMP Linace Londa: Pozovi Blok JMP Lkrajuslova Linace: Pozovi Blok Lkrajuslova: .... Sl. 6.2.3. 6.3. Generisani kôd za realizaciju uslova Petlje Iako konceptualno složenije od uslova petlje su za realizaciju još jednostavnije. Kao sintaksni simbol petlje uzima se znak &, čije druge dvije upotrebe za adresu varijable i binarnu konjunkciju neće praviti konfuziju jer nema smisla da se u tom kontekstu nalaze na početku naredbe. Petlja se predstavlja sintaksnim dijagramom sa slike Sl. 6.3.1. 24 Petlja: & Izraz dodjeljivanja Blok { Sl. 6.3.1. Petlja Primjer & a<0 { a:a+1} sve dok je a manje od nula, uvećavaj varijablu a za 1. Petlja se može realizovati generisanim kodom kao na slici Sl. 6.3.2. Luslov: Pozovi Izraz dodjeljivanja CMP EAX,0 JNE Ldok JMP Lkrajpetlje Ldok: Pozovi Blok JMP Luslov Lkrajpetlje: .... Sl. 6.3.2. Generisanje koda za petlje Sa ovim tipom petlje (odgovara while petlji) mogu se realizovati i programi koji zahtijevaju ostala dva popularna tipa petlji (for i do/repeat). Programskom jeziku potrebno je sada dodati ulaz/izlaz. To je već stvar ovisna od operativnog sistema i ne može se realizovati bez asemblerskih potprograma ili poziva sistemskih procedura. Stoga se uvodi specijalni simbol \ , koji predstavlja da od sljedeće linije slijedi asemblerski kôd Nakon ovoga, kompajler jednostavno prepisuje naredne linije u generisani asemblerski kôd, sve dok se ne dođe do linije koja počinje znakom \. Sintaksni dijagram za asemblersku sekvencu se neće navoditi, jer je asemblerski jezik linijski orijentisan. 6.4. Generalizovani jezički pojam blok Jezički pojam Blok, i s njim vezana odgovarajuća procedura se sada mora redizajnirati da uključi uslove, petlje, asembler i izraz dodjeljivanja, kao na slici Sl. 6.4.1 Blok: & ? Petlja Uslov Izraz dodjeljivanja \ } ; Asembler Sl. 6.4.1. Jezički pojam blok To u realizaciji znači da procedura Blok treba da prepozna odgovarajući simbol i ovisno o njemu pozove odgovarajuću proceduru. Sada se može realizovati listing treće verzije kompajlera, pod imenom komp32v3, koji je naveden u prilogu 3. Izmjene u odnosu na drugu verziju prikazane su tamnijim slovima. 25 6.5. Testni primjer Kao primjer programa u ovoj verziji jezika uzeće se traženje kvadratnog korijena cijelog broja Heronovim algoritmom. Koristeći Heronov algoritam, program će naći cijeli dio korijena broja iz varijable n, pazeći da ne dođe do dijeljenja s nulom ili vađenja korijena negativnog broja, a zatim emitovati zvučni signal onoliko puta koliki je rezultat. Zvučni signal se generiše asemblerskim pozivom sistemske funkcije MessageBeep@4, koja se nalazi u biblioteci USER32.DLL, pri čemu se prije poziva mora na stek staviti broj -1. Treba unijeti sljedeći kôd sa slike Sl. 6.5.1 i snimiti ga pod imenom heron.jez { } n:200; } a:n; q:a; b:1; & q>0 & (b<10) { { \ ? (a>0) extrn MessageBeep@4:near { PUSH -1 a:(a+n/a)/2; CALL MessageBeep@4 b:b+1; \ } q:q-1; { } a:0; } Sl. 6.5.1. Traženje kvadratnog korijena Heronovim algoritmom Nakon naredbi komp32v3 heron.jez heron.asm ml /c /coff /Fl heron.asm | more link /defaultlib:user32.lib kernel32.lib /subsystem:console heron.obj i startanja prevedenog programa, zvučni signal se čuje 14 puta što je približno korijen iz 200. 6.6. Rezime poglavlja U trećoj verziji jezika aritmetički izrazi su prošireni relacionim i unarnim operatorima. Varijable su statički alocirane relativno od labele GLOBALV i njihova adresa se izračunava iz ASCII koda jednoslovnog imena varijable. Uslovi i petlje se označavaju simbolima ? i &. Moguće je uključivati asemblerske instrukcije. U ovoj verziji jezika moguće je pisati primjere iz oblasti cjelobrojne numeričke analize. Prilog 3: Verzija izvornog koda kompajlera br. 3 program Kompajler; const OCEKIVANO = 'Ocekivano '; GRIZRAZ = 'Izraz'; var ulaz, izlaz: text; pozicija, trenlabela, brojaclinija: integer; znak: char; linija: string; procedure NovaLabela(var ImeLabele: string); begin trenlabela := trenlabela + 1; Str(trenlabela, ImeLabele); end; procedure Greska(poruka: string); begin WriteLn(poruka); WriteLn(brojaclinija, ':', linija); Close(ulaz); Close(izlaz); Halt; end; procedure Emit(st: string); begin WriteLn(izlaz, st); end; procedure Novi; begin repeat pozicija := pozicija + 1; if pozicija > Length(linija) then begin brojaclinija := brojaclinija + 1; if not (Eof(ulaz)) then ReadLn(ulaz, linija); Emit(';' + linija); pozicija := 1; end; if Length(linija) > 0 then znak := linija[pozicija] else znak := ' '; until (znak > ' ') or Eof(ulaz) end; procedure IdiDo(z: char); begin if (znak <> z) then Greska(OCEKIVANO + z); Novi; end; function UzmiKonstantu: integer; var rezultat: integer; begin rezultat := 0; while (znak >= '0') and (znak <= '9') do begin rezultat := 10 * rezultat + ord(znak) - ord('0'); Novi; end; if (znak = ' ') or (znak = '`') then Novi; UzmiKonstantu := rezultat; end; procedure IzrazDodjeljivanja; forward; procedure Blok; forward; procedure Varijabla; var rezultat: integer; st: string; begin rezultat := (ord(znak) ord('a')) * 4; Str(rezultat, st); Emit( ' LEA EBX,GLOBALV[' + st + ']'); Emit(' MOV EAX,[EBX]'); 26 Novi; end; procedure Faktor; var rezultat: integer; st: string; begin case znak of '-': begin Novi; Faktor; Emit(' NEG EAX'); end; '~': begin Novi; Faktor; Emit(' NOT EAX'); end; '&': begin Novi; Faktor; Emit(' MOV EAX,EBX'); end; '*': begin Novi; Faktor; Emit(' MOV EBX,EAX'); Emit(' MOV EAX,[EBX]'); end; '!': begin Novi; Faktor; Emit(' CMP EAX,0'); Emit(' SETE AL'); Emit(' AND EAX,0FFh'); end; '0'..'9': begin rezultat := UzmiKonstantu; Str(rezultat, st); Emit(' MOV EAX,' + st); end; '(': begin Novi; IzrazDodjeljivanja; IdiDo(')'); end; 'a'..'z': Varijabla else Greska(GRIZRAZ); end; end; procedure Clan; var z: char; begin Faktor; while (znak in ['*', '/', '%']) do begin z := znak; Emit(' PUSH EAX'); Novi; Faktor; case z of '*': begin Emit(' POP EBX'); Emit(' IMUL EBX'); end; '/', '%': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); Emit(' CDQ'); Emit(' IDIV EBX'); if z = '%' then Emit(' MOV EAX,EDX'); end; end; end; end; procedure Izraz; var z: char; begin Clan; while (znak in ['+', '-', '&', '|', '^']) do begin Emit(' PUSH EAX'); z := znak; Novi; Clan; case z of '+': begin Emit(' POP EBX'); Emit(' ADD EAX,EBX'); end; '-': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); Emit(' SUB EAX,EBX'); end; '&': begin Emit(' POP EBX'); Emit(' AND EAX,EBX'); end; '|': begin Emit(' POP EBX'); Emit(' OR EAX,EBX'); end; '^': begin Emit(' POP EBX'); Emit(' XOR EAX,EBX'); end; end; end; end; procedure IzrazDodjeljivanja; var z: char; begin Izraz; case znak of ':': begin Emit(' PUSH EBX'); Novi; IzrazDodjeljivanja; Emit(' POP EBX'); Emit(' MOV [EBX],EAX'); end; {:} '=', '>', '<', '#': begin Emit(' PUSH EAX'); z := znak; Novi; Izraz; Emit(' POP EBX'); Emit(' CMP EBX,EAX'); case z of '=': Emit(' SETE AL'); '>': Emit(' SETG AL'); '<': Emit(' SETL AL'); '#': Emit(' SETNE AL'); end; Emit(' AND EAX,0FFh'); end; end; end; procedure Uslov; var sonda, sinace, skrajuslova: string; begin Novi; IzrazDodjeljivanja; Emit(' CMP EAX,0'); NovaLabela(sonda); NovaLabela(sinace); NovaLabela(skrajuslova); Emit(' JNE L' + sonda); Emit(' JMP L' + sinace); IdiDo('{'); Emit('L' + sonda + ':'); Blok; Emit(' JMP L' + skrajuslova); Emit('L' + sinace + ':'); IdiDo('{'); Blok; Emit('L' + skrajuslova + ':'); end; procedure Asembler; begin repeat ReadLn(ulaz, linija); if linija <> '\' then Emit(linija); if eof(ulaz) then linija := '\'; until linija[1] = '\'; pozicija := 1; znak := linija[pozicija]; IdiDo('\'); end; procedure Petlja; var sdok, skrajpetlje, suslov: string; begin Novi; NovaLabela(suslov); Emit('L' + suslov + ':'); IzrazDodjeljivanja; Emit(' CMP EAX,0'); NovaLabela(sdok); NovaLabela(skrajpetlje); Emit(' JNE L' + sdok); Emit(' JMP L' + skrajpetlje); IdiDo('{'); Emit('L' + sdok + ':'); Blok; Emit(' JMP L' + suslov); Emit('L' + skrajpetlje + ':'); end; procedure Blok; begin while znak <> '}' do case znak of '&': Petlja; '?': Uslov; '\': Asembler; else begin IzrazDodjeljivanja; IdiDo(';'); end; end; IdiDo('}'); end; procedure Prevedi; begin Emit('.386'); Emit('.MODEL FLAT,STDCALL'); Emit('OPTION CASEMAP:NONE'); Emit('EXTRN ExitProcess@4:NEAR'); Emit('.CODE'); Emit('ULAZ:'); Emit(' JMP GLAVNI'); pozicija := 0; Novi; IdiDo('{'); Emit('GLAVNI:'); Blok; Emit(' PUSH 0'); Emit(' CALL ExitProcess@4'); Emit('.DATA'); Emit('GLOBALV DD 26 DUP(0)'); Emit('END ULAZ') end; procedure Glavni; var linija: string; begin trenlabela := 0; Assign(ulaz, paramstr(1)); Assign(izlaz, paramstr(2)); brojaclinija := 0; linija := ''; Reset(ulaz); Rewrite(izlaz); Prevedi; Close(ulaz); Close(izlaz); WriteLn('Prevedeno bez greske'); end; begin Glavni end. 27 7. KLJUČNE RIJEČI, STRINGOVI, DINAMIČKI NIZOVI I FUNKCIJE Prethodna verzija kompajlera omogućava, u kombinaciji s asemblerskim umetnutim kodom, realizaciju raznih programa i za neke čitaoce je dovoljna, ali i dalje ima mnogo slabih tačaka. Tu je prije svega evidentan nedostatak potprograma, jednodimenzionalnih nizova i stringova. Osim toga, jezik je veoma kriptičan i potrebno mu je dodati ključne riječi, kako bi bio razumljiviji. 7.1. Ključne riječi Neka se dodaju prvo ključne riječi. Jezički pojam Blok sada može izgledati kao na slici Sl. 7.1.1. Blok: dok Petlja ako Uslov Izraz dodjeljivanja asembler ; } Asembler r Sl. 7.1.1. Blok Za prepoznavanje ključnih riječi postoje dva pristupa. Jedan je izrada konačnog automata koji se zove skaner ili leksički analizator. On se zasniva na dodjeli specijalnih simbola ključnim riječima. U primjeru sa slike Sl. 7.1.1 bi trebalo modifikovati proceduru Novi da ako prepozna slovo a da provjeri da li iza njega slijedi slovo k ili s pa ako slijedi k, provjeriti da li slijedi slovo o i ako su sva tri uslova ispunjena tada se vraća simbol za ako, u protivnom se vraća identifikator a, ak, ili čak neki duži identifikator (akcenat, akt itd.). U slučaju da je iza slova a slijedilo slovo s analogno se provjerava da li je riječ o ključnoj riječi asembler ili možda varijabli astronaut. Skanerski pristup je brži, i omogućava odvajanje prepoznavanja ključnih riječi (leksička analiza) od ostatka procesa prevođenja, te samim tim fleksibilniji kompajler. Pristup je konzistentan jer se jednom procedurom dohvataju i jednoslovni i višeslovni jezički simboli. Mana skanerskog pristupa je u relativno dugačkom kodu za ostvarenje jednostavnog zadatka, kao i činjenici da se prosti karakter tip koji prikazuje simbol koji slijedi mora zamijeniti cjelobrojnim ili specijalizovanim, jer 256 znakova nije dovoljno. Drugi pristup je pristup očekivanih uzoraka (matching) . Ovaj pristup primijenjen je u kompajleru za programski jezik Small C. U ulaznoj liniji se provjerava da li na trenutnom mjestu u ulaznoj slijedi željeni string u cjelini. To znači da će se provjera vršiti više puta, bila ona potrebna ili ne. Osim toga, provjera se mora realizovati posebnom procedurom umjesto prostog poređenja sa narednim simbolom, pa se malo gubi na konzistentnosti. Ali, pristup je dovoljno jednostavan da je izabran za programski jezik razvijan u ovom radu Kako taj jezik ima vrlo malo ključnih riječi, gubitak performansi je neznatan. Za prepoznavanje uzorka uvodi se funkcija Slijedi. Ova funkcija ima string argument, koji predstavlja očekivanu ključnu riječ, a vraća Boolean, tako da se može pozivati sa if Slijedi('ako') then ... Algoritam koji realizuje funkciju Slijedi se radi na sljedeći način: Ako je niz znakova na trenutnoj ulaznoj poziciji jednak stringu navedenom kao parametar, onda se vraća vrijednost tačno i postavi pokazivač pozicije iza tog niza. U protivnom se vrati vrijednost netačno. Koristeći ovu funkciju slijedi, lako je napisati novu verziju procedure blok i na taj način uvesti ključne riječi. 7.2. Komentari i neignorisanje simbola Strukturirani programski jezik je nezamisliv bez komentara. Programski jezici obično definišu komentare kao dio koda koji se ignoriše, pri čemu se komentar smatra dijelom koda između dva specijalna niza simbola ili od jednog simbola do kraja linije. U ovom jeziku, komentar je predstavljen apostrofom okrenutim na desnu stranu ` . Od tog znaka, do kraja linije tekst se ignoriše. Proceduru Novi je potrebno malo modifikovati da bi dio koda između ovog simbola i kraja linije bio ignorisan. Ponekad je potrebno dohvatiti i analizirati simbol čak i kada je on blanko, naopaki apostrof ili novi red. Naime, u prethodnoj verziji kompajlera bilo je sasvim normalno napisati 28 a:1343223; kao i a:134 3 22 3; što je vrlo neuobičajeno, a kada se budu uvele stringovne konstante i neprihvatljivo. Stoga se pored funkcije novi uvodi funkcija NoviSvaki koja radi slično kao Novi, ali ne provjerava da li je riječ o blanku ili komentaru. Ova funkcija ima parametar koji govori da li će se prijavljivati greška ukoliko se, dohvaćajući simbole, došlo do kraja reda ili ne (u tom slučaju kao kraj reda vraća blanko). Procedura UzmiKonstantu se sada modifikuje tako da novu cifru uzima ovom procedurom umjesto procedure Novi. 7.3. Modifikacija uslova i petlji Pošto je nepraktično pisati uslove tako da se uvijek navodi i sekcija koja se izvrši kad je uslov ispunjen i ona kad uslov nije ispunjen, uvodi se ključna riječ inace i jezički pojam Uslov redizajnira kao na slici Sl. 7.3.1 i skladno tome se mijenja odgovarajuća procedura Uslov. Time dio koda koji se izvršava kada uslov nije ispunjen postaje opcionalan. Uslov: ako Izraz dodjeljivan ja Blok { inace { Blok Sl. 7.3.1. Uslov Sintaksa petlji se ne mijenja, iako je simbol & zamijenjen ključnom riječju dok. Prepoznavanje ključne riječi dok se obavlja unutar procedure Blok. 7.4. Modifikacije aritmetičkih izraza i uvođenje stringova Dodjeljivanje simbolom : je takođe zbunjujuće, pa se Izraz dodjeljivanja mijenja da se umjesto znaka : , dodjeljivanje vrši koristeći operator := . Taj se operator može, nakon što je prepoznata dvotačka, provjeravati funkcijom slijedi(':='). Izraz dodjeljivanja je prikazan na slici Sl. 7.4.1 = > < Izraz Izraz # := Sl. 7.4.1. Izraz dodjeljivanja Izraz dodjeljivanja Stringovne konstante nije teško dodati, ukoliko se preuzme koncepcija stringova iz C-a. U C-u se stringovi prenose u potprograme i dodjeljuju odgovarajućim varijablama tako što se prenosi adresa početka stringovne konstante. Da bi se znalo gdje je kraj stringovne konstante, na kraju stringa se nalazi bajt sa vrijednošću 0. Stringovne konstante uokvirene su dvostrukim navodnicima. String konstanta: " karakter Sl. 7.4.2. " String konstanta 29 Procedura koja prevodi stringovnu konstantu koristi proceduru NoviSvaki uz zabranu prelaska u naredni red. Ona mora generisati kôd sa slike Sl. 7.4.3 .DATA Lnn db "String koji je koristen",0 .CODE MOV EAX,OFFSET Lnn Sl. 7.4.3. Generisani kôd za stringovne konstante Iz ovoga se vidi da se mora prvo prekinuti kodni segment i reći asembleru da se ova konstanta smjesti u segment sa podacima, kako bi se izbjeglo izvršavanje besmislenih instrukcija koje slučajno imaju isti operacioni kôd kao bajtovi predstavljeni ASCII kodovima. Nakon ovoga ponovo se navodi kodni segment i instrukcija kojom se u EAX registar donosi adresa toga stringa. Ova adresa će se kasnije moći prosljeđivati Windows API funkcijama kao argument. U specijalnom slučaju, prazan string se prevodi u Lnn DB 0. Ideja iz jezika C o pristupu nizovima cijelih brojeva koristeći pokazivačke varijable, omogućava vrlo jednostavno dodavanje jednodimenzionalnih nizova. Uz pretpostavku da varijabla sadrži adresu nekog prostora u memoriji (koji se može u ovom trenutku dobiti dodjeljivanjem stringovne konstante varijabli ili pozivom Windows API funkcije GlobalAlloc u asemblerskom modulu) i ako se taj prostor iskoristi za smještanje elemenata niza, tada je dovoljno u sintaksi varijable dodati opcionalni indeks unutar uglastih zagrada, kao što se vidi na sintaksnom dijagramu sa slike Sl. 7.4.4: Varijabla: Slovo [ Sl. 7.4.4. Izraz dodjeljivanja ] Varijabla Adresa elementa niza tada se može dobiti po formuli Adresa=vrijednost varijable predstavljene slovom + 4 * vrijednost izraza dodjeljivanja Stoga se element niza dobija koristeći kôd sa slike Sl. 7.4.5. PUSH EAX Pozovi IzrazDodjeljivanja; POP EBX SAL EAX,2 ADD EBX,EAX MOV EAX,[EBX] Sl. 7.4.5. Generisani kôd za dobijanje elementa niza Instrukcija SAL pomjera registar EAX za dva bita ulijevo, što efektivno predstavlja množenje sa 4. U skladu sa dosadašnjim standardom, adresa elementa niza se dobija u registru EBX, a njegova vrijednost u registru EAX. 7.5. Funkcije i procedure Pošto je jezik koji se razvija sličan C-u, gdje se kreće od izraza, a ne iskaza, dodavanje funkcija automatski rješava i problem dodavanja procedura ili običnih potprograma. Procedure su prosto funkcije čija se vrijednost zanemaruje, a obični potprogrami pored toga nemaju argumenata. Poziv funkcije se vrši unutar izraza i sintaksno je prikazan na slici Sl. 7.5.1: Veliko slovo malo slovo ( Izraz dodjeljivanja , ) Sl. 7.5.1. Poziv funkcije Kao u implementaciji većine modernih programskih jezika, parametri se prije poziva funkcije smještaju na stek. 30 U definiciji funkcije se za sada ne navode parametri, iako se oni mogu navesti pri pozivu. Stoga, ova verzija kompajlera nema provjeru broja i tipa parametara funkcija i smatraće se da sve funkcije imaju po 26 parametara. Imajući ovo u vidu, generisani kôd za poziv funkcije izgleda kao na slici Sl. 7.5.2 : Za svaki parametar: Pozovi Izrazdodjeljivanja PUSH EAX MOV ECX,ukupna veličina svih parametara CALL P_funkcija Sl. 7.5.2. Poziv funkcije, generisani kôd Podatak o tome koliko su memorije na steku zauzeli parametri, a koji se smješta u ECX, koristiće se u samoj funkciji. Definicija funkcije data je na sintaksnom dijagramu na slici Sl. 7.5.3. Funkcija: funkcija Veliko slovo malo slovo ; { Blok Sl. 7.5.3. Funkcija Ime funkcije obavezno počinje velikim slovom iza koga slijedi više malih slova. Ovo je učinjeno da bi se razlikovale funkcije po imenu od varijabli, koje su predstavljene malim slovima. Ako iza imena funkcije slijedi znak { , tada slijedi tijelo funkcije. Ukoliko iza imena funkcije slijedi znak ; tada je samo u pitanju deklarisanje funkcije, čije se tijelo nalazi u drugom modulu (drugoj .JEZ ili .OBJ datoteci). Definisanje funkcije koja je implementirana u drugom modulu se realizuje prostom upotrebom pseudoinstrukcije EXTRN: EXTRN P_imefunkcije:NEAR Funkcije koje imaju tijelo se prevode znatno složenije. Na steku se rezerviše prostor za svih 26 parametara, koji iznosi 104 bajta (26*4). Parametri se označavaju sa @a, @b, ... , @z, pri čemu @a predstavlja prvi parametar naveden u pozivu, a @z predstavlja 26-ti parametar. Naravno, većina parametara neće biti iskorištena , pa se neiskorišteni parametri mogu upotrijebiti kao lokalne varijable. Registar ECX, kako je već rečeno, sadrži veličinu dijela steka potrošenog za parametre, a za lokalne varijable ostaje 104-ECX bajtova. Lokalnim varijablama i parametrima se pristupa relativno u odnosu na EBP registar, pa EBP registar treba pokazivati na vrh steka u trenutku poziva. Sam stek pointer se mora umanjiti kako bi se iz funkcija pozivale druge funkcije, a zatim na stek stavila povratna adresa. Sve navedeno se postiže kodom slike Sl. 7.5.4. Primjećuje se da nema posebnog koda za vraćanje vrijednosti funkcije. Ona se jednostavno već nalazi u EAX registru kao rezultat posljednjeg aritmetičkog izraza unutar bloka. Instrukcija RET 104 pored povratka iz potprograma ujedno i vrati poziciju stek pointera na vrijednost prije stavljanja prvog argumenta. Ovaj kôd će se pojednostaviti nakon uvođenja provjera argumenata, u narednom poglavlju. P_ImeFunkcije: POP EDX ADD ESP,ECX SUB ESP,104 PUSH EDX PUSH EBP MOV EBP,ESP Pozovi Blok POP EBP RET 104 Sl. 7.5.4. Generisani kôd za tijelo funkcije Realizacija funkcija, dinamičkih nizova i stringova dovodi do nove sintaksne definicije pojma faktor i skladno s tim odgovarajuće procedure: 31 Faktor: ~ & Faktor * ! Numerička konstanta ( Izraz dodjeljivanja ) @ Varijabla " String konstanta Poziv funkcije Sl. 7.5.5. Faktor Numeričku konstantu, varijablu ili poziv funkcije moguće je razlikovati po tome da li počinju cifrom, malim ili velikim slovom. Lokalne varijable se implementiraju sljedećim kodom LEA EBX,[EBP+n] MOV EAX,[EBX] gdje se n računa izrazom n=108-(ord(znak)- ord('a'))*4 . U ovom izrazu, znak predstavlja ime varijable bez simbola @. 7.6. Testni primjer Na slici Sl. 7.6.1 dat je program u četvrtoj verziji jezika koji prikazuje na ekranu za brojeve od 1 do 10: broj, ime broja, kvadrat, kub, faktorijel (rekurzivno) te proste faktore tog broja. Program se zove tabbroj.jez i kompajlira koristeći komp32v4 tabbroj.jez tabbroj.asm ml /c /coff /Fl tabbroj.asm | more link /defaultlib:user32.lib kernel32.lib /subsystem:console tabbroj.obj 32 funkcija Prikazistring { asembler extrn GetStdHandle@4:near extrn WriteConsoleA@20:near MOV EAX,-11 ; -11 je parametar za STDOUT PUSH EAX CALL GetStdHandle@4 ; Uzmi hendl za STDOUT MOV ECX,0 ; Petlja koja racuna duzinu stringa MOV EBX,[EBP+108] DUZ: CMP BYTE PTR [EBX],0 JE IZR INC ECX INC EBX JMP DUZ IZR: PUSH DWORD PTR 0 ; Rezervisano LEA EBX,[EBP+104] PUSH EBX ; Pointer na broj karaktera koji su prikazani PUSH ECX ; Broj karaktera koji se pisu MOV EBX,[EBP+108] PUSH EBX ; Pointer na string PUSH EAX ; Handle CALL WriteConsoleA@20 ; Ispisi string \ } funkcija Zamijeniznak { asembler MOV EBX,[EBP+108] ; Adresa stringa ADD EBX,[EBP+104] ; Redni broj karaktera MOV EAX,[EBP+100] ; ASCII kod karaktera koji mijenjamo MOV [EBX],AL ; Upisuje karakter \ } funkcija Novired { @a:=" "; Zamijeniznak(@a,0,13); Zamijeniznak(@a,1,10); Prikazistring(@a); } funkcija Prikazibroj { @q:=" "; ` Alociramo bafer @c:=@a; ` Negativne brojeve oznaci indikatorom ako (@c<0) { @i:=1; @c:=-@c; } inace { @i:=0; } `maksimalno 9 cifara @p:=9; ako (@c=0) { Zamijeniznak(@q,@p,48);@p:=@p-1;} dok (@c>0) { @o:=(@c % 10); `ostatke dijeljenja u bafer Zamijeniznak(@q,@p,@o+48); @c:=@c/10; ` stalno dijeli s 10 @p:=@p-1; } ako (@i=1) { Zamijeniznak(@q,@p,45); @p:=@p-1; } @q:=@q+@p+1; ` Pomjeri pokazivac pocetka stringa Prikazistring(@q); Sl. 7.6.1. } funkcija Fact { ako (@a=0) { 1; } inace { @a*Fact(@a-1); } } funkcija Tabela { Prikazistring("Tabela"); Novired(); n:=1; dok (n<11) { Prikazibroj (n); Prikazistring(" "); Prikazistring(a[n]); Prikazistring(" "); Prikazibroj (n*n); Prikazistring(" "); Prikazibroj (n*n*n); Prikazistring(" "); Prikazibroj (Fact(n)); Prikazistring(" Djeljiv sa "); m:=1; dok !(m>n) { ako (n%m=0) { Prikazibroj(m); Prikazistring(" "); } m:=m+1; } n:=n+1; Novired(); } } funkcija Postavinazive { a:=" ` Prostor za niz a[1]:="Jedan"; a[2]:="Dva"; a[3]:="Tri"; a[4]:="Cetiri"; a[5]:="Pet"; a[6]:="Sest"; a[7]:="Sedam"; a[8]:="Osam"; a[9]:="Devet"; a[10]:="Deset"; } "; { Postavinazive(); Tabela(); } Tablica brojeva, četvrta verzija kompajlera Funkcija Prikazistring realizovana je u asembleru, jer poziva Windows API funkcije GetStdHandle i WriteConsole. Ove funkcije predstavljaju način ispisa stringa na ekranu koristeći Windowsove sistemske funkcije za rad s konzolnim aplikacijama. Funkcija GetStdHandle je sistemska funkcija koja vraća broj pridružen ulaznom uređaju, izlaznom uređaju ili uređaju greške. U Windows API funkcijama definisana je ovako HANDLE GetStdHandle( DWORD nStdHandle // input, output, or error device ); pa je potrebno na stek prije njenog poziva staviti konstantu -11, koja predstavlja STDOUT. Funkcija WriteConsole je definisana ovako 33 BOOL WriteConsole( HANDLE hConsoleOutput, // handle to a console screen buffer CONST VOID *lpBuffer, // pointer to buffer to write from DWORD nNumberOfCharsToWrite, // number of characters to write LPDWORD lpNumberOfCharsWritten,//pointer to number of chars written LPVOID lpReserved // reserved ); Windows-ova konvencija je da se parametri za API funkcije smještaju na stek obrnutim redom u odnosu na onaj koji je definisan u zaglavlju funkcije. Asemblerski potprogram priprema sve parametre i smješta ih potrebnim redoslijedom. Pošto još nema naredbi za pristup pojedinačnim karakterima, u asembleru je napisana i funkcija Zamijeniznak, koja se poziva sa tri parametra, prvi je adresa stringa, drugi redni broj karaktera koji mijenjamo i treći ASCII kôd koji upisujemo. Ostale funkcije su pisane bez pomoći asemblera. Funkcija Novired ispisuje string koji sadrži kodove CR i LF, čime se prelazi u novi red. Funkcija Prikazibroj pretvara cijeli broj u njegovu ASCII reprezentaciju, koristeći uzastopno dijeljenje sa 10 uz prikazivanje ostataka, a zatim se ta ASCII reprezentacija prikazuje na ekranu, koristeći funkciju PrikaziString. Posebno je interesantna funkcija Fact koja rekurzivno računa faktorijel, koristeći definiciju faktorijela. Dakle, jezik već u ovoj fazi podržava i tako složene stvari kao što je rekurzija. Glavna funkcija Tabela je dobro strukturirana i shvatljiva svakome ko poznaje bar jedan viši programski jezik. Jedino treba reći da se u unutrašnjoj petlji (sa m kao brojačem) vrši poređenje ostatka (pri dijeljenju n sa m ) sa brojem 0 i ako je ostatak jednak 0, tada se prikazuje broj kao djelilac. U funkciji Postavinazive se globalnoj varijabli a pridruži adresa stringa koji ima dosta blankova. Ovaj string služi samo kao rezervisani prostor za 10 pokazivača na nove stringove koji sadrže imena brojeva. Izvršenje programa Tabbroj daje kao rezultat 1 2 3 4 5 6 7 8 9 10 Jedan 1 1 1 Djeljiv sa 1 Dva 4 8 2 Djeljiv sa 1 2 Tri 9 27 6 Djeljiv sa 1 3 Cetiri 16 64 24 Djeljiv sa 1 2 4 Pet 25 125 120 Djeljiv sa 1 5 Sest 36 216 720 Djeljiv sa 1 2 3 6 Sedam 49 343 5040 Djeljiv sa 1 7 Osam 64 512 40320 Djeljiv sa 1 2 4 8 Devet 81 729 362880 Djeljiv sa 1 3 9 Deset 100 1000 3628800 Djeljiv sa 1 2 5 10 što je i trebalo dobiti. EXE verzija programa je velika svega 4 kilobajta, jer nema opterećujuće biblioteke, kao u svim drugim kompajlerima. Ova verzija jezika je sasvim upotrebljiva za mnoge primjene iako programi pisani u njoj zahtijevaju dosta hakerskih trikova. Tu se prije svega misli na povremenu upotrebu asemblerskog koda. Ipak, asemblerske i druge funkcije se već u ovoj verziji kompajlera mogu izdvojiti i posebno kompajlirati i linkovati, te na taj način formirati jezgro programske biblioteke, što u mnogome olakšava programiranje. 7.7. Rezime poglavlja Četvrta verzija kompajlera uvodi ključne riječi. Ključne riječi se mogu prepoznavati skanerom, koji provjerava slovo po slovo kao konačni automat ili očekivanim uzorkom, poređenjem sa cijelim očekivanim stringom. Odabran je princip očekivanih uzoraka, i uzorci se provjeravaju procedurom Slijedi. Dodane su ključne riječi ako, dok, inace, funkcija i asembler. Dodjeljivanje vrijednosti varijabli se vrši simbolom :=. Stringovne konstante se prevode u instrukciju koja registru EAX dodjeljuje adresu stringa. Uvedeni su jednodimenzionalni nizovi, vezani uz pojam pointera. Moguće je pozivati funkcije sa varijabilnim brojem parametara. Parametri se mogu koristiti kao lokalne varijable. Funkcije mogu biti i u eksternim modulima. Testni primjer uključuje cjelobrojnu aritmetiku i ispis na ekran. Ovo je najznačajnija verzija kompajlera. Dovoljno je kratka da se može prikazati za jedan nastavni blok-čas, ali opet dovoljno velika da uključuje većinu koncepata iterativnih programskih jezika. 34 program Kompajler; const GRIZRAZ = 'Izraz'; DUGAKONST = 'Konstanta prevazilazi liniju'; OCEKIVANO = 'Ocekivano '; IMEFUN = 'Ocekivano ime funkcije'; DEFFUN = 'Definicija funkcije'; OCEKDOD = 'Ocekivano dodjeljivanje'; var ulaz, izlaz: text; pozicija, trenlabela, brojaclinija: integer; znak: char; linija: string; procedure NovaLabela(var ImeLabele: string); begin trenlabela := trenlabela + 1; Str(trenlabela, ImeLabele); end; procedure Greska(poruka: string); begin WriteLn(poruka); WriteLn(brojaclinija, ':', linija); Close(ulaz); Close(izlaz); Halt; end; procedure Emit(st: string); begin WriteLn(izlaz, st); end; procedure Novi; begin repeat pozicija := pozicija + 1; if pozicija > Length(linija) then begin brojaclinija := brojaclinija + 1; if not (Eof(ulaz)) then ReadLn(ulaz, linija); Emit(';' + linija); pozicija := 1; end; if Length(linija) > 0 then znak := linija[pozicija] else znak := ' '; if (znak = '`') then pozicija := Length(linija); until ((znak > ' ') and (znak <> '`')) or Eof(ulaz) end; procedure NoviSvaki(greskakrln: Boolean); begin pozicija := pozicija + 1; if pozicija > Length(linija) then begin if greskakrln then Greska(DUGAKONST) else znak := ' '; end else znak := linija[pozicija]; end; procedure IdiDo(z: char); begin if (znak <> z) then Greska(OCEKIVANO + z); Novi; end; function UzmiKonstantu: integer; var rezultat: integer; begin rezultat := 0; while (znak >= '0') and (znak <= '9') do begin rezultat := 10 * rezultat + ord(znak) - ord('0'); NoviSvaki(false); end; if (znak = ' ') or (znak = '`') then Novi; UzmiKonstantu := rezultat; end; function Slijedi(ocekivano: string): Boolean; begin if copy(linija, pozicija, Length(ocekivano)) = ocekivano then begin Slijedi := true; pozicija := pozicija + Length(ocekivano) - 1; end else Slijedi := false; end; procedure IzrazDodjeljivanja; forward; procedure Blok; forward; * 4; Str(rezultat, st); Emit(' LEA EBX,GLOBALV[' + st +']'); end else begin Novi; if (znak < 'a') or (znak > 'z') then Greska('Lokalna'); rezultat := 108 - (ord(znak) ord('a')) * 4; Str(rezultat, st); Emit(' LEA EBX,[EBP+' + st + ']'); end; Emit(' MOV EAX,[EBX]'); Novi; if znak = '[' then PokazivacINiz; end; procedure Faktor; var procedure PokazivacINiz; rezultat: integer; begin st: string; Novi; begin Emit(' PUSH EAX'); case znak of IzrazDodjeljivanja; '-': begin Emit(' POP EBX'); Novi; Emit(' SAL EAX,2'); Faktor; Emit(' ADD EBX,EAX'); Emit(' NEG EAX'); Emit(' MOV EAX,[EBX]'); end; IdiDo(']'); '~': begin end; Novi; Faktor; procedure StringKonstanta; Emit(' NOT EAX'); var end; st, strtekst: string; '&': begin begin Novi; NovaLabela(strtekst); Faktor; Emit('.DATA'); Emit(' MOV EAX,EBX'); st := 'L' + strtekst + ' DB '''; end; repeat '*': begin NoviSvaki(true); Novi; if znak <> '"' then Faktor; st := st + znak; Emit(' MOV EBX,EAX'); until znak = '"'; Emit(' MOV EAX,[EBX]'); IdiDo('"'); end; st := st + ''',0'; '!': begin if copy(st, length(st) - 3, 2) = Novi; '''''' then Faktor; st := 'L' + strtekst + ' DB 0'; Emit(' CMP EAX,0'); Emit(st); Emit(' SETE AL'); Emit('.CODE'); Emit(' AND EAX,0FFh'); Emit(' MOV EAX,OFFSET L' + strtekst); end; '"': end; StringKonstanta; procedure PozivFunkcije; '0'..'9': begin var rezultat := UzmiKonstantu; lokalnih: integer; Str(rezultat, st); ImeFunkcije, st: string; Emit(' MOV EAX,' + st); begin end; ImeFunkcije := ''; '(': begin while ((znak >= 'a') and (znak <= Novi; 'z')) or IzrazDodjeljivanja; ((znak >= 'A') and (znak <= 'Z')) do IdiDo(')'); begin end; '@': ImeFunkcije := ImeFunkcije + znak; Varijabla(false); NoviSvaki(false); 'A'..'Z': end; PozivFunkcije; if (znak = ' ') or (znak = '`') then 'a'..'z': Novi; Varijabla(true) lokalnih := 0; IdiDo('('); else while (znak <> ')') do begin Greska(GRIZRAZ); IzrazDodjeljivanja; end; Emit(' PUSH EAX'); end; lokalnih := lokalnih + 4; if znak <> ')' then procedure Clan; IdiDo(','); var end; z: char; IdiDo(')'); begin Str(lokalnih, st); Faktor; Emit(' MOV ECX,' + st); while (znak in ['*', '/', '%']) do Emit(' CALL P_' + ImeFunkcije); begin end; z := znak; Emit(' PUSH EAX'); procedure Varijabla(glob: Boolean); Novi; Faktor; var case z of rezultat: integer; '*': begin st: string; begin Emit(' POP EBX'); if glob then begin Emit(' IMUL EBX'); end; rezultat := (ord(znak) - ord('a')) 35 '/', '%': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); Emit(' CDQ'); Emit(' IDIV EBX'); if z = '%' then Emit(' MOV EAX,EDX'); end; end; end; end; procedure Izraz; var z: char; begin Clan; while (znak in ['+', '-', '&', '|', '^']) do begin Emit(' PUSH EAX'); z := znak; Novi; Clan; case z of '+': begin Emit(' POP EBX'); Emit(' ADD EAX,EBX'); end; '-': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); Emit(' SUB EAX,EBX'); end; '&': begin Emit(' POP EBX'); Emit(' AND EAX,EBX'); end; '|': begin Emit(' POP EBX'); Emit(' OR EAX,EBX'); end; '^': begin Emit(' POP EBX'); Emit(' XOR EAX,EBX'); end; end; end; end; procedure IzrazDodjeljivanja; var z: char; begin Izraz; case znak of ':': begin if not (Slijedi(':=')) then Greska(OCEKDOD); Emit(' PUSH EBX'); Novi; IzrazDodjeljivanja; Emit(' POP EBX'); Emit(' MOV [EBX],EAX'); end; {:} '=', '>', '<', '#': begin Emit(' PUSH EAX'); z := znak; Novi; Izraz; Emit(' POP EBX'); Emit(' CMP EBX,EAX'); case z of '=': Emit(' SETE AL'); '>': Emit(' SETG AL'); '<': Emit(' SETL AL'); '#': Emit(' SETNE AL'); end; Emit(' AND EAX,0FFh'); end; end; end; procedure Uslov; var sonda, sinace, skrajuslova: string; begin Novi; IzrazDodjeljivanja; Emit(' CMP EAX,0'); NovaLabela(sonda); NovaLabela(sinace); NovaLabela(skrajuslova); Emit(' JNE L' + sonda); Emit(' JMP L' + sinace); IdiDo('{'); Emit('L' + sonda + ':'); Blok; Emit(' JMP L' + skrajuslova); Emit('L' + sinace + ':'); if Slijedi('inace') then begin Novi; IdiDo('{'); Blok; end; Emit('L' + skrajuslova + ':'); end; procedure Asembler; begin repeat ReadLn(ulaz, linija); if linija <> '\' then Emit(linija); if eof(ulaz) then linija := '\'; until linija[1] = '\'; pozicija := 1; znak := linija[pozicija]; IdiDo('\'); end; procedure Petlja; var sdok, skrajpetlje, suslov: string; begin Novi; NovaLabela(suslov); Emit('L' + suslov + ':'); IzrazDodjeljivanja; Emit(' CMP EAX,0'); NovaLabela(sdok); NovaLabela(skrajpetlje); Emit(' JNE L' + sdok); Emit(' JMP L' + skrajpetlje); IdiDo('{'); Emit('L' + sdok + ':'); Blok; Emit(' JMP L' + suslov); Emit('L' + skrajpetlje + ':'); end; procedure Blok; begin while znak <> '}' do begin if Slijedi('dok') then Petlja else if Slijedi('ako') then Uslov else if Slijedi('asembler') then Asembler else begin IzrazDodjeljivanja; IdiDo(';'); end; end; IdiDo('}'); end; procedure DefFunkcija; var ImeFunkcije: string; begin if (znak < 'A') or (znak > 'Z') then Greska(IMEFUN); ImeFunkcije := znak; Novi; while (znak >= 'a') and (znak <= 'z') do begin ImeFunkcije := ImeFunkcije + znak; Novi; end; case znak of '{': begin Emit('P_' + ImeFunkcije + ':'); Emit(' POP EDX'); Emit(' ADD ESP,ECX'); Emit(' SUB ESP,104'); Emit(' PUSH EDX'); Emit(' PUSH EBP'); Emit(' MOV EBP,ESP'); IdiDo('{'); Blok; Emit(' POP EBP'); Emit(' RET 104'); Emit('PUBLIC P_' + ImeFunkcije); end; ';': begin Emit('extrn P_' + ImeFunkcije + ':near'); IdiDo(';'); end else Greska(DEFFUN); end; end; procedure Prevedi; begin Emit('.386'); Emit('.MODEL FLAT,STDCALL'); Emit('OPTION CASEMAP:NONE'); Emit('EXTRN ExitProcess@4:NEAR'); Emit('.CODE'); Emit('ULAZ:'); Emit(' JMP GLAVNI'); pozicija := 0; Novi; while (Slijedi('funkcija')) do begin Novi; DefFunkcija; end; IdiDo('{'); if znak <> '}' then begin Emit('GLAVNI:'); Blok; Emit(' PUSH 0'); Emit(' CALL ExitProcess@4'); Emit('.DATA'); Emit('GLOBALV DD 26 DUP(0)'); Emit('END ULAZ') end else begin Emit('GLAVNI:'); Emit('END'); end; end; procedure Glavni; var linija: string; begin trenlabela := 0; Assign(ulaz, paramstr(1)); Assign(izlaz, paramstr(2)); brojaclinija := 0; linija := ''; Reset(ulaz); Rewrite(izlaz); Prevedi; Close(ulaz); Close(izlaz); WriteLn('Prevedeno bez greske'); end; begin Glavni end. 36 8. DEKLARACIJE VARIJABLI, STANDARDNE FUNKCIJE Iako već prihvatljiva da u nekim kraćim kursevima kompajlera bude i finalna, prethodna verzija kompajlera ima četiri ozbiljna nedostatka: • Jednoslovna imena varijabli ograničavaju jezik na 26 lokalnih/parametarskih i toliko globalnih varijabli. Iako je to često dovoljno, postoje situacije kada nije. Sem toga, ova imena nisu dovoljno deskriptivna. • Jedini tip je 32 bitni cijeli broj koji se slučajno poklapa sa pointerom. • Programski jezik nema nikakve semantičke analize. Sasvim je legalno napisati izraz tipa 5:=2+a; što će upisati vrijednost zbira konstante 2 i varijable a, na neku slučajnu lokaciju gdje je u tom trenutku pokazivao EBX registar. Funkcija može biti deklarisana više puta, a grešku će primijetiti tek asembler. • Poziv potprograma nije standardan, pa se sistemske funkcije moraju pozivati iz asemblerskog modula. 8.1. Tabela identifikatora Uvođenje višeslovnih imena varijabli zahtijeva napuštanje statičkog načina alokacije varijabli i pravljenje tabele identifikatora. Tabela identifikatora TabIdent je niz slogova TIdent=record ime:string[20]; duzina:integer; adresa:integer; nivo:integer; vrsta:Tvrsta; tip:Ttip; pod1:integer; pod2:integer; pod3:integer; end; koji čuvaju ime identifikatora, dužinu, relativnu adresu identifikatora u skupu svih varijabli unutar funkcije ili globalnih varijabli, nivo koji predstavlja identifikator funkcije kojoj varijabla pripada (ili 0 za globalne), vrstu identifikatora (funkcija, lokalna varijabla, globalna varijabla, parametar), tip identifikatora (karakter, cijeli broj, pointer na karakter, pointer na cijeli broj), kao i tri dodatna podatka za šire objašnjenje identifikatora. Ova promjena u koncepciji zahtijeva dodavanje novih procedura, kao i da neke procedure u kompajleru budu proširene, a neke čak i nanovo napisane, čime kompajler postaje gotovo duplo duži u odnosu na prethodnu verziju. Procedura NoviIdent dodaje identifikator u tabelu identifikatora. Dodavanje se vrši trivijalno, uvećanjem brojača identifikatora ukupnoident za 1, a zatim upisom svih devet parametara ove procedure u odgovarajuća polja konkretnog sloga tabele identifikatora. U svrhu traženja željenog identifikatora u ovoj tabeli uvodi se funkcija NadjiIdent koja ima za parametre ime identifikatora, nivo koji predstavlja identifikator funkcije kojoj varijabla pripada (ili 0 za globalne), vrstu uslova i dodatni podatak. Ova funkcija treba da vrati poziciju navedenog identifikatora u tabeli identifikatora, ili vrijednost 0 ako identifikator nije nađen. Pretraživanje se vrši sekvencijalno jer identifikatori nisu sortirani. No, ono se vrši s kraja prema početku, kako bi lokalne varijable bile nađene prije istoimenih globalnih. Značenje parametra “vrsta uslova” dato je u tabeli na slici Sl. 8.1.1. Broj Značenje 1 Traži lokalnu varijablu, globalnu varijablu, parametar funkcije ili funkciju koja ima ime kao navedena a nalazi se u funkciji koja se trenutno prevodi ili glavnom programu 2 Traži lokalnu varijablu, globalnu varijablu, parametar funkcije ili funkciju koja ima kao navedena a nalazi se u ili funkciji koja se trenutno prevodi ili u glavnom programu ako se on u tom trenu prevodi 3 Rezervisano 4 Traži parametar funkcije koja se prevodi u ovom trenutku po njegovom rednom broju Sl. 8.1.1. Parametar Vrsta uslova Procedura UzmiIdent vraća string vrijednost koja predstavlja niz slova. Algoritam koji implementira tu proceduru izgleda ovako: 37 Postavi rezultantni string na prazan string Sve dok slijedi slovo dodaj ga na rezultantni string, i uzmi sljedeći znak Ako je sljedeći znak blanko ili komentar dohvati ga kako bi ga rutine ignorisale Procedura DeklIdent objedinjuje UzmiIdent i NadjiIdent, tj. dohvata identifikator i traži da li on već postoji u tabeli, te ako postoji prijavljuje grešku. Sada je potrebno proširiti sintaksu jezika. Prvo treba definisati pojam identifikatora, koji je prikazan na slici Sl. 8.1.2. Identifikator: Cifra _ Slovo (veliko ili malo) Slovo (veliko ili malo) Sl. 8.1.2. Identifikator Realizacija jezičkog pojma Identifikator urađena je u proceduri UzmiIdent. 8.2. Tipovi Postoje četiri tipa varijabli, cijeli, karakter, te pointeri na njih. Oni se zajedno definišu u pojmu ImeTipa, (Sl. 8.2.1) koji je implementiran u funkcijama SlijediDekTipa i TipDek. Funkcija function TipDek(imetipa: string; var tip: TTip; stip, ptip: TTip): Boolean; provjerava da li slijedi navedeno ime tipa ili pointer na njega. Ako ne slijedi ni jedno ni drugo, funkcija vraća false. Ime tipa se navodi kao niz karaktera, a u varijablu tip funkcija vraća oznaku tipa ili pointera na njega. Ove oznake se navode kao parametri stip i ptip i mogu biti karakter, cijeli, pkarakter i pcijeli. Rogobatna sintaksa funkcije TipDek se prevazilazi funkcijom function SlijediDekTipa(var tip: TTip):Boolean koja vraća true ako slijedi ime bilo kojeg tipa, a kao bočni efekt u varijabli tip se dobije oznaka tog tipa. ImeTipa cijeli * karakter * Sl. 8.2.1. Ime tipa Veličina prostora koji zauzima pojedinačna varijabla nekog tipa dobija se funkcijom DuzinaTipa. Za tip karakter, ta vrijednost iznosi 1 bajt, dok za tipove cijeli, pkarakter i pcijeli veličina prostora je 4 bajta. 8.3. Deklarisanje varijabli i nova struktura programa Nakon uvođenja identifikatora i imena tipa, može se pristupiti deklarisanju varijabli. Deklaracija varijabli izgleda kao na slici Sl. 8.3.1. Deklaracija varijabli: Identifikator ImeTipa , Sl. 8.3.1. Deklaracija varijabli ; 38 Na primjer: cijeli Duzina, Sirina; karakter * ime; U suštini, deklaracija svake nove varijable jednostavno povećava ukupnu veličinu prostora za same varijable, bilo u prostoru za globalne varijable, bilo na steku za lokalne varijable. Tada se u slogu koji predstavlja dati identifikator upiše relativna adresa gdje se nalazi varijabla kojoj se pristupa. Dakle, u generisanom asemblerskom kodu se ne čuva ime varijable. Pojam programa sada uključuje deklaraciju varijabli, definiciju funkcija i glavni blok. Varijable i funkcije se mogu u programu neograničeno puta ponavljati. Ako se u glavnom bloku nalazi samo zatvorena zagrada, tada je riječ o biblioteci funkcija. Nova definicija pojma Program nalazi se na slici Sl. 8.3.2. Program: Deklaracija funkcije } { Blok Deklaracija varijabli Sl. 8.3.2. Deklaracija funkcije će biti prikazana kasnije. 8.4. Program Izrazi i semantika Uvođenje jedinstvenog sistema identifikatora zahtijeva izmjenu jezičkog pojma Faktor u kome se zbog toga ukida sintaksa lokalnih varijabli sa znakom @, te prepoznavanje funkcije tako što joj ime počinje velikim slovom. Sada je pogodan trenutak i za uvođenje znakovne konstante koja se, kao u C-u, navodi između jednostrukih navodnika. Jezički pojam Faktor sada izgleda kao na slici Sl. 8.4.1 Faktor: ~ & Faktor * ! Numerička konstanta ( Izraz dodjeljivanja ) Varijabla String " Poziv funkcije ‘ ‘ Slovo Sl. 8.4.1. Faktor 39 Realizacija slovne konstante je trivijalna i svodi se na prostu MOV AL,konstanta instrukciju. No, iako se sintaksno ne mijenjaju ostali jezički pojmovi koji sačinjavaju izraz, procedure koje ga realizuju potrebno je radikalno promijeniti. Razlog tome je uvođenje semantike i različitih tipova. Ozbiljan semantički problem da je u prethodnim verzijama kompajlera moguće napisati 5+3:=a-8; rješava se uvođenjem varijabilnog parametra dod u sve procedure koje realizuju aritmetičke izraze. Prilikom obrade dijela izraza, ovom parametru daje se vrijednost true, ako se tom dijelu izraza može dodijeliti vrijednost. Tipično, to su varijable, elementi nizova i lokacije na koje pokazuju pointeri. Ovaj parametar će se provjeravati u proceduri IzrazDodjeljivanja nakon prvog poziva procedure Izraz i prijaviti greška ukoliko on nema tačnu vrijednost. Procedurama koje predstavljaju dijelove aritmetičkih izraza dodaje se još jedan varijabilni parametar. Preko tog parametra se vraća tip dijela aritmetičkog izraza, tj. da li je karakter, cijeli broj, pointer itd. Jezik koji se ovdje razvija spada u jezike slabe tipiziranosti i omogućava automatske konverzije između podataka različitih tipova prilikom dodjeljivanja. To znači da je legalno napisati a:=’#’+1; gdje je a cjelobrojna varijabla. Iako su sabirci u gornjem zbiru različitog tipa (karakter i cijeli broj), ipak rezultat predstavlja cijeli broj 36, jer je ASCII kôd znaka # jednak 35. Cijeli brojevi i pointeri zahtijevaju četiri bajta za njihovo predstavljanje, dok se karakteri mogu smjestiti u jedan bajt. Baš kao što se za smještanje cijelih brojeva u toku izraza koriste registri EAX, EBX i stek, za karaktere se koriste AL, BL i stek, pri čemu se zbog karakteristika steka na stek smještaju čitavi EAX/EBX registri. U primjeru “a:=’#’+1” kompajler generiše kôd za smještanje konstante 35 u registar AL, ali nakon toga nalazi cjelobrojnu konstantu 1, zaključuje da je ipak riječ o izrazu sa 32 bitnim rezultatom pa registar AL konvertuje u EAX i nastavlja da generiše kôd kao da je riječ o sabiranju dva 32 bitna broja. Konverzija registra AL u EAX se vrši postavljanjem viših 24 bita na nula instrukcijom AND. Većina udžbenika o kompajlerima izbjegava miješanje različitih tipova podataka unutar jednog aritmetičkog izraza. Razlog je u tome što je broj potrebnih konverzija jednak kvadratu broja tipova koji se u tom izrazu mogu pojaviti. Razrješenju tog problema pomažu tablice, navedene u sljedećoj tački. 8.5. Tablice generisanog koda za različite operande Pošto ima dosta kombinacija lijevog i desnog operanda, za sve binarne i unarne operatore potrebno je napraviti odgovarajuće tablice koje određuju kakav će se kôd generisati zavisno od operatora i tipa operanada. Pri prikazu generisanog koda, dio koji se jednom ili više puta ponavlja (ukoliko se dati operator uzastopno ponavlja više puta) stavljen je u vitičaste zagrade. Operacija Desni Karakter cijeli karakter * cijeli * karakter Clan { PUSH EAX Clan POP EBX ADD AL,BL } Nije dopušteno Nije dopušteno cijeli Clan { PUSH EAX Clan POP EBX AND EAX,0FFh ADD EAX,EBX } Nije dopušteno Clan { PUSH EAX Clan POP EBX AND EBX,0FFh ADD EAX,EBX } Clan { PUSH EAX Clan POP EBX ADD EAX,EBX } Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Lijevi + Samo za slučaj sabiranja dva karaktera rezultat je tipa karakter, u svim ostalim slučajevima rezultat je cijeli broj karakter * cijeli * Sl. 8.5.1. Generisani kôd za sabiranje zavisno od tipova argumenata 40 Operacija Desni Karakter cijeli karakter * cijeli * karakter Clan { PUSH EAX Clan MOV EBX,EAX POP EAX SUB AL,BL } Nije dopušteno Nije dopušteno cijeli Clan { PUSH EAX Clan MOV EBX,EAX POP EAX AND EBX,0FFh SUB EAX,EBX } Nije dopušteno Clan { PUSH EAX Clan MOV EBX,EAX POP EAX AND EAX,0FFh SUB EAX,EBX } Clan { PUSH EAX Clan MOV EBX,EAX POP EAX SUB EAX,EBX } Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Lijevi Samo za slučaj oduzimanja dva karaktera rezultat je tipa karakter, u svim ostalim slučajevima rezultat je cijeli broj karakter * cijeli * Sl. 8.5.2. Generisani kôd za oduzimanje zavisno od tipova argumenata Iz tabela sa sabiranje i oduzimanje (Sl. 8.5.1 i Sl. 8.5.2) vidi se da pointerski tipovi ne mogu učestvovati u operacijama sabiranja i oduzimanja. Samo ako su oba operanda karakteri koriste se instrukcije ADD AL,BL ili SUB AL,BL. Ako je jedan operand karakter ubacuje se AND EAX,0FFh ili AND EBX,0FFh. Na ovaj način se tri viša bajta EAX ili EBX registra postavljaju na nule, bez izmjena registara AL odnosno BL. To predstavlja efikasnu konverziju između karaktera i cijelih brojeva. Ako su oba operanda cijeli brojevi, nema dodatnih instrukcija. Operacija Desni Karakter cijeli karakter * cijeli * Cijeli ili karakter Clan { PUSH EAX Clan POP EBX AND EAX,EBX } Clan { PUSH EAX Clan POP EBX AND EAX,EBX } Nije dopušteno Nije dopušteno Cijeli ili karakter Clan { PUSH EAX Clan POP EBX OR EAX,EBX } Clan { PUSH EAX Clan POP EBX XOR EAX,EBX } Clan { PUSH EAX Clan POP EBX OR EAX,EBX } Clan { PUSH EAX Clan POP EBX XOR EAX,EBX } Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Lijevi & rezultat je karakter ako su oba argumenta tog tipa, inače cijeli | tip kao kod & ^ tip kao kod & Cijeli ili karakter Sl. 8.5.3. Generisani kôd za logičke operacije zavisno od tipova argumenata Logičke operacije (Sl. 8.5.3) nemaju prijenosa, jer se obavljaju bit po bit. Kod ovih instrukcija nema potrebe za specijalnim slučajevima u kodu. 41 Operacija Desni Karakter cijeli karakter * cijeli * Faktor { PUSH EAX Faktor POP EBX AND EAX,0FFh AND EBX,0FFh IMUL EBX } Faktor { PUSH EAX Faktor POP EBX AND EAX,0FFh IMUL EBX } Nije dopušteno Faktor { PUSH EAX Faktor POP EBX AND EBX,0FFh IMUL EBX } Nije dopušteno Nije dopušteno Faktor { PUSH EAX Faktor POP EBX IMUL EBX } Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Lijevi karakter * Tip rezultata je uvijek cijeli broj cijeli karakter * cijeli * Sl. 8.5.4. Generisani kôd za množenje zavisno od tipova argumenata Na slici Sl. 8.5.4 se vidi da pri množenju nisu dopušteni pointeri kao faktori, a da se faktori koji su tipa karakter trebaju prije množenja konvertovati u cijeli broj instrukcijama AND EAX,0ffh ili AND EBX,0ffh. Operacija Desni Karakter Cijeli karakter * cijeli * Faktor { PUSH EAX Faktor MOV EBX,EAX POP EAX AND EAX,0FFh AND EBX,0FFh CDQ IDIV EBX } Faktor { PUSH EAX Faktor MOV EBX,EAX POP EAX AND EBX,0FFh CDQ IDIV EBX } Nije dopušteno Faktor { PUSH EAX Faktor MOV EBX,EAX POP EAX AND EAX,0FFh CDQ IDIV EBX } Nije dopušteno Nije dopušteno Faktor { PUSH EAX Faktor MOV EBX,EAX POP EAX CDQ IDIV EBX } Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Lijevi karakter / Tip rezultata je uvijek cijeli broj cijeli karakter * cijeli * Sl. 8.5.5. Generisani kôd za dijeljenje zavisno od tipova argumenata 42 Operacija Desni Karakter Cijeli karakter * cijeli * Faktor { PUSH EAX Faktor MOV EBX,EAX POP EAX AND EAX,0FFh AND EBX,0FFh CDQ IDIV EBX MOV EAX,EDX } Faktor { PUSH EAX Faktor MOV EBX,EAX POP EAX AND EBX,0FFh CDQ IDIV EBX MOV EAX,EDX } Nije dopušteno Faktor { PUSH EAX Faktor MOV EBX,EAX POP EAX AND EAX,0FFh CDQ IDIV EBX MOV EAX,EDX } Nije dopušteno Nije dopušteno Faktor { PUSH EAX Faktor MOV EBX,EAX POP EAX CDQ IDIV EBX MOV EAX,EDX } Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Nije dopušteno Lijevi karakter % Tip rezultata je uvijek cijeli broj cijeli karakter * cijeli * Sl. 8.5.6. Generisani kôd za ostatak pri dijeljenju zavisno od tipova argumenata Na slikama Sl. 8.5.5 i Sl. 8.5.6 se vidi da pri dijeljenju i ostatku pri dijeljenju nisu dopušteni pointeri kao operandi, a da se operandi koji su tipa karakter trebaju prije dijeljenja konvertovati u cijeli broj instrukcijama AND EAX,0ffh ili AND EBX,0ffh. Operacija Desni Karakter cijeli karakter * cijeli * Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],AL Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],EAX Nije dopušteno Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],AL Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],EAX Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],EAX Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],EAX Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],AL Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],EAX Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],EAX Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],EAX Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],AL Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],EAX Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],EAX Izraz PUSH EBX Izrazdodjelj POP EBX MOV [EBX],EAX Lijevi karakter cijeli := Tip rezultata je tip koji ima operand sa lijeve strane operatora karakter * cijeli * Sl. 8.5.7. Nije dopušteno Generisani kôd za dodjeljivanje zavisno od tipova argumenata Iz tabele Sl. 8.5.7 vidi se da se karakter ne smije dodijeliti pointeru, a da je međusobna razlika svih ostalih kombinacija tipova operanada u tome što ako se s lijeve strane izraza dodjeljivanja nalazi varijabla karakterskog tipa, da se na navedenu adresu na koji pokazuje registar EBX upisuje sadržaj registra AL. Pointerske varijable se mogu dodjeljivati cjelobrojnim i obrnuto, bez eksplicitnog navođenja imena tipa (type casting). 43 Operacija Desni Karakter cijeli karakter * cijeli * karakter Izraz PUSH EAX Izraz POP EBX CMP BL,AL SETE AL AND EAX,0FFh cijeli Izraz PUSH EAX Izraz POP EBX AND EBX,0FFh CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX AND EBX,0FFh CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX AND EBX,0FFh CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX AND EAX,0FFh CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX AND EAX,0FFh CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX AND EAX,0FFh CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX CMP EBX,EAX SETE AL AND EAX,0FFh Izraz PUSH EAX Izraz POP EBX CMP EBX,EAX SETE AL AND EAX,0FFh Lijevi =#<> Tip rezultata je uvijek cijeli broj. Promijeniti instrukciju SETE u karakter * Za = SETE cijeli * Za < SETL Za > SETG Za # SETNE Sl. 8.5.8. Generisani kôd za poređenje zavisno od tipova argumenata Tabela na slici Sl. 8.5.8 obuhvata sva četiri relaciona operatora, pri čemu je za svaki navedeni operator potrebno upisati odgovarajuću SETxx instrukciju. Unarni operatori i generisani kôd za njih su navedeni na slici Sl. 8.5.9. Operacija Karakter cijeli karakter * cijeli * Unarni - Nije dopušteno Faktor NEG EAX (rez. tip je cijeli ) Nije dopušteno Nije dopušteno Unarni * Nije dopušteno Nije dopušteno Faktor MOV EBX,EAX MOV EAX,[EBX] (rez. tip je cijeli) Unarni & Faktor MOV EAX,EBX (rez. tip je karakter *) Faktor MOV EAX,EBX (rez. tip je cijeli *) Unarni ! CMP EAX,0 SETE AL AND EAX,0FFh (rez. tip je karakter ) Faktor NOT AL (rez. tip je karakter ) CMP EAX,0 SETE AL (rez. tip je cijeli ) Faktor MOV EBX,EAX MOV EAX,[EBX] AND EAX,0FFh (rez. tip je karakter ) Faktor MOV EAX,EBX (rez. tip je cijeli *) Nije dopušteno Faktor MOV EAX,EBX (rez. tip je cijeli *) Nije dopušteno Nije dopušteno Nije dopušteno Unarni ~ Sl. 8.5.9. Faktor NOT EAX (rez. tip je cijeli ) Generisani kôd za unarne operatore zavisno od tipova argumenata Na bazi gornjih tabela se mijenjaju funkcije Clan, Faktor, Izraz i IzrazDodjeljivanja. Iskorištavaju se uočene pravilnosti u generisanom kodu, jer nema potrebe mnogo puta ponavljati isti skup naredbi. 8.6. Funkcije i provjera parametara Deklaracija funkcije se u ovoj verziji kompajlera proširuje definisanjem svih parametara i lokalnih varijabli koje funkcija može imati, kao na slici Sl. 8.6.1. 44 ImeTipa funkcija Identifikator ( Ime Tipa Identifikator ) { Deklaracia varijabli Blok , ; Sl. 8.6.1. Deklaracija funkcije Deklarisanje parametara i lokalnih varijabli se realizuje tako da se za svaki prepoznati identifikator dodaju podaci o njemu u tabelu identifikatora, pri čemu se za nivo uzima pozicija identifikatora funkcije u tabeli svih identifikatora. Po Windowsovom standardu svi parametri, bez obzira na veličinu, moraju biti poravnati na adrese djeljive sa 4. Pod poravnanjem se podrazumijeva smještanje svih podataka tako da počinju od adrese djeljive s nekim paranim brojem. Lokalne varijable moraju biti poravnate na adrese djeljive sa 4 ako je njihova dužina djeljiva sa 4. Prema redoslijedu smještanja parametara na stek razlikuju se konvencije: a) C call, parametri se smještaju na stek PUSH instrukcijama u obrnutom redoslijedu u odnosu na navedeni u pozivu funkcije, a poziciju stek pointera vraća u prvobitno stanje glavni program. Ovaj način poziva se koristi u Windows API funkciji wvsprintf i svim funkcijama biblioteke MSVCRT.DLL (biblioteka Microsoft C kompajlera) b) Pascal call, parametri se smještaju na stek PUSH instrukcijama u istom redoslijedu u odnosu na navedeni, a poziciju stek pointera vraća u prvobitno stanje potprogram. Koristi se u svim sistemskim pozivima za Windows 3.1 aplikacije c) StdCall, parametri se smještaju na stek PUSH instrukcijama u obrnutom redoslijedu u odnosu na navedeni, a poziciju stek pointera vraća u prvobitno stanje potprogram. Koristi se u većini Win32 API funkcija. d) Fast Call, parametri su u registrima, koristi se pri pozivu DOS interapta e) Inline Call, parametri se navode u memorijskom bloku, (na fiksnoj lokaciji ili neposredno iza CALL instrukcije= obično se interno koristi u asemblerskim programima. Najlakše je prilagoditi postojeći kompajler da generiše pozive po Pascal Call standardu, pa će ovaj način poziva biti i implementiran. Pri tome će se ime potprograma generisati od imena funkcije iza kojeg slijedi znak @ i ukupan broj bajtova koliko zauzimaju parametri. Tako na primjer funkcija čije je ime Racunaj i koja ima tri parametra će u generisanom kodu imati ime Racunaj@12. Ovo je učinjeno da bi se postigla izvjesna kompatibilnost sa Win32 API funkcijama koje imaju interno iste ovakve nazive, a kojih postoji preko 9000. Windows API funkcije, međutim, koriste standard StdCall, koje zahtijeva suprotan redoslijed postavljanja parametara na stek od standarda Pascal Call. Ovaj problem je rješiv tako što se pri pozivu ovih funkcija navode parametri obrnutim redoslijedom u odnosu na onaj kojim se parametri navode u jeziku C i kako su definisan u standardnoj dokumentaciji za Windows API. Generisani kôd za definiciju funkcije izgleda kao na slici Sl. 8.6.2. PUSH EBP Racunaj@12: (zavisno od imena i prostora za parametre) MOV EBP,ESP SUB ESP,velicina prostora za lokalne varijable Pozovi Blok; MOV ESP,EBP POP EBP RET velicina prostora za parametre PUBLIC Racunaj@12 Sl. 8.6.2. Definicija funkcije, generisani kôd Postavljanje EBP registra na mjesto gdje se ESP nalazio prije alokacije prostora za lokalne varijable, omogućava da se lokalnim varijablama pristupa sa MOV EAX,[EBP-nn] a parametrima sa MOV EAX,[EBP+nn]. Odgovarajuće konstante nn se računaju prilikom deklaracija lokalnih varijabli i parametara i nalaze se u polju adresa tabele identifikatora. Za parametre, prije dohvatanja prvog parametra ovo polje ima vrijednost 0, a zatim se uvećava za ((duzinavarijable-1) div 4 + 1)*4 nakon 45 svakog deklarisanog parametra. Za lokalne varijable, prije dohvatanja prve lokalne varijable, ovo polje ima vrijednost 0, a zatim se, kako se redom dohvataju varijable, po apsolutnoj vrijednosti uvećava za duzinavarijable, a upisuje se negativna vrijednost. Generisani kôd za poziv funkcije, prikazan na slici Sl. 8.6.3 se vrlo malo promijenio od prethodne verzije kompajlera Za svaki parametar (osim ako se karakter prosljeđuje pointeru što je greška): Pozovi Izrazdodjeljivanja Ako se karakter prosljeđuje cijelim brojevima generiši AND EAX,0FFh PUSH EAX MOV ECX,ukupna veličina svih parametara CALL funkcija@duzinaparametara Ako funkcija vraća karakter generiši AND EAX,0FFh Sl. 8.6.3. Generisani kôd za poziv funkcije Globalnim varijablama se i sada pristupa sa MOV EAX,GLOBALV[nn] pri čemu se nn nalazi u polju adresa tabele identifikatora. Ako je varijabla tipa karakter registar EAX treba zamijeniti registrom AL. Prilikom deklaracije globalnih varijabli prije dohvatanja prve globalne varijable ovo polje ima vrijednost 0, a zatim se kako se redom dohvataju varijable po apsolutnoj vrijednosti uvećava za duzinavarijable. Koristeći sve ove informacije, može se napisati nova verzija kompajlera. Navedena je u prilogu broj 5. 8.7. Testni primjer Primjer programa u petoj verziji jezika može biti identičan prethodnom primjeru, uz izbacivanje potrebe da se dijelovi pišu u asembleru. Ipak, pošto dosadašnji primjeri nisu imali ulaz, dodano je da se unese ime korisnika na početku, a zatim ono i prikaže na ekranu. Za čitanje se koristi API funkcija ReadConsoleA, koja ima iste parametre kao i WriteConsoleA, samo što zahtijeva standardni hendl –10, umjesto –11. Primjer se prevodi koristeći komp32v5 tabbroj2.jez tabbro2j.asm ml /c /coff /Fl tabbroj2.asm | more link /defaultlib:user32.lib kernel32.lib /subsystem:console tabbroj2.obj Izvorni kôd primjera naveden je na slici Sl. 8.7.1 46 cijeli funkcija GetStdHandle(cijeli brhan); cijeli funkcija WriteConsoleA(cijeli rez,cijeli * upisano, cijeli upisati,karakter * bafer,cijeli han); cijeli funkcija ReadConsoleA(cijeli rez,cijeli * upisano, cijeli upisati,karakter * bafer,cijeli han); cijeli * a; ` Ovo je zapravo niz pointera na stringove cijeli * ime; cijeli funkcija Prikazistring (karakter * poruka){ cijeli handle,priv,duz; handle:=GetStdHandle(-11); duz:=0; dok (poruka[duz]#0) { duz:=duz+1;} WriteConsoleA(0,&priv,duz,poruka,handle); } cijeli funkcija Unesistring (karakter * poruka){ cijeli handle,priv,duz; handle:=GetStdHandle(-10); duz:=30; ReadConsoleA(0,&priv,duz,poruka,handle); } cijeli funkcija Novired () { karakter * dvoznak; dvoznak:=" "; dvoznak[0]:=13; dvoznak[1]:=10; Prikazistring(dvoznak); } cijeli funkcija Predstavljanje () { ime:=" "; Unesistring(ime); Prikazistring("Tabelu generisao "); Prikazistring(ime); Novired(); } cijeli funkcija Prikazibroj (cijeli broj){ cijeli cifra,negativan,pokazivac,ostatak; karakter * bafer; bafer:=" "; ` Alociramo bafer cifra:=broj; ` Negativne brojeve oznaci indikatorom ako (cifra<0) { negativan:=1; cifra:=-cifra; } inace { negativan:=0; } `maksimalno 9 cifara pokazivac:=9; ako (cifra=0) { bafer[pokazivac]:='0'; pokazivac:=pokazivac-1; } dok (cifra>0) { ostatak:=(cifra % 10); `ostatke dijeljenja u bafer bafer[pokazivac]:=ostatak+'0'; cifra:=cifra/10; ` stalno dijeli s 10 pokazivac:=pokazivac-1; } ako (negativan=1) { Sl. 8.7.1. 8.8. bafer[pokazivac]:='-'; pokazivac:=pokazivac-1; } bafer:=&(bafer[pokazivac+1]); ` Pomjeri pokazivac pocetka stringa Prikazistring(bafer); } cijeli funkcija Fact(cijeli a) { ako (a=0) { 1; } inace { a*Fact(a-1); } } cijeli funkcija Tabela() { cijeli m,n; Prikazistring("Tabela"); Novired(); n:=1; dok (n<11) { Prikazibroj (n); Prikazistring(" "); Prikazistring(a[n]); Prikazistring(" "); Prikazibroj (n*n); Prikazistring(" "); Prikazibroj (n*n*n); Prikazistring(" "); Prikazibroj (Fact(n)); Prikazistring(" Djeljiv sa "); m:=1; dok !(m>n) { ako (n%m=0) { Prikazibroj(m); Prikazistring(" "); } m:=m+1; } n:=n+1; Novired(); } } cijeli funkcija Postavinazive() { a:=" ` Prostor za niz a[1]:="Jedan"; a[2]:="Dva"; a[3]:="Tri"; a[4]:="Cetiri"; a[5]:="Pet"; a[6]:="Sest"; a[7]:="Sedam"; a[8]:="Osam"; a[9]:="Devet"; a[10]:="Deset"; } { Predstavljanje(); Postavinazive(); Tabela(); } "; Primjer: Tablica brojeva bez asemblerskih modula Rezime poglavlja Ova verzija kompajlera predstavlja veliki skok naprijed i omogućava realizaciju većine aplikacija koje koriste cijele brojeve i stringove. Uvedeni su tipovi cijeli, cijeli *, realni i realni *. Program se sada sastoji iz deklaracija varijabli, deklaracija funkcija i tijela programa Imena varijabli se sastoje iz više slova, pa je potrebna tablica identifikatora. Pri pozivu funkcija provjerava se broj i tipovi argumenata. Uvođenje tipova usložnjava aritmetičke izraze i zahtijeva pažljivo praćenje generisanog koda za svaku kombinaciju operanada različitog tipa. U testnim primjerima opada potreba za asemblerom. 47 Prilog 5: Verzija izvornog koda kompajlera br. 5 program Kompajler; const MAXIDENT = 1024; DUGAKONST = 'Konstanta prevazilazi liniju'; OCEKIVANO = 'Ocekivano '; REDEKLAR = 'Redeklarisan identifikator'; PROSTNIZ = 'Prosti tip ne moze biti niz'; NEKORARG = 'Nekorektan broj argumenata'; NEKDODJP = 'Losa dodjela pointeru'; NEDEKL = 'Nedeklarisano '; GRIZRAZ = 'Izraz'; POGRMNOZ = 'Pogresan tip u ' + 'mnozenju ili dijeljenju'; NEDOPFP = ' Nedopustena FP operacija'; NEDOPARIT = 'Nedopusteni tip u aritmetici'; OCEKDOD = 'Ocekivano dodjeljivanje'; NEDODJ = 'Izraz se ne moze dodijeliti'; DODJPOINT = 'Losa dodjela pointeru'; TIPUSL = 'Neodgovarajuci tip uslova'; TUSLPET = 'Neodgovarajuci uslov u petlji'; IMEFUN = 'Ocekivano ime funkcije'; DEFFUN = 'Definicija funkcije'; ARGNEKOM = 'Argument nekompatibilan' + ' s operatorom'; OCIDENT = 'Ocekivan Identifikator'; type TVrsta = (funkcija, lokalna, globalna, parametar); TTip = (karakter, cijeli, pkarakter, pcijeli); TIdent = record ime: string[20]; duzina: integer; adresa: integer; nivo: integer; vrsta: TVrsta; tip: TTip; pod1: integer; pod2: integer; pod3: integer; end; var ulaz, izlaz: text; pozicija, trenlabela, brojaclinija, aktnivo: integer; znak: char; linija: string; TabIdent: array[0..MAXIDENT] of TIdent; ukupnoident: integer; t: TTip; dod: Boolean; procedure NoviIdent(pime: string; pduzina: integer; padresa: integer; pnivo: integer; pvrsta: TVrsta; ptip: TTip; ppod1: integer; ppod2: integer; ppod3: integer); begin ukupnoident := ukupnoident + 1; with TabIdent[ukupnoident] do begin ime := pime; duzina := pduzina; adresa := padresa; nivo := pnivo; vrsta := pvrsta; tip := ptip; pod1 := ppod1; pod2 := ppod2; pod3 := ppod3; end; end; procedure NovaLabela(var ImeLabele: string); begin trenlabela := trenlabela + 1; Str(trenlabela, ImeLabele); end; procedure Greska(poruka: string); begin WriteLn(poruka); WriteLn(brojaclinija, ':', linija); Close(ulaz); Close(izlaz); Halt; end; procedure Emit(st: string); begin WriteLn(izlaz, st); end; procedure Novi; begin repeat pozicija := pozicija + 1; if pozicija > Length(linija) then begin brojaclinija := brojaclinija + 1; if not (Eof(ulaz)) then ReadLn(ulaz, linija); Emit(';' + linija); pozicija := 1; end; if Length(linija) > 0 then znak := linija[pozicija] else znak := ' '; if (znak = '`') then pozicija := Length(linija); until ((znak > ' ') and (znak <> '`')) or Eof(ulaz) end; if Length(linija) >= n then begin znak := linija[n]; if ((znak >= 'a') and (znak <= 'z')) or ((znak >= 'A') and (znak <= 'Z')) then ureduiza := false end end; if ureduiza and (copy(linija, pozicija, Length(ocekivano)) = ocekivano) then begin Slijedi := true; pozicija := pozicija + Length(ocekivano) - 1; end else Slijedi := false; end; function TipDek(imetipa: string; var tip: TTip; stip, ptip: TTip): Boolean; begin TipDek := false; if Slijedi(imetipa, false) then begin TipDek := true; Novi; if znak = '*' then begin tip := ptip; Novi end else tip := stip; end end; procedure NoviSvaki(greskakrln: Boolean); begin pozicija := pozicija + 1; if pozicija > Length(linija) then begin if greskakrln then Greska(DUGAKONST) else znak := ' '; end else znak := linija[pozicija]; end; function SlijediDekTipa(var tip: TTip): Boolean; var a: Boolean; begin a := false; if not (a) then a := TipDek('cijeli', tip, cijeli, pcijeli); if not (a) then a := TipDek('karakter', tip, karakter, pkarakter); SlijediDekTipa := a; end; procedure IdiDo(z: char); begin if (znak <> z) then Greska(OCEKIVANO + z); Novi; end; function DuzinaTipa(tip: TTip): Integer; begin case tip of cijeli, pcijeli, pkarakter: DuzinaTipa := 4; karakter: DuzinaTipa := 1; else DuzinaTipa := 4; end; end; function UzmiKonstantu (var t: TTip; var dod: Boolean): integer; var rezultat: integer; begin rezultat := 0; while (znak >= '0') and (znak <= '9') do begin rezultat := 10 * rezultat + ord(znak) - ord('0'); NoviSvaki(false); end; if (znak = ' ') or (znak = '`') then Novi; UzmiKonstantu := rezultat; t := cijeli; dod := false; end; function Slijedi(ocekivano: string; dslovoiza: Boolean): Boolean; var ureduiza: Boolean; n: integer; znak: char; begin if dslovoiza then ureduiza := true else begin n := pozicija + Length(ocekivano); ureduiza := true; function NadjiIdent(ident: string; nivo, tuslova, p1: integer): integer; var n, poz: integer; nadjen, Uslov: Boolean; begin n := ukupnoident; nadjen := false; poz := 0; while (n > 0) and (not (nadjen)) do begin case tuslova of 1: Uslov := (TabIdent[n].ime = ident) and (TabIdent[n].vrsta in [lokalna, globalna, parametar, funkcija]) and ((TabIdent[n].nivo = nivo) or (TabIdent[n].nivo = 0)); 2: Uslov := (TabIdent[n].ime = ident) and (TabIdent[n].vrsta in [lokalna, globalna, parametar, funkcija]) and ((TabIdent[n].nivo = nivo)); 4: Uslov := (TabIdent[n].nivo = nivo) and 48 (TabIdent[n].pod2 = p1) and (TabIdent[n].vrsta = parametar) else Uslov := false; end; if Uslov then begin nadjen := true; poz := n; end; n := n - 1; end; NadjiIdent := poz; end; '''''' then st := 'L' + strtekst + ' DB 0'; Emit(st); Emit('.CODE'); Emit(' MOV EAX,OFFSET L' + strtekst); t := pkarakter; dod := false; end; procedure PozivFunkcije (idpoz: integer; var t: TTip; var dod: Boolean); var parametara, N, velsteka: integer; t1, t2: TTip; procedure UzmiIdent(var ident: string); ImeFunkcije, st: string; begin begin ImeFunkcije := TabIdent[idpoz].ime; if znak in ['a'..'z', 'A'..'Z'] then parametara := 0; begin velsteka := 0; ident := znak; NoviSvaki(false); IdiDo('('); end while (znak <> ')') do begin IzrazDodjeljivanja(t1, dod); else parametara := parametara + 1; Greska(OCIDENT); n := NadjiIdent('', idpoz, 4, while (znak in ['a'..'z', 'A'..'Z', parametara); '0'..'9', '_']) do begin if n = 0 then ident := ident + znak; Greska(NEKORARG); NoviSvaki(false); t2 := TabIdent[n].tip; end; if (t1 = karakter) and if (znak = ' ') or (znak = '`') then (t2 in [pkarakter, pcijeli]) then Novi; Greska(NEKDODJP); end; if (t1 = karakter) and (t2 = cijeli) then procedure DeklIdent(var ident: string; Emit(' AND EAX,0FFh'); nivo: integer); velsteka := velsteka + 4; begin Emit(' PUSH EAX'); UzmiIdent(ident); if znak <> ')' then if NadjiIdent(ident, nivo, 2, 0) <> 0 then IdiDo(','); Greska(REDEKLAR); end; end; IdiDo(')'); if TabIdent[idpoz].pod1 <> parametara then procedure IzrazDodjeljivanja Greska(NEKORARG); (var t: TTip; var dod: Boolean); Str(velsteka, st); forward; Emit(' MOV ECX,' + st); procedure Blok; forward; Emit(' CALL ' + ImeFunkcije + '@' + st); procedure PokazivacINiz(var t: TTip; var dod := false; dod: Boolean); t := TabIdent[idpoz].tip; var if t = karakter then t1: TTip; Emit(' AND EAX,0FFh0'); begin end; Novi; Emit(' PUSH EAX'); procedure Varijabla IzrazDodjeljivanja(t1, dod); (idpoz: integer; var t: TTip; var Emit(' POP EBX'); dod: Boolean; glob: Boolean); case t of pkarakter: begin var t := karakter; rezultat: integer; end; st: string; begin pcijeli: begin rezultat := TabIdent[idpoz].adresa; Emit(' SAL EAX,2'); t := TabIdent[idpoz].tip; t := cijeli; Str(rezultat, st); end; else if glob then Emit(' LEA EBX,GLOBALV[' + st + ']') Greska(PROSTNIZ) else begin end; if rezultat >= 0 then Emit(' ADD EBX,EAX'); Emit(' LEA EBX,[EBP+' + st + ']') case t of else karakter: Emit(' LEA EBX,[EBP' + st + ']'); Emit(' MOV AL,[EBX]'); else end; case t of Emit(' MOV EAX,[EBX]'); karakter: Emit(' MOV AL,[EBX]'); end; else IdiDo(']'); Emit(' MOV EAX,[EBX]'); dod := true; end; end; dod := true; if znak = '[' then procedure StringKonstanta(var t: TTip; PokazivacINiz(t, dod); var dod: Boolean); end; var st, strtekst: string; procedure Faktor(var t: TTip; var dod: begin Boolean); NovaLabela(strtekst); var Emit('.DATA'); rezultat, poz: integer; st := 'L' + strtekst + ' DB '''; st, ime, err: string; repeat begin NoviSvaki(true); err := ARGNEKOM; if znak <> '"' then st := st + znak; case znak of until znak = '"'; '-': begin IdiDo('"'); Novi; Faktor(t, dod); st := st + ''',0'; case t of if copy(st, length(st) - 3, 2) = cijeli: Emit(' NEG EAX'); else Greska(err); end; dod := false; end; '~': begin Novi; Faktor(t, dod); case t of cijeli: Emit(' NOT EAX'); karakter: Emit(' NOT AL'); else Greska(err); end; dod := false; end; '&': begin Novi; Faktor(t, dod); Emit(' MOV EAX,EBX'); case t of cijeli: t := pcijeli; karakter: t := pkarakter; else t := pcijeli; end; dod := false; end; '*': begin Novi; Faktor(t, dod); Emit(' MOV EBX,EAX'); Emit(' MOV EAX,[EBX]'); case t of pcijeli: t := cijeli; pkarakter: begin t := karakter; Emit(' AND EAX,0FFh'); end; else Greska(err); end; dod := true; end; '!': begin Novi; Faktor(t, dod); case t of cijeli: Emit(' CMP EAX,0'); karakter: Emit(' CMP AL,0'); else Greska(err); end; Emit(' SETE AL'); Emit(' AND EAX,0FFh'); dod := false; t := cijeli; end; '"': begin StringKonstanta(t, dod); end; '''': begin NoviSvaki(true); Emit(' MOV AL,''' + znak + ''''); Novi; IdiDo(''''); t := karakter; end; '0'..'9': begin rezultat := UzmiKonstantu(t, dod); Str(rezultat, st); Emit(' MOV EAX,' + st); end; '(': begin Novi; IzrazDodjeljivanja(t, dod); IdiDo(')'); end; 'A'..'Z', 'a'..'z': begin UzmiIdent(ime); poz := NadjiIdent(ime, aktnivo, 1, 0); if poz = 0 then Greska(NEDEKL + ime); case TabIdent[poz].vrsta of funkcija: PozivFunkcije(poz, t, dod); lokalna, parametar: Varijabla(poz, t, dod, false); globalna: 49 Varijabla(poz, t, dod, true) end end; else Greska(GRIZRAZ); end; end; procedure Clan(var t: TTip; var dod: Boolean); var z: char; t1, t2: TTip; begin Faktor(t1, dod); t := t1; while (znak in ['*', '/', '%']) do begin z := znak; Emit(' PUSH EAX'); Novi; Faktor(t2, dod); dod := false; if ((t1 <> cijeli) and (t1 <> karakter)) or ((t2 <> cijeli) and (t2 <> karakter)) then Greska(POGRMNOZ); t := cijeli; case z of '*': begin Emit(' POP EBX'); if t1 = karakter then Emit(' AND EBX,0FFh'); if t2 = karakter then Emit(' AND EAX,0FFh'); Emit(' IMUL EBX'); end; '/', '%': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); Emit(' CDQ'); if t1 = karakter then Emit(' AND EAX,0FFh'); if t2 = karakter then Emit(' AND EBX,0FFh'); Emit(' IDIV EBX'); if z = '%' then Emit(' MOV EAX,EDX'); end; end; t1 := t; end; end; procedure Izraz(var t: TTip; var dod: Boolean); var z: char; t1, t2: TTip; begin Clan(t1, dod); t := t1; while (znak in ['+', '-', '&', '|', '^']) do begin Emit(' PUSH EAX'); z := znak; Novi; Clan(t2, dod); dod := false; if ((t1 <> cijeli) and (t1 <> karakter)) or ((t2 <> cijeli) and (t2 <> karakter)) then Greska(NEDOPARIT); case z of '+': begin Emit(' POP EBX'); if (t1 = karakter) and (t2 = karakter) then begin t := karakter; Emit(' ADD AL,BL'); end else begin t := cijeli; if t1 = karakter then Emit(' AND EBX,0FFh'); if t2 = karakter then Emit(' AND EAX,0FFh'); Emit(' ADD EAX,EBX'); end; end; '-': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); if (t1 = karakter) and (t2 = karakter) then begin t := karakter; Emit(' SUB AL,BL'); end else begin t := cijeli; if t1 = karakter then Emit(' AND EAX,0FFh'); if t2 = karakter then Emit(' AND EBX,0FFh'); Emit(' SUB EAX,EBX'); end; end; '&', '|', '^': begin if (t1 = karakter) and (t2 = karakter) then t := karakter else t := cijeli; Emit(' POP EBX'); case z of '&': Emit(' AND EAX,EBX'); '|': Emit(' OR EAX,EBX'); '^': Emit(' XOR EAX,EBX'); end; end; end; t1 := t; end; end; procedure IzrazDodjeljivanja (var t: TTip; var dod: Boolean); var z: char; t1, t2: TTip; dod1: Boolean; begin Izraz(t1, dod1); t := t1; dod := dod1; case znak of ':': begin if not (Slijedi(':=', true)) then Greska(OCEKDOD); if not (dod1) then Greska(NEDODJ); Emit(' PUSH EBX'); Novi; IzrazDodjeljivanja(t2, dod); Emit(' POP EBX'); if (t2 = karakter) and (t1 <> karakter) and (t1 <> cijeli) then Greska(DODJPOINT); if t1 = karakter then Emit(' MOV [EBX],AL') else Emit(' MOV [EBX],EAX'); t := t1; end; {:} '=', '>', '<', '#': begin Emit(' PUSH EAX'); z := znak; Novi; Izraz(t2, dod); Emit(' POP EBX'); if (t1 = karakter) and (t2 = karakter) then Emit(' CMP BL,AL') else begin if t1 = karakter then Emit(' AND EAX,0FFh'); if t2 = karakter then Emit(' AND EBX,0FFh'); Emit(' CMP EBX,EAX'); end; case z of '=': Emit(' SETE AL'); '>': Emit(' SETG AL'); '<': Emit(' SETL AL'); '#': Emit(' SETNE AL'); end; Emit(' AND EAX,0FFh'); t := cijeli; end; end; end; procedure Uslov; var sonda, sinace, skrajuslova: string; begin Novi; IzrazDodjeljivanja(t, dod); if t <> cijeli then Greska(TIPUSL); Emit(' CMP EAX,0'); NovaLabela(sonda); NovaLabela(sinace); NovaLabela(skrajuslova); Emit(' JNE L' + sonda); Emit(' JMP L' + sinace); IdiDo('{'); Emit('L' + sonda + ':'); Blok; Emit(' JMP L' + skrajuslova); Emit('L' + sinace + ':'); if Slijedi('inace', false) then begin Novi; IdiDo('{'); Blok; end; Emit('L' + skrajuslova + ':'); end; procedure Asembler; begin repeat ReadLn(ulaz, linija); if linija <> '\' then Emit(linija); if eof(ulaz) then linija := '\'; until linija[1] = '\'; pozicija := 1; znak := linija[pozicija]; IdiDo('\'); end; procedure Petlja; var sdok, skrajpetlje, suslov: string; begin Novi; NovaLabela(suslov); Emit('L' + suslov + ':'); IzrazDodjeljivanja(t, dod); if t <> cijeli then Greska(TUSLPET); Emit(' CMP EAX,0'); NovaLabela(sdok); NovaLabela(skrajpetlje); Emit(' JNE L' + sdok); Emit(' JMP L' + skrajpetlje); IdiDo('{'); Emit('L' + sdok + ':'); Blok; Emit(' JMP L' + suslov); Emit('L' + skrajpetlje + ':'); end; procedure Blok; begin while znak <> '}' do begin if Slijedi('dok', false) then Petlja else if Slijedi('ako', false) then Uslov else if Slijedi('asembler', false) then Asembler else begin IzrazDodjeljivanja(t, dod); IdiDo(';'); end; end; IdiDo('}'); end; procedure DefFunkcija(ftip: TTip); var parametara, paradresa, lokadresa, pfunkc, i: integer; ImeFunkcije, imeparametra, imevarijable, st: string; tip: TTip; imaistogtipa: Boolean; begin if not (((znak >= 'a') and (znak <= 'z')) or ((znak >= 'A') and (znak <= 'Z'))) then Greska(IMEFUN); DeklIdent(ImeFunkcije, 0); 50 NoviIdent(ImeFunkcije, 4, 0, 0, funkcija, ftip, 0, 0, 0); pfunkc := ukupnoident; aktnivo := pfunkc; IdiDo('('); parametara := 0; lokadresa := 0; paradresa := 0; while znak <> ')' do begin if SlijediDekTipa(tip) then begin DeklIdent(ImeParametra, pfunkc); parametara := parametara + 1; paradresa := paradresa + ((DuzinaTipa(tip) - 1) div 4 + 1) * 4; NoviIdent(ImeParametra, DuzinaTipa(tip), paradresa, pfunkc, parametar, tip, pfunkc, parametara, 0); end; if znak <> ')' then IdiDo(','); end; IdiDo(')'); for i := ukupnoident downto 0 do if (TabIdent[i].nivo = pfunkc) and (TabIdent[i].vrsta = parametar) then TabIdent[i].adresa := paradresa + 8 - TabIdent[i].adresa; TabIdent[pfunkc].pod1 := parametara; case znak of '{': begin IdiDo('{'); while SlijediDekTipa(tip) do begin repeat DeklIdent(ImeVarijable, pfunkc); lokadresa := lokadresa + DuzinaTipa(tip); NoviIdent(ImeVarijable, DuzinaTipa(tip), -lokadresa, pfunkc, lokalna, tip, pfunkc, parametara, 0); imaistogtipa := true; if znak = ',' then begin Novi; imaistogtipa := false; end; until imaistogtipa; while (lokadresa mod 4) <> 0 do lokadresa := lokadresa + 1; IdiDo(';'); end; Str(paradresa, st); Emit(ImeFunkcije + '@' + st + ':'); Emit(' PUSH EBP'); Emit(' MOV EBP,ESP'); Str(lokadresa, st); Emit(' SUB ESP,' + st); Blok; Emit(' MOV ESP,EBP'); Emit(' POP EBP'); Str(paradresa, st); Emit(' RET ' + st); Emit('PUBLIC ' + ImeFunkcije + '@' + st); end; ';': begin Str(paradresa, st); Emit('extrn ' + ImeFunkcije + '@' + st + ':near'); IdiDo(';'); end else Greska(DEFFUN); end; aktnivo := 0; end; procedure Prevedi; var globadresa: Integer; ImeVarijable, st: string; tip: TTip; imaistogtipa: Boolean; begin Emit('.386'); Emit('.MODEL FLAT,STDCALL'); Emit('OPTION CASEMAP:NONE'); Emit('EXTRN ExitProcess@4:NEAR'); Emit('.CODE'); Emit('ULAZ:'); Emit(' JMP GLAVNI'); pozicija := 0; globadresa := 0; Novi; while SlijediDekTipa(tip) do begin if Slijedi('funkcija', false) then begin Novi; DefFunkcija(tip); end else begin repeat DeklIdent(ImeVarijable, 0); NoviIdent(ImeVarijable, DuzinaTipa(tip), globadresa, 0, globalna, tip, 0, 0, 0); globadresa := globadresa + DuzinaTipa(tip); imaistogtipa := true; if znak = ',' then begin Novi; imaistogtipa := false; end; until imaistogtipa; while (globadresa mod 4) <> 0 do globadresa := globadresa + 1; IdiDo(';'); end end; IdiDo('{'); if znak <> '}' then begin Emit('GLAVNI:'); Blok; Emit(' PUSH 0'); Emit(' CALL ExitProcess@4'); Emit('.DATA'); Str(globadresa, st); Emit('GLOBALV DB ' + st + ' DUP(0)'); Emit('END ULAZ') end else begin Emit('GLAVNI:'); Emit('END'); end; end; procedure Glavni; var linija: string; begin trenlabela := 0; ukupnoident := 0; aktnivo := 0; Assign(ulaz, paramstr(1)); Assign(izlaz, paramstr(2)); brojaclinija := 0; linija := ''; Reset(ulaz); Rewrite(izlaz); Prevedi; Close(ulaz); Close(izlaz); WriteLn('Prevedeno bez greske'); end; begin Glavni end. 51 9. REALNI BROJEVI Na listi prioriteta koje treba implementirati slijede realni (floating point) brojevi. Iako se mnogi problemi koji zahtijevaju upotrebu ovih brojeva mogu riješiti i cjelobrojnom aritmetikom uz potrebno skaliranje (fixed point), preostaju problemi kod kojih je aritmetika u pokretnom zarezu nezamjenjiva. 9.1. Koprocesor Izbor procesora 486 i Pentium za ciljnu arhitekturu navodi da se aritmetika u pokretnom zarezu realizuje koristeći instrukcije koprocesora koji je u njih ugrađen, umjesto pisanja posebnih potprograma. Čak i za procesore 386 i 486SX (kojima koprocesor nedostaje), Windows 95 obezbjeđuje softverske emulatore koprocesora. Instrukcije za rad u pokretnom zarezu su drugačije koncipirane od instrukcija za cjelobrojnu aritmetiku. One ne operišu sa uobičajenim registrima, nego imaju interni stek na koji može da stane osam konstanti, velikih 32, 64 ili 80 bita. Kao optimalna veličina FP brojeva uzeće se 64 bita, tj. dvostruka preciznost. Brojevi u memoriji su predstavljeni po IEEE-754 standardu. Po ovom standardu, bitovi 0-51 predstavljaju mantisu, bitovi 52-62 predstavljaju eksponent, a bit 63 predznak broja. 9.2. Realne konstante Prije svega je potrebno proširiti sintaksu numeričke konstante. Gotovo svi programski jezici poznaju realne brojeve u formi “2.4E-8” , što predstavlja 2,4·108 u klasičnom obliku. Pri tome se mogu izostaviti predznak eksponenta, čitav eksponentski dio ili necijeli dio frakcije. Stoga nova sintaksa za numeričke konstante izgleda kao na slici Sl. 9.2.1 Numerička konstanta + Cifra . Cifra Cifra E - Sl. 9.2.1. Numerička konstanta Konvertovanje brojeva iz uobičajenog dekadnog formata tipa “2.4E-8” u format “binarna mantisa i eksponent” je složen, neportabilan, posao koji je podložan numeričkim greškama. Na sreću, većina 32-bitnih asemblera već poznaje ovaj format konstanti, pa je dovoljno proslijediti izvorno napisan broj asembleru, koji će pravilno upisati u memoriju konstante oblika KONST DQ 2.4E-8 Stoga je nova verzija procedure UzmiKonstantu razmjerno jednostavna. Ova procedura pored računa cjelobrojne konstante, sve njene znakove pridodaje na jedan string, koji je u globalnoj varijabli realnakonstanta. Ako se pri dohvaćanju znakova naiđe na znak ‘.’ ili ‘E’, prestaje se s računom cjelobrojne konstante, ali se nastavlja pridodavanje znakova na spomenutu globalnu string varijablu, uz stalnu provjeru sintakse. U okviru procedure Faktor, prilikom obrade numeričkih konstanti se provjeri da li je procedura UzmiKonstantu vratila cjelobrojnu ili realnu vrijednost. U slučaju cjelobrojne vrijednosti generiše se uobičajena MOV EAX,nn instrukcija. Ako je u pitanju realna konstanta, tada se vrijednost te konstante ne treba staviti u EAX registar nego na vrh FP steka. Da bi se to postiglo treba generisati sljedeći kôd .DATA L12 DQ 2.4E-8 .CODE FLD L12 pri čemu su oznaka labele i konstanta dati radi ilustracije. 9.3. Komunikacija između FP steka i memorije FP stek je ograničen na svega osam konstanti, za razliku od steka adresiranog ESP registrom za koji je operativni sistem rezervisao nekoliko desetina kilobajta. To onemogućava rekurzivno računanje nekih funkcija, pa je potrebno omogućiti 52 privremeno čuvanje međurezultata FP operacija i na steku adresiranom ESP registrom. U tu svrhu, kao i radi konverzije između formata, se uvode sljedeće procedure: CijeliNaFPStek (sadržaj cjelobrojnog registra se prebacuje na vrh FP steka) generiše sljedeći kôd Ako se posmatra samo nižih osam bita cijelog broja generiši AND registar,0FFh MOV INTTOFP,registar FILD DWORD PTR INTTOFP FPStekUCijeli (broj s vrha FP steka se prebacuje u cjelobrojni registar. Kao privremena lokacija u memoriji koristi se vrh ESP adresiranog steka) generiše sljedeći kôd ADD ESP,-4 FISTP DWORD PTR [ESP] POP registar CPUStekCijeliNaFPStek (cijeli broj sa vrha ESP adresiranog steka prebacuje se na vrh FP steka) generiše sljedeći kôd Ako se posmatra samo nižih osam bita cijelog broja generiši AND DWORD PTR [ESP],0FFh FILD DWORD PTR [ESP] ADD ESP,4 FPUStekNaStek (broj u pokretnom zarezu se prebacuje sa vrha FP steka na vrh ESP adresiranog steka) generiše sljedeći kôd ADD ESP,-8 FSTP QWORD PTR [ESP] StekNaFPUStek (broj u pokretnom zarezu se prebacuje sa vrha ESP adresiranog steka na vrh FP steka) generiše sljedeći kôd FLD QWORD PTR [ESP] ADD ESP,8 Gore navedene funkcije potrebne su i zato što ne postoje instrukcije za direktno prebacivanje podataka iz FP internog steka u cjelobrojne registre. 9.4. Aritmetičke operacije Aritmetičke operacije nad realnim brojevima za slučaj sabiranja, oduzimanja, množenja i dijeljenja uvijek kao rezultat imaju realan broj, bez obzira da li je drugi argument ovih operacija cijeli broj, realni broj ili karakter. Sabiranje u kome je bar jedan sabirak FP broj se može realizovati kodom sa slike Sl. 9.4.1. Pozovi Član Ako je prvi član cijeli broj ili karakter generiši PUSH EAX inače pozovi FPUStekNaStek Pozovi Član Ako nijedan član nije realan broj, generiši kôd kao i ranije, prema tablicama iz prethodnog poglavlja Ako je drugi član cijeli broj ili karakter a prvi član je bio realni broj pozovi CijeliNaFPStek za registar EAX Ako je prvi član cijeli broj ili karakter pozovi CPUStekCijeliNaFP, a ako je realni pozovi StekNaFPUStek Generiši FADD Sl. 9.4.1. Generisanje koda za sabiranje u pokretnom zarezu 53 Potreba za privremenim čuvanjem podataka na procesorskom steku, radi omogućivanja rekurzije, dovodi do redundantnog koda u još izraženijem obliku nego kod cjelobrojne aritmetike. Za sada se zanemaruje taj problem, jer je u ovom trenutku tačnost i jednostavnost kompajlera u prvom planu. Realizacija oduzimanja, množenja i dijeljenja se ne razlikuje mnogo od realizacije sabiranja. Kod ove tri operacije je potrebno umjesto FADD respektivno generisati instrukcije FSUBR, FMUL i FDIVR, koje kao i FADD obavljaju operaciju nad dva broja na vrhu FP steka, uklone ih sa FP steka i rezultat opet ostavljaju na vrh FP steka. Za množenje i dijeljenje poziv funkcije Član se zamjenjuje pozivom funkcije Faktor. U slučaju poređenja koristi se instrukcija FCOMPP, kao na slici Sl. 9.4.2. Instrukcija FCOMPP poredi brojeve na vrhu steka, ali rezultat smješta u koprocesorske flegove. Da bi se ovi flegovi mogli testirati, instrukcijom FSTFW AX se oni smještaju u AX registar, a zatim instrukcijom SAHF prebacuju u F registar. Instrukcija SETE se mijenja zavisno od relacijskog operatora u '=': SETE AL '>': SETA AL '<': SETB AL '#': SETNE AL Zanimljivo je da instrukcija FSTFW AX pakuje flegove nepredznačeno, iako je u pitanju predznačeno poređenje. tako da izgleda kao da se FP operacije porede Pozovi Izraz Ako je prvi član cijeli broj ili karakter generiši PUSH EAX inače pozovi FPUStekNaStek Pozovi Izraz Ako je prvi član cijeli broj ili karakter generiši POP EBX Ako nijedan član nije realan broj, generiši kod kao i ranije, prema tablicama iz prethodnog poglavlja Ako je drugi član cijeli broj ili karakter a prvi član je bio realni broj pozovi CijeliNaFPStek za registar EAX Ako je prvi član cijeli broj ili karakter a drugi član je bio realni broj pozovi CijeliNaFPStek za registar EBX Ako je prvi član realni pozovi StekNaFPUStek Generiši FCOMPP Generiši FSTSW AX Generiši SAHF Generiši SETE AL Generiši AND EAX,0FFh Sl. 9.4.2. 9.5. Generisanje koda za poređenje dva realna broja Realne varijable Uvođenje dva nova tipa, realni i realni * , zahtijeva redefiniciju pojma ImeTipa : Ime tipa: cijeli realni karakter * * * Sl. 9.5.1. Ime tipa Čitanje sadržaja realne varijable se obavlja koristeći sljedeće dvije instrukcije, od kojih je jedna već poznata LEA EBX,adresa FLD QWORD PTR [EBX] 54 Međutim, kada je riječ o dodjeli vrijednosti varijabli instrukcija FLD sa lijeve strane operatora dodjeljivanja je ne samo nepotrebna, nego i štetna jer ostavlja na FP steku konstantu i tako ga prepunjava. Pošto se unaprijed ne zna da li slijedi znak dodjeljivanja, ovo se mora neutralisati instrukcijom FSTP ST(0). Stoga se dodjela vrijednosti, kada figurišu i realne varijable, obavlja kodom sa slike Sl. 9.5.2: Pozovi Izraz Prijavi grešku ako izraz nije dodjeljiv Generiši PUSH EBX Ako je prvi izraz realni broj generiši FSTP ST(0) Pozovi IzrazDodjeljivanja Generiši POP EBX Ako je drugi izraz cijeli broj ili karakter a prvi član je bio realni broj pozovi CijeliNaFPStek za registar EAX Ako je prvi izraz cijeli broj ili karakter a drugi član je bio realni broj pozovi FPStekUCijeli za registar EAX Ako je prvi izraz karakter generiši MOV [EBX],AL Sl. 9.5.2. Ako je prvi izraz realni broj generiši FSTP QWORD PTR [EBX] Sl. 9.5.3. Ako je prvi izraz cijeli broj generiši MOV [EBX],EAX Sl. 9.5.4. Sl. 9.5.5. 9.6. Generisanje koda za dodjeljivanje vrijednosti realnim promjenjivim Funkcije realnog argumenta i unarni operatori Analognim pravilima konverzije tipova se proširuje i poziv funkcije. Svaki realni parametar na steku zauzima po 8 bajtova i umjesto prostog generisanja PUSH EAX instrukcije (slučaj ostalih tipova), ovdje se poziva procedura FPUStekNaStek. Ako je na mjestu realnog parametra u pozivu proslijeđena cjelobrojna ili karakter varijabla, prije poziva procedure FPUStekNaStek treba pozvati CijeliNaFPStek sa parametrom EAX, što će konvertovati cijeli broj u realni. Ukoliko se realna vrijednost prosljeđuje cjelobrojnom parametru, treba pozvati FPStekUCijeli prije generisanja instrukcija PUSH EAX. Samo tri unarna operatora operatora imaju smisla u radu s realnim brojevima. To su -, & i *. Unarni minus treba da generiše instrukciju FCHS koja mijenja predznak broja na vrhu FP steka. Operator adrese pored promjene tipa, pored uobičajene MOV EAX,EBX instrukcije treba da uništi broj na vrhu FP steka koristeći FSTP ST(0) instrukciju. Operator vrijednosti na koju pointer pokazuje za tip realni * ,umjesto instrukcije MOV EAX,[EBX] , treba generisati instrukcije FSTP ST(0) i FLD QWORD PTR [EBX]. Za razliku od Fortran-a, Pascal-a i BASIC-a, transcendentne funkcije nisu sastavni dio ovog jezika. One se mogu prosto dodati u naknadno napisanim bibliotekama. Minorna izmjena je potrebna u Entry stub dijelu generisanog koda. Mašina koja se podrazumijeva je 486, umjesto 386, te je potrebno inicijalizirati koprocesor instrukcijom FINIT, i dodati pomoćnu lokaciju INTTOFP DD 0. Sada je moguće napisati šestu verziju kompajlera, koja je data u prilogu 6. 9.7. Testni primjer Primjer programa u šestoj verziji jezika je jedna od numeričkih metoda. Metodom ekstrapolacionom i interpolacionom režimu rada) se rješava jednačina sekante (koja radi u x − 2 = 0 . Kod ove metode naredna tačka se dobija formulom x k +1 = x k − f ( x k ) x k − x k −1 f ( x k ) − f ( x k −1 ) Funkcija čija se nula traži navodi se unutar tijela funkcije f. Treba primijetiti da je funkcija sqrt napisana kao asemblerski potprogram, jer je to sa ovim procesorom jednostavnije i brže od vlastite implementacije Heronovog algoritma. Funkcija Prikazidecimalnibroj prikazuje broj na 5 decimala, tako što već poznatom funkcijom Prikazibroj ispiše cijeli, a zatim razlomljeni dio izraza. Kompajliranje ovog primjera se vrši na uobičajeni način, s tim što mu je ime sekanta.jez. 55 cijeli funkcija GetStdHandle(cijeli brhan); cijeli funkcija WriteConsoleA(cijeli rez,cijeli * upisano, cijeli upisati,karakter * bafer,cijeli han); cijeli funkcija ReadConsoleA(cijeli rez,cijeli * upisano, cijeli upisati,karakter * bafer,cijeli han); cijeli * ime; cijeli funkcija Prikazistring (karakter * poruka){ cijeli handle,priv,duz; handle:=GetStdHandle(-11); duz:=0; dok (poruka[duz]#0) { duz:=duz+1;} WriteConsoleA(0,&priv,duz,poruka,handle); } cijeli funkcija Novired () { karakter * dvoznak; dvoznak:=" "; dvoznak[0]:=13; dvoznak[1]:=10; Prikazistring(dvoznak); } cijeli funkcija Prikazibroj (cijeli broj){ cijeli cifra,negativan,pokazivac,ostatak; karakter * bafer; bafer:=" "; ` Alociramo bafer cifra:=broj; ` Negativne brojeve oznaci indikatorom ako (cifra<0) { negativan:=1; cifra:=-cifra; } inace { negativan:=0; } `maksimalno 9 cifara pokazivac:=9; ako (cifra=0) { bafer[pokazivac]:='0'; pokazivac:=pokazivac-1; } dok (cifra>0) { ostatak:=(cifra % 10); `ostatke dijeljenja u bafer bafer[pokazivac]:=ostatak+'0'; cifra:=cifra/10; ` stalno dijeli s 10 pokazivac:=pokazivac-1; } ako (negativan=1) { bafer[pokazivac]:='-'; pokazivac:=pokazivac-1; } bafer:=&(bafer[pokazivac+1]); ` Pomjeri pokazivac pocetka stringa Prikazistring(bafer); } realni funkcija abs(realni x) { ako (x>0) { x;} inace {-x;} } Sl. 9.7.1. 9.8. realni funkcija sqrt(realni x) { asembler FLD QWORD PTR [EBP+8] FSQRT \ } cijeli funkcija Prikazidecimalnibroj(realni x) { cijeli c,nn,q; realni o; c:=x; o:=abs(x-c); Prikazibroj(c); Prikazistring("."); nn:=100000*o; q:=10; dok q<100000 { ako (nn<q) {Prikazistring("0");} q:=q*10; } Prikazibroj(nn); Novired(); } realni funkcija f(realni x) { sqrt(x)-2; } cijeli funkcija Racun() { realni x,predx,novix; cijeli i,q; i:=0; predx:=0; x:=1; dok ( (i<2000) & (abs(x-predx) >0.000001) ) { novix:=x-(f(x)*(x-predx))/(f(x)-f(predx)); predx:=x; x:=novix; Prikazidecimalnibroj(x); i:=i+1; } } { Racun(); } ---------------------------- Rezultat 2.00000 3.41421 4.08918 4.00341 4.00002 4.00000 4.00000 Primjer Metoda sekante Rezime poglavlja Zahvaljujući ugrađenom matematičkom koprocesoru dodavanje realne aritmetike je razmjerno jednostavno. Realne konstante se prosto prosljeđuju asembleru jer svi moderni asembleri poznaju eksponencijalnu sintaksu. Koprocesor radi na principu steka i potrebne su konverzione procedure između koprocesorskog steka i cjelobrojnih registara. 56 Prilog 6: Verzija izvornog koda kompajlera br. 6 program Kompajler; const MAXIDENT = 1024; MAXDIM = 10; DUGAKONST = 'Konstanta prevazilazi liniju'; REALKONST = 'Realna konstanta'; OCEKIVANO = 'Ocekivano '; REDEKLAR = 'Redeklarisan identifikator'; PROSTNIZ = 'Prosti tip ne moze biti niz'; NEKORARG = 'Nekorektan broj argumenata'; NEKDODJP = 'Losa dodjela pointeru'; NEDEKL = 'Nedeklarisano '; GRIZRAZ = 'Izraz'; POGRMNOZ = 'Pogresan tip u ' + 'mnozenju ili dijeljenju'; NEDOPFP = ' Nedopustena FP operacija'; NEDOPARIT = 'Nedopusteni tip u aritmetici'; OCEKDOD = 'Ocekivano dodjeljivanje'; NEDODJ = 'Izraz se ne moze dodijeliti'; DODJPOINT = 'Losa dodjela pointeru'; TIPUSL = 'Neodgovarajuci tip uslova'; TUSLPET = 'Neodgovarajuci uslov u petlji'; IMEFUN = 'Ocekivano ime funkcije'; DEFFUN = 'Definicija funkcije'; ARGNEKOM = 'Argument nekompatibilan' + ' s operatorom'; OCIDENT = 'Ocekivan Identifikator'; type TVrsta = (funkcija, lokalna, globalna, parametar); TTip = (karakter, cijeli, realni, pkarakter, pcijeli, prealni); TIdent = record ime: string[20]; duzina: integer; adresa: integer; nivo: integer; vrsta: TVrsta; tip: TTip; pod1: integer; pod2: integer; pod3: integer; end; var ulaz, izlaz: text; pozicija, trenlabela, brojaclinija, aktnivo: integer; znak: char; linija, realnakonstanta: string; TabIdent: array[0..MAXIDENT] of TIdent; ukupnoident: integer; t: TTip; dod: Boolean; procedure NoviIdent(pime: string; pduzina: integer; padresa: integer; pnivo: integer; pvrsta: TVrsta; ptip: TTip; ppod1: integer; ppod2: integer; ppod3: integer); begin ukupnoident := ukupnoident + 1; with TabIdent[ukupnoident] do begin ime := pime; duzina := pduzina; adresa := padresa; nivo := pnivo; vrsta := pvrsta; tip := ptip; pod1 := ppod1; pod2 := ppod2; pod3 := ppod3; end; end; procedure NovaLabela(var ImeLabele: string); begin trenlabela := trenlabela + 1; Str(trenlabela, ImeLabele); end; procedure Greska(poruka: string); begin WriteLn(poruka); WriteLn(brojaclinija, ':', linija); Close(ulaz); Close(izlaz); Halt; end; procedure Emit(st: string); begin WriteLn(izlaz, st); end; procedure Novi; begin repeat pozicija := pozicija + 1; if pozicija > Length(linija) then begin brojaclinija := brojaclinija + 1; if not (Eof(ulaz)) then ReadLn(ulaz, linija); Emit(';' + linija); pozicija := 1; end; if Length(linija) > 0 then znak := linija[pozicija] else znak := ' '; if (znak = '`') then pozicija := Length(linija); until ((znak > ' ') and (znak <> '`')) or Eof(ulaz) end; procedure NoviSvaki(greskakrln: Boolean); begin pozicija := pozicija + 1; if pozicija > Length(linija) then begin if greskakrln then Greska(DUGAKONST) else znak := ' '; end else znak := linija[pozicija]; end; procedure IdiDo(z: char); begin if (znak <> z) then Greska(OCEKIVANO + z); Novi; end; function UzmiKonstantu (var t: TTip; var dod: Boolean): integer; var rezultat: integer; begin rezultat := 0; realnakonstanta := ''; while (znak >= '0') and (znak <= '9') do begin rezultat := 10 * rezultat + ord(znak) - ord('0'); realnakonstanta := realnakonstanta + znak; NoviSvaki(false); end; if (znak = '.') or (znak = 'e') or (znak = 'E') then begin if znak = '.' then begin realnakonstanta := realnakonstanta + znak; NoviSvaki(false); while (znak >= '0') and (znak <= '9') do begin realnakonstanta := realnakonstanta + znak; NoviSvaki(false); end; end; if (znak = 'e') or (znak = 'E') then begin realnakonstanta := realnakonstanta + znak; NoviSvaki(false); if (znak = '+') or (znak = '-') then begin realnakonstanta := realnakonstanta + znak; NoviSvaki(false); end; if (znak < '0') or (znak > '9') then Greska(REALKONST); while (znak >= '0') and (znak <= '9') do begin realnakonstanta := realnakonstanta + znak; NoviSvaki(false); end; end; UzmiKonstantu := 0; t := realni; end else begin UzmiKonstantu := rezultat; t := cijeli; end; if (znak = ' ') or (znak = '`') then Novi; dod := false; end; function Slijedi(ocekivano: string; dslovoiza: Boolean): Boolean; var ureduiza: Boolean; n: integer; znak: char; begin if dslovoiza then ureduiza := true else begin n := pozicija + Length(ocekivano); ureduiza := true; if Length(linija) >= n then begin znak := linija[n]; if ((znak >= 'a') and (znak <= 'z')) or ((znak >= 'A') and (znak <= 'Z')) then ureduiza := false end end; if ureduiza and (copy(linija, pozicija, Length(ocekivano)) = ocekivano) then begin Slijedi := true; pozicija := pozicija + Length(ocekivano) - 1; end else Slijedi := false; end; function TipDek(imetipa: string; var tip: TTip; stip, ptip: TTip): Boolean; begin TipDek := false; if Slijedi(imetipa, false) then begin TipDek := true; Novi; if znak = '*' then begin tip := ptip; Novi end else tip := stip; end end; function SlijediDekTipa(var tip: TTip): Boolean; var a: Boolean; begin a := false; if not (a) then 57 a := TipDek('cijeli', tip, cijeli, pcijeli); if not (a) then a := TipDek('karakter', tip, karakter, pkarakter); if not (a) then a := TipDek('realni', tip, realni, prealni); SlijediDekTipa := a; end; function DuzinaTipa(tip: TTip): Integer; begin case tip of cijeli, pcijeli, pkarakter, prealni: DuzinaTipa := 4; karakter: DuzinaTipa := 1; realni: DuzinaTipa := 8; else DuzinaTipa := 4; end; end; function NadjiIdent(ident: string; nivo, tuslova, p1: integer): integer; var n, poz: integer; nadjen, Uslov: Boolean; begin n := ukupnoident; nadjen := false; poz := 0; while (n > 0) and (not (nadjen)) do begin case tuslova of 1: Uslov := (TabIdent[n].ime = ident) and (TabIdent[n].vrsta in [lokalna, globalna, parametar, funkcija]) and ((TabIdent[n].nivo = nivo) or (TabIdent[n].nivo = 0)); 2: Uslov := (TabIdent[n].ime = ident) and (TabIdent[n].vrsta in [lokalna, globalna, parametar, funkcija]) and ((TabIdent[n].nivo = nivo)); 4: Uslov := (TabIdent[n].nivo = nivo) and (TabIdent[n].pod2 = p1) and (TabIdent[n].vrsta = parametar) else Uslov := false; end; if Uslov then begin nadjen := true; poz := n; end; n := n - 1; end; NadjiIdent := poz; end; procedure UzmiIdent(var ident: string); begin if znak in ['a'..'z', 'A'..'Z'] then begin ident := znak; NoviSvaki(false); end else Greska(OCIDENT); while (znak in ['a'..'z', 'A'..'Z', '0'..'9', '_']) do begin ident := ident + znak; NoviSvaki(false); end; if (znak = ' ') or (znak = '`') then Novi; end; (var t: TTip; var dod: Boolean); forward; procedure Blok; forward; begin Emit(' ADD ESP,-8'); Emit(' FSTP QWORD PTR [ESP]'); end; procedure PokazivacINiz(var t: TTip; var procedure StekNaFPUStek; dod: Boolean); begin var Emit(' FLD QWORD PTR [ESP]'); t1: TTip; Emit(' ADD ESP,8'); begin end; Novi; Emit(' PUSH EAX'); procedure PozivFunkcije IzrazDodjeljivanja(t1, dod); (idpoz: integer; var t: TTip; var Emit(' POP EBX'); dod: Boolean); case t of var pkarakter: begin parametara, N, velsteka: integer; t := karakter; t1, t2: TTip; end; ImeFunkcije, st: string; pcijeli: begin begin Emit(' SAL EAX,2'); ImeFunkcije := TabIdent[idpoz].ime; t := cijeli; parametara := 0; end; prealni: begin velsteka := 0; Emit(' FSTP ST(0)'); IdiDo('('); Emit(' SAL EAX,3'); while (znak <> ')') do begin t := realni; IzrazDodjeljivanja(t1, dod); end; parametara := parametara + 1; n := NadjiIdent('', idpoz, 4, else parametara); Greska(PROSTNIZ) if n = 0 then end; Greska(NEKORARG); Emit(' ADD EBX,EAX'); t2 := TabIdent[n].tip; case t of if (t1 in [karakter, realni]) and karakter: (t2 in [pkarakter, pcijeli, Emit(' MOV AL,[EBX]'); prealni]) then realni: Greska(NEKDODJP); Emit(' FLD QWORD PTR [EBX]') if (t1 = karakter) and (t2 = cijeli) else then Emit(' MOV EAX,[EBX]'); Emit(' AND EAX,0FFh'); end; case t2 of IdiDo(']'); realni: begin dod := true; velsteka := velsteka + 8; end; case t1 of realni: ; procedure StringKonstanta(var t: TTip; karakter: var dod: Boolean); CijeliNaFPStek('EAX', var true); st, strtekst: string; else begin CijeliNaFPStek('EAX', NovaLabela(strtekst); false); Emit('.DATA'); end; st := 'L' + strtekst + ' DB '''; FPUStekNaStek; repeat end NoviSvaki(true); else begin if znak <> '"' then velsteka := velsteka + 4; st := st + znak; if t1 = realni then until znak = '"'; FPStekUCijeli('EAX'); IdiDo('"'); Emit(' PUSH EAX'); st := st + ''',0'; end; if copy(st, length(st) - 3, 2) = end; '''''' then if znak <> ')' then st := 'L' + strtekst + ' DB 0'; IdiDo(','); Emit(st); end; Emit('.CODE'); IdiDo(')'); Emit(' MOV EAX,OFFSET L' + strtekst); if TabIdent[idpoz].pod1 <> parametara t := pkarakter; then dod := false; Greska(NEKORARG); end; Str(velsteka, st); procedure CijeliNaFPStek(reg: string; Emit(' MOV ECX,' + st); osmobitni: Boolean); Emit(' CALL ' + ImeFunkcije + '@' + begin st); if osmobitni then dod := false; Emit(' AND ' + reg + ',0FFh'); t := TabIdent[idpoz].tip; Emit(' MOV INTTOFP,' + reg); if t = karakter then Emit(' AND EAX,0FFh0'); Emit(' FILD DWORD PTR INTTOFP'); end; end; procedure FPStekUCijeli(reg: string); begin Emit(' ADD ESP,-4'); Emit(' FISTP DWORD PTR [ESP]'); Emit(' POP ' + reg); end; procedure DeklIdent(var ident: string; nivo: integer); begin UzmiIdent(ident); if NadjiIdent(ident, nivo, 2, 0) <> 0 then Greska(REDEKLAR); end; procedure CPUStekCijeliNaFPStek(osmobitni: Boolean); begin if osmobitni then Emit(' AND DWORD PTR [ESP],0FFh'); Emit(' FILD DWORD PTR [ESP]'); Emit(' ADD ESP,4'); end; procedure IzrazDodjeljivanja procedure FPUStekNaStek; procedure Varijabla (idpoz: integer; var t: TTip; var dod: Boolean; glob: Boolean); var rezultat: integer; st: string; begin rezultat := TabIdent[idpoz].adresa; t := TabIdent[idpoz].tip; Str(rezultat, st); if glob then Emit(' LEA EBX,GLOBALV[' + st + ']') else begin if rezultat >= 0 then Emit(' LEA EBX,[EBP+' + st + ']') else Emit(' LEA EBX,[EBP' + st + ']'); end; 58 case t of karakter: Emit(' MOV AL,[EBX]'); realni: Emit(' FLD QWORD PTR [EBX]'); cijeli: Emit(' MOV EAX,[EBX]'); else Emit(' MOV EAX,[EBX]'); end; dod := true; if znak = '[' then PokazivacINiz(t, dod); end; procedure Faktor(var t: TTip; var dod: Boolean); var rezultat, poz: integer; st, fpkonst, ime, err: string; begin err := ARGNEKOM; case znak of '-': begin Novi; Faktor(t, dod); case t of cijeli: Emit(' NEG EAX'); realni: Emit(' FCHS'); else Greska(err); end; dod := false; end; '~': begin Novi; Faktor(t, dod); case t of cijeli: Emit(' NOT EAX'); karakter: Emit(' NOT AL'); else Greska(err); end; dod := false; end; '&': begin Novi; Faktor(t, dod); Emit(' MOV EAX,EBX'); case t of cijeli: t := pcijeli; karakter: t := pkarakter; realni: begin t := prealni; Emit(' FSTP ST(0)'); end; else t := pcijeli; end; dod := false; end; '*': begin Novi; Faktor(t, dod); Emit(' MOV EBX,EAX'); if t = prealni then begin Emit(' FSTP ST(0)'); Emit(' FLD QWORD PTR [EBX]'); end else Emit(' MOV EAX,[EBX]'); case t of pcijeli: t := cijeli; pkarakter: begin t := karakter; Emit(' AND EAX,0FFh'); end; prealni: t := realni; else Greska(err); end; dod := true; end; '!': begin Novi; Faktor(t, dod); case t of cijeli: Emit(' CMP EAX,0'); karakter: Emit(' CMP AL,0'); else Greska(err); end; Emit(' SETE AL'); Emit(' AND EAX,0FFh'); dod := false; t := cijeli; end; '"': begin StringKonstanta(t, dod); end; '''': begin NoviSvaki(true); Emit(' MOV AL,''' + znak + ''''); Novi; IdiDo(''''); t := karakter; end; '0'..'9': begin rezultat := UzmiKonstantu(t, dod); case t of cijeli: begin Str(rezultat, st); Emit(' MOV EAX,' + st); end; realni: begin NovaLabela(fpkonst); Emit('.DATA'); st := 'L' + fpkonst + ' DQ '+ realnakonstanta; Emit(st); Emit('.CODE'); Emit(' FLD L' + fpkonst); end; end; end; '(': begin Novi; IzrazDodjeljivanja(t, dod); IdiDo(')'); end; 'A'..'Z', 'a'..'z': begin UzmiIdent(ime); poz := NadjiIdent(ime, aktnivo, 1, 0); if poz = 0 then Greska(NEDEKL + ime); case TabIdent[poz].vrsta of funkcija: PozivFunkcije(poz, t, dod); lokalna, parametar: Varijabla(poz, t, dod, false); globalna: Varijabla(poz, t, dod, true) end end; else Greska(GRIZRAZ); end; end; procedure Clan(var t: TTip; var dod: Boolean); var z: char; t1, t2: TTip; begin Faktor(t1, dod); t := t1; while (znak in ['*', '/', '%']) do begin z := znak; if t1 <> realni then Emit(' PUSH EAX') else FPUStekNaStek; Novi; Faktor(t2, dod); dod := false; if (not (t1 in [cijeli, karakter, realni])) or (not (t2 in [cijeli, karakter, realni])) then Greska(POGRMNOZ); if (t1 = realni) or (t2 = realni) then begin t := realni; if t2 <> realni then CijeliNaFPStek('EAX', t2 = karakter); if t1 <> realni then CPUStekCijeliNaFPStek(t1 = karakter) else StekNaFPUStek; case z of '*': Emit(' FMUL '); '/': Emit(' FDIVR '); else Greska(NEDOPFP); end end else begin t := cijeli; case z of '*': begin Emit(' POP EBX'); if t1 = karakter then Emit(' AND EBX,0FFh'); if t2 = karakter then Emit(' AND EAX,0FFh'); Emit(' IMUL EBX'); end; '/', '%': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); Emit(' CDQ'); if t1 = karakter then Emit(' AND EAX,0FFh'); if t2 = karakter then Emit(' AND EBX,0FFh'); Emit(' IDIV EBX'); if z = '%' then Emit(' MOV EAX,EDX'); end; end; end; t1 := t; end; end; procedure Izraz(var t: TTip; var dod: Boolean); var z: char; t1, t2: TTip; begin Clan(t1, dod); t := t1; while (znak in ['+', '-', '&', '|', '^']) do begin if t1 <> realni then Emit(' PUSH EAX') else FPUStekNaStek; z := znak; Novi; Clan(t2, dod); dod := false; if (not (t1 in [cijeli, karakter, realni])) or (not (t2 in [cijeli, karakter, realni])) then Greska(NEDOPARIT); if (t1 = realni) or (t2 = realni) then begin t := realni; if t2 <> realni then CijeliNaFPStek('EAX', t2 = karakter); if t1 <> realni then CPUStekCijeliNaFPStek(t1 = karakter) else StekNaFPUStek; case z of '+': Emit(' FADD '); '-': Emit(' FSUBR '); else Greska(NEDOPFP); end end else begin case z of '+': begin Emit(' POP EBX'); if (t1 = karakter) and (t2 = karakter) then begin t := karakter; Emit(' ADD AL,BL'); end else begin t := cijeli; if t1 = karakter then Emit(' AND EBX,0FFh'); if t2 = karakter then Emit(' AND EAX,0FFh'); Emit(' ADD EAX,EBX'); end; end; '-': begin Emit(' MOV EBX,EAX'); 59 Emit(' POP EAX'); if (t1 = karakter) and (t2 = karakter) then begin t := karakter; Emit(' SUB AL,BL'); end else begin t := cijeli; if t1 = karakter then Emit(' AND EAX,0FFh'); if t2 = karakter then Emit(' AND EBX,0FFh'); Emit(' SUB EAX,EBX'); end; end; '&', '|', '^': begin if (t1 = karakter) and (t2 = karakter) then t := karakter else t := cijeli; Emit(' POP EBX'); case z of '&': Emit(' AND EAX,EBX'); '|': Emit(' OR EAX,EBX'); '^': Emit(' XOR EAX,EBX'); end; end; end; end; t1 := t; end; end; procedure IzrazDodjeljivanja (var t: TTip; var dod: Boolean); var z: char; t1, t2: TTip; dod1: Boolean; begin Izraz(t1, dod1); t := t1; dod := dod1; case znak of ':': begin if not (Slijedi(':=', true)) then Greska(OCEKDOD); if not (dod1) then Greska(NEDODJ); Emit(' PUSH EBX'); if (t1 = realni) then Emit(' FSTP ST(0)'); Novi; IzrazDodjeljivanja(t2, dod); Emit(' POP EBX'); if (t2 in [karakter, realni]) and (t1 in [pkarakter, pcijeli, prealni]) then Greska(NEKDODJP); if (t1 = realni) and (t2 <> realni) then CijeliNaFPStek('EAX', t2 = karakter); if (t1 <> realni) and (t2 = realni) then FPStekUCijeli('EAX'); case t1 of karakter: Emit(' MOV [EBX],AL'); realni: Emit(' FSTP QWORD PTR [EBX]'); else Emit(' MOV [EBX],EAX'); end; t := t1; end; {:} '=', '>', '<', '#': begin if t1 <> realni then Emit(' PUSH EAX') else FPUStekNaStek; z := znak; Novi; Izraz(t2, dod); if t1 <> realni then Emit(' POP EBX'); if (t1 = realni) or (t2 = realni) then begin if t2 <> realni then CijeliNaFPStek('EAX', t2 = karakter); if t1 <> realni then CijeliNaFPStek('EBX', t1 = karakter) else StekNaFPUStek; Emit(' FCOMPP '); Emit(' FSTSW AX'); Emit(' SAHF'); case z of '=': Emit(' SETE AL'); '>': Emit(' SETA AL'); '<': Emit(' SETB AL'); '#': Emit(' SETNE AL'); end; Emit(' AND EAX,0FFh'); t := cijeli; end else begin if (t1 = karakter) and (t2 = karakter) then Emit(' CMP BL,AL') else begin if t1 = karakter then Emit(' AND EAX,0FFh'); if t2 = karakter then Emit(' AND EBX,0FFh'); Emit(' CMP EBX,EAX'); end; case z of '=': Emit(' SETE AL'); '>': Emit(' SETG AL'); '<': Emit(' SETL AL'); '#': Emit(' SETNE AL'); end; Emit(' AND EAX,0FFh'); t := cijeli; end; end end; end; procedure Uslov; var sonda, sinace, skrajuslova: string; begin Novi; IzrazDodjeljivanja(t, dod); if t <> cijeli then Greska(TIPUSL); Emit(' CMP EAX,0'); NovaLabela(sonda); NovaLabela(sinace); NovaLabela(skrajuslova); Emit(' JNE L' + sonda); Emit(' JMP L' + sinace); IdiDo('{'); Emit('L' + sonda + ':'); Blok; Emit(' JMP L' + skrajuslova); Emit('L' + sinace + ':'); if Slijedi('inace', false) then begin Novi; IdiDo('{'); Blok; end; Emit('L' + skrajuslova + ':'); end; procedure Asembler; begin repeat ReadLn(ulaz, linija); if linija <> '\' then Emit(linija); if eof(ulaz) then linija := '\'; until linija[1] = '\'; pozicija := 1; znak := linija[pozicija]; IdiDo('\'); end; procedure Petlja; var sdok, skrajpetlje, suslov: string; begin Novi; NovaLabela(suslov); Emit('L' + suslov + ':'); IzrazDodjeljivanja(t, dod); if t <> cijeli then Greska(TUSLPET); Emit(' CMP EAX,0'); NovaLabela(sdok); NovaLabela(skrajpetlje); Emit(' JNE L' + sdok); Emit(' JMP L' + skrajpetlje); IdiDo('{'); Emit('L' + sdok + ':'); Blok; Emit(' JMP L' + suslov); Emit('L' + skrajpetlje + ':'); end; procedure Blok; begin while znak <> '}' do begin if Slijedi('dok', false) then Petlja else if Slijedi('ako', false) then Uslov else if Slijedi('asembler', false) then Asembler else begin IzrazDodjeljivanja(t, dod); IdiDo(';'); end; end; IdiDo('}'); end; procedure DefFunkcija(ftip: TTip); var parametara, paradresa, lokadresa, pfunkc, i: integer; ImeFunkcije, imeparametra, imevarijable, st: string; tip: TTip; imaistogtipa: Boolean; begin if not (((znak >= 'a') and (znak <= 'z')) or ((znak >= 'A') and (znak <= 'Z'))) then Greska(IMEFUN); DeklIdent(ImeFunkcije, 0); NoviIdent(ImeFunkcije, 4, 0, 0, funkcija, ftip, 0, 0, 0); pfunkc := ukupnoident; aktnivo := pfunkc; IdiDo('('); parametara := 0; lokadresa := 0; paradresa := 0; while znak <> ')' do begin if SlijediDekTipa(tip) then begin DeklIdent(ImeParametra, pfunkc); parametara := parametara + 1; paradresa := paradresa + ((DuzinaTipa(tip) - 1) div 4 + 1) * 4; NoviIdent(ImeParametra, DuzinaTipa(tip), paradresa, pfunkc, parametar, tip, pfunkc, parametara, 0); end; if znak <> ')' then IdiDo(','); end; IdiDo(')'); for i := ukupnoident downto 0 do if (TabIdent[i].nivo = pfunkc) and (TabIdent[i].vrsta = parametar) then TabIdent[i].adresa := paradresa + 8 - TabIdent[i].adresa; TabIdent[pfunkc].pod1 := parametara; case znak of '{': begin IdiDo('{'); while SlijediDekTipa(tip) do begin repeat DeklIdent(ImeVarijable, pfunkc); lokadresa := lokadresa + DuzinaTipa(tip); NoviIdent(ImeVarijable, DuzinaTipa(tip), -lokadresa, pfunkc, lokalna, tip, pfunkc, parametara, 0); 60 imaistogtipa := true; if znak = ',' then begin Novi; imaistogtipa := false; end; until imaistogtipa; while (lokadresa mod 4) <> 0 do lokadresa := lokadresa + 1; IdiDo(';'); end; Str(paradresa, st); Emit(ImeFunkcije + '@' + st + ':'); Emit(' PUSH EBP'); Emit(' MOV EBP,ESP'); Str(lokadresa, st); Emit(' SUB ESP,' + st); Blok; Emit(' MOV ESP,EBP'); Emit(' POP EBP'); Str(paradresa, st); Emit(' RET ' + st); Emit('PUBLIC ' + ImeFunkcije + '@' + st); end; ';': begin Str(paradresa, st); Emit('extrn ' + ImeFunkcije + '@' + st + ':near'); IdiDo(';'); end else Greska(DEFFUN); end; aktnivo := 0; end; procedure Prevedi; var globadresa: Integer; ImeVarijable, st: string; tip: TTip; imaistogtipa: Boolean; begin Emit('.486'); Emit('.MODEL FLAT,STDCALL'); Emit('OPTION CASEMAP:NONE'); Emit('EXTRN ExitProcess@4:NEAR'); Emit('.CODE'); Emit('ULAZ:'); Emit(' FINIT'); Emit(' JMP GLAVNI'); pozicija := 0; globadresa := 0; Novi; while SlijediDekTipa(tip) do begin if Slijedi('funkcija', false) then begin Novi; DefFunkcija(tip); end else begin repeat DeklIdent(ImeVarijable, 0); NoviIdent(ImeVarijable, DuzinaTipa(tip), globadresa, 0, globalna, tip, 0, 0, 0); globadresa := globadresa + DuzinaTipa(tip); imaistogtipa := true; if znak = ',' then begin Novi; imaistogtipa := false; end; until imaistogtipa; while (globadresa mod 4) <> 0 do globadresa := globadresa + 1; IdiDo(';'); end end; IdiDo('{'); if znak <> '}' then begin Emit('GLAVNI:'); Blok; Emit(' PUSH 0'); Emit(' CALL ExitProcess@4'); Emit('.DATA'); Str(globadresa, st); Emit('GLOBALV DB ' + st + ' DUP(0)'); Emit('INTTOFP DD 0'); Emit('END ULAZ') end else begin Emit('GLAVNI:'); Emit('END'); end; end; procedure Glavni; var linija: string; begin trenlabela := 0; ukupnoident := 0; aktnivo := 0; Assign(ulaz, paramstr(1)); Assign(izlaz, paramstr(2)); brojaclinija := 0; linija := ''; Reset(ulaz); Rewrite(izlaz); Prevedi; Close(ulaz); Close(izlaz); WriteLn('Prevedeno bez greske'); end; begin Glavni end. 61 10. SLOŽENI TIPOVI PODATAKA Dosadašnje smještanje nizova, definisanih preko pointera, u statički navedene stringove prilično ograničava veličinu koju niz može da ima. Iako se taj problem može prevazići primjenom API funkcije GlobalAlloc, i dalje se osjeća nedostatak definisanih nizova određene veličine u samom programskom jeziku. Pored ovoga, treba uvesti i višedimenzionalne nizove. Drugi složeni tip koji treba uvesti su slogovi (strukture u C-u), tj. skup podataka različitog tipa pod istim imenom. Konačno, da bi bilo moguće praviti Windows aplikacije koje rade u grafičkom okruženju, neophodno je i uvesti pointere na funkcije ili neki drugi način da se funkcija može pozvati, iako se u trenutku kompajliranja ne zna o kojoj je funkciji riječ. Kombinovano sa slogovima, to je i korak ka jeziku koji omogućava objektno orijentisano programiranje. 10.1. Višedimenzionalni nizovi Deklarisanje višedimenzionalnih nizova se vrši navođenjem broja elemenata svake dimenzije iza oznake tipa, pri čemu je donji indeks nizova uvijek 0. Npr., cijeli [2,3] a; će rezervisati prostor za cijele brojeve a[0,0] a[0,1] a[0,2] a[1,0] a[1,1] i a[1,2] . Jedan ili više pozitivnih cijelih brojeva razdvojenih zarezima unutar uglastih zagrada naziva se deklaracioni dimenzijski modifikator. Jedan ili više numeričkih izraza razdvojenih zarezima unutar uglastih zagrada naziva se lista indeksa. Sintaksno se mogu predstaviti kao na slici Sl. 10.1.1 Deklaracioni dimenzijski modifikator [ Lista indeksa [ Konstanta ] Izraz dodjeljivan ja ] , , Sl. 10.1.1. Deklaracioni dimenzijski modifikator i lista indeksa Adresa početka elementa jednodimenzionalnog niza se dobija formulom AdresaElementa=AdresaPočetkaNiza+Index*VeličinaElementaNiza Za dvodimenzionalne nizove ova formula iznosi AdresaElementa=AdresaPočetkaNiza+(BrojElemenataDrugeDimenzije*IndexPrveDimenzije+IndexDrugeDimenzije) *VeličinaElementaNiza Za trodimenzionalne nizove ova formula iznosi AdresaElementa=AdresaPočetkaNiza+(BrojElemenataDrugeDimenzije*BrojElemenataTrećeDimenzije*IndexPrveDi menzije+ BrojElemenataTrećeDimenzije*IndexDrugeDimenzije+IndexTrećeDimenzije)*VeličinaElementaNiza Formula se može generalizovati AdresaElementa=AdresaPočetkaNiza+(Indexn+∑((i=1,n-1,Indexi)*∏(j=i+1,n,BrojElemenataj)))VeličinaElementa ili generisati kodom sa slike Sl. 10.1.2, (koji će svoje mjesto naći u proceduri PokazivacINiz ) uz pretpostavku da registar EBX sadrži adresu početka niza Generiši MOV EAX,0 Povećaj brojač dimenzija Generisi PUSH EAX Pozovi IzrazDodjeljivanja Generisi POP EBX Ako nije zadnji indeks generiši MOV DX,ProizvodBrojElemenataNarednihDimenzija i generiši MUL EDX Generiši ADD EBX,EAX Generiši MOV EAX,EBX Generiši množenje EAX sa veličinom elementa Sl. 10.1.2. Pseudokod i generisanje mašinskog koda za račun elementa višedimenzionalnog niza 62 Preuzima se koncept iz C-a da su nizovi i pointeri kompatibilni kada se prenose kao parametri, pri čemu se nizu ne može dodijeliti vrijednost, iako je sintaksa višedimenzionalnih nizova drugačija. Za niz se alocira onoliko bajtova koliki je proizvod svih dimenzija pomnožen sa veličinom pojedinačnog argumenta, a za pointer četiri bajta. Da bi se znalo koliko prostora treba alocirati, u slog tabele TabIdent dodaje se broj dimenzija niza i broj elemenata u svakoj dimenziji. Ovaj sadržaj se kopira u globalni niz dimenzije i varijablu ukdim po potrebi. Shodno ovom proširuje se procedura DuzinaTipa. U dosadašnjim verzijama kompajlera iza imena varijable mogao je biti opcionalni indeks niza. Sada, kada se dodaju višedimenzionalni nizovi, slogovi i indirektni pozivi funkcija, jezički pojam varijabla izgleda kao na slici Sl. 10.1.3. Varijabla: ( Izraz dodjeljivanja ) , Identifikator [ Lista indeksa Sl. 10.1.3. Varijabla Male zagrade iza imena varijable omogućavaju indirektni poziv funkcije. 10.2. Indirektni poziv funkcije Pointerskoj varijabli moguće je dodijeliti ime funkcije, čime ona pokazuje na potprogram. Kada se iza pointerske varijable stave zagrade, tada će se generisati poziv potprograma takav da adresa na koju se skače nije konstantna, nego se čita s druge adrese. Kôd koji se generiše koristeći novu proceduru IndirektniPoziv izgleda kao na slici Sl. 10.2.1. Generiši labelu i lokaciju na kojoj se smješta duga riječ, npr L15 DD (?) Generiši MOV L15,EAX Za svaki izraz do zatvorene zagrade pozovi IzrazDodjeljivanja i odgovarajuće smještanje podataka na stek Generiši MOV ECX,velicinasteka Generiši indirektni poziv CALL L15 Sl. 10.2.1. Generisanje koda za indirektni poziv funkcije Procedura IndirektniPoziv je jako slična proceduri PozivFunkcije, osim što ne provjerava tip i broj argumenata prilikom generisanja poziva funkcije. Dosadašnja funkcija PozivFunkcije uključuje i varijantu kada iza imena funkcije ne slijede zagrade. Tada se u EAX registru vraća adresa početka funkcije. Tip rezultata koji vraćaju indirektno pozvane funkcije je dereferencirani tip varijable u kojoj se nalazi adresa funkcije. Na primjer, ako je varijabli koja je pokazivač na realni broj dodijeljena adresa funkcije, ova funkcija će vratiti realni broj. Indirektni pozivi funkcija su moćan mehanizam koji treba koristiti sa velikim oprezom pošto mala greška može lako da dovede do kraha programa. Iako se argumenti ne provjeravaju prilikom indirektnog poziva, funkcije normalno prihvaćaju samo onaj broj i tip argumenata koliko ih ima u deklaraciji. Ukoliko je funkcija pozvana sa drugačijim brojem argumenata od očekivanog, stek pointer neće biti u ispravnom položaju i to će izazvati krah. S druge strane, kako ECX registar u trenutku poziva funkcije sadrži veličinu memorije koju su zauzeli argumenti, uz pomoć asemblerskih modula moguće je praviti funkcije sa promjenjivim brojem argumenata. Indirektni tip poziva omogućava uzajamnu rekurziju, tj. da funkcija P poziva funkciju Q, a funkcija Q da poziva funkciju P. To se postiže tako da se prije definicije funkcija definišu dvije pointerske varijable, unutar samih funkcija poziv 63 uzajamno rekurzivnih vrši koristeći indirektni poziv, a dodjela adresa funkcija pointerskim varijablama obavi na početku glavnog programa. 10.3. Slogovi Slogovi se definišu rekurzivno, jer član sloga može biti novi slog, kao i niz, odnosno matrica, a također su mogući nizovi slogova. U mnogim programskim jezicima svaka slogovska struktura predstavlja poseban tip. Kako jezik FILDZAN-32 nema korisničkih tipova, sve varijable koje predstavljaju slogove su tipa slog, a kao numerička oznaka pojedine slogovske strukture koristi se polje pod3 u tabeli identifikatora. Dodavanje tipa slog zahtijeva izmjenu jezičkog pojma ImeTipa, što je prikazano na slici uz odgovarajuće promjene funkcija TipDek i SlijediDekTipa. Dio koda iz procedure Varijabla , koji generiše kôd za čitanje sadržaja pointerskih varijabli prebačen je u proceduru PEmit da se izbjegne njegovo dupliranje nakon uvođenja pointera na slogove. ImeTipa: slog cijeli * Deklaracioni dimenzijski modifikator realni * Deklaracioni dimenzijski modifikator karakter * Deklaracioni dimenzijski modifikator Deklaracioni dimenzijski modifikator * Sl. 10.3.1. Deklaracija sloga Jezički pojam ImeTipa Jezički pojam Deklaracija sloga, implementiran u proceduri DeklaracijaSloga izgleda kao na slici Sl. 10.3.2. { Identifikator imena polja ImeTipa } , ; Sl. 10.3.2. Deklaracija sloga Primjer: slog { cijeli x1,y1; cijeli x2,y2; karakter[80] poruka; } texbox; Implementacija deklaracije sloga, prikazana na slici Sl. 10.3.3 u osnovi dodaje u tabelu identifikatora za svako polje u slogu novi identifikator pri čemu se za vrstu identifikatora navodi polje. Dodatni podaci koji se navode u tabeli slogova su oznaka sloga, oznaka podsloga i relativna pozicija polja u bajtima od početka sloga. 64 Povećaj ukupni broj slogova za jedan i postavi dužinu sloga na nulu. Za svaki tip koji se pojavljuje u deklaraciji sloga (*) Ako je tip slog ili pointer na slog, podslog se dobija rekurzivnim pozivom deklaracije sloga, a za proste tipove podslog je sam slog. Preuzmi ime identifikatora polja. Potraži da li već postoji takav identifikator u tablici identifikatora za taj nivo i tu oznaku sloga i ako ima prijavi grešku. Upiši ime polja u tablicu identifikatora zajedno sa oznakom podsloga i samog sloga, te trenutnom duzinom sloga. Uvećaj dužinu sloga za dužinu tipa Sve dok slijedi znak ‘,’ vrati se na tačku (*) Dužinu sloga poravnaj na vrijednost djeljivu sa 4. Očekuj simbol ‘;’ Ako nema više tipova, očekuj simbol ‘}’. Sl. 10.3.3. Aktivnosti pri deklarisanju sloga, pseudokod Cijeli slog (tj. varijabla slogovnog tipa) ima svoju poziciju u tabeli identifikatora, u koju se upisuje prilikom deklaracije varijable ili parametara funkcije. OznakaSloga nije ta pozicija, nego redni broj deklarisanog sloga koji se svaki put kada započne deklarisanje novog sloga ili podsloga, uvećava za jedan. Varijabla zadnji čuva podatke o zadnjem definisanom ili upotrijebljenom slogu. Ti podaci su njegova dužina, redni broj sloga po redoslijedu deklarisanja i pozicija u tabeli identifikatora gdje se nalazi njegovo ime. Pomoću varijable zadnji prevaziđen je problem različite strukture različitih slogova. Procedura DuzinaTipa će za slogove vratiti dužinu zadnjeg definisanog ili upotrijebljenog sloga. U proceduri varijabla se provjeri da li je u pitanju niz/matrica slogova. Ako jeste, dužina tipa se dijeli sa ukupnim brojem elemenata. Pretraživač identifikatora NadjiIdent treba da traži poziciju polja u tabeli identifikatora. Do sada rezervisani, tip pretraživanja 3 će obaviti ovaj zadatak. Nad slogovima je dopušteno od operacija samo dodjeljivanje čitavog sloga drugom slogu. Kako konkretna slogovna struktura nema imena uzeta je konvencija da se slog može dodijeliti drugom slogu samo ako su jednake dužine. Dodjela sloga slogu ili stavljanje sloga na stek se vrši naredbom REP MOVSB. Prije ove naredbe, ESI treba da pokazuje na izvorni slog, EDI na odredišni ili mjesto na vrhu steka, ECX na dužinu sloga, a direction flag treba biti jednak 0. Na slici Sl. 10.3.4 dat je generisani kôd za smještanje sloga na stek i dodjeljivanje jedne slogovne varijable drugoj. MOV SUB MOV MOV CLD REP ECX,duzinasloga ESP,duzinasloga ESI,EBX EDI,ESP PUSH EBX Izraz dodjeljivanja POP EDI MOV ESI,EBX CLD MOV ECX,duzina sloga REP MOVSB MOVSB Smještanje sloga na stek Sl. 10.3.4. Dodjeljivanje slogovnih varijabli Generisanje koda za operacije sa kompletnim slogovima Implementacija elementa sloga, tj. adrese i vrijednosti polja, navedena u proceduri ElementSloga je slična implementaciji varijabli, osim što se nakon dobijanja adrese varijable (cijelog sloga) u EBX registru, generiše instrukcija ADD EBX,pozicijapolja, kako bi registar EBX pokazivao na početak samog polja. Realizacija elementa sloga zahtijeva izmjenu jezičkog pojma Faktor Sl. 10.3.5. Na kraj ovog jezičkog pojma se dodaje pojam ElementSloga ukoliko se na kraju pojma Faktor nalazi simbol “.”. Napomena: Ovo je izmijenjeno u odnosu na prethodno izdanje skripte (gdje je element sloga bio iza varijable) kako bi se moglo pristupiti elementu sloga na koji pokazuje pointer. 65 ~ & Faktor * ! . Numerička konstanta ( Izraz dodjeljivanja Element sloga ) Varijabla String " Poziv funkcije ‘ Slovo Sl. 10.3.5. ‘ Jezički pojam Faktor Kako element sloga može takođe biti slog, jezički pojam ElementSloga treba da ponavlja generisanje adresa za pristup podpoljima i njegova struktura izgleda kao na slici Sl. 10.3.6 Identifikator imena polja . Sl. 10.3.6. Jezički pojam ElementSloga 66 10.4. Testni primjer Primjer programa u ovoj verziji jezika je jedna jednostavna Windows GUI aplikacija. Program generiše osnovni prozor na kome se nalaze tri dugmeta, od kojih pritisak na jedno aktivira poruku na ekranu, drugo pokreće aplikaciju Solitaire, a treće crta jedan krug na ekranu. Počevši od treće verzije jezika svi dosadašnji primjeri su bile Windows konzolne aplikacije, tj. aplikacije koje koriste tekstualni korisnički interfejs i nemaju reakcija na asinhrone događaje kao što je pritisak na miša ili preklapanje između prozora/procesa. Windows GUI aplikacije, s druge strane, primaju poruke u red čekanja i odgovaraju na njih. To se obično vrši primjenom GetMessage i DispatchMessage API funkcija koje čitaju poruku i pozivaju odgovarajući potprogram da se poruka obradi. Potprogram za obradu poruke (koja je zapravo jedan slog), je definisan u opisu tzv. klase prozora, u njenom polju lpfnWndProc. Klasa prozora predstavlja slog koji se ili popunjava pri startu programa ili uzima već gotov (kao što je “BUTTON”). Tu klasu navodimo prilikom kreiranja prozora, kao jedan od parametara funkcije CreateWindow. Glavni prozor odgovara na tri vrste poruka, otvaranje programa (kada kreira podprozore koji su zapravo dugmad), zatvaranje prozora (kada šalje poruku koja završava GetMessage/DispatchMessage petlju) i komandu (kada zavisno od podprozora koji ju je poslao poziva funkciju MessageBox za ispis poruke, WinExec za start programa ili Ellipse za prikaz elipse čiji je specijalni slučaj krug). Prozori se međusobno identifikuju konstantom koja se zove rukovatelj prozora (handle). Pored toga, prikaz elipse zahtijeva konstantu device context kao jedan od parametara, koji se uzima funkcijom GetDC. Detaljniji opis ovoga primjera oduzeo bi dosta prostora. O načinu programiranja za Windows pogledati u referenci [PETZOLD-01]. Program se prevodi sa: komp32v7 wincircle.jez wincircle.asm ml /c /coff /Fl wincircle.asm | more link /defaultlib: user32.lib kernel32.lib gdi32.lib /subsystem:windows wincircle.obj Činjenica da ovaj primjer radi, pokazuje da je jezik već dovoljno moćan da se u njemu, uz dosta truda, realizuje bilo koja aplikacija koja koristi standardni Windows API . Interesantno je da je prevedeni EXE kôd dosta kratak, svega 4608 bajtova, iako još nije implementirana optimizacija koda. U većini drugih programskih jezika, sem asemblera, ovaj primjer bi imao veći prevedeni kôd: od 12 kilobajta (Delphi u Object Pascal režimu) do nekoliko megabajta (neki vizuelni alati koji zahtijevaju veliki runtime, npr. Oracle Forms) 67 cijeli funkcija RegisterClassExA(cijeli * wndclass); cijeli funkcija ShowWindow ( cijeli a,cijeli b) ; cijeli funkcija UpdateWindow(cijeli hWnd) ; cijeli funkcija GetMessageA (cijeli a, cijeli b, cijeli c,cijeli * d); cijeli funkcija TranslateMessage (cijeli * d) ; cijeli funkcija DispatchMessageA (cijeli * d) ; cijeli funkcija CreateWindowExA(cijeli a,cijeli b,cijeli c, cijeli d,cijeli e,cijeli f, cijeli g,cijeli h,cijeli i, karakter * j,karakter * k,cijeli l); cijeli funkcija LoadCursorA ( cijeli a,cijeli b) ; cijeli funkcija GetStockObject ( cijeli a) ; cijeli funkcija PostQuitMessage ( cijeli a) ; cijeli funkcija DefWindowProcA (cijeli a, cijeli b, cijeli c,cijeli d); cijeli funkcija MessageBoxA (cijeli a, karakter * b, karakter * c,cijeli d); cijeli funkcija WinExec (karakter * b, karakter * c); cijeli funkcija GetModuleHandleA ( cijeli a) ; cijeli funkcija GetDC ( cijeli a) ; cijeli funkcija Ellipse (cijeli a, cijeli b, cijeli c,cijeli d,cijeli e); cijeli funkcija ReleaseDC (cijeli a, cijeli b); cijeli hWnd ; cijeli ka,kb,kc; slog { cijeli hwnd; cijeli message; cijeli wParam; cijeli lParam; cijeli time; slog { cijeli x; cijeli y; } pt; } msg ; ` a message structure 40,120,60,140, WSCHILD | WSVISIBLE,"Soliter","BUTTON",0); kc:=CreateWindowExA (0,hInstance,0,hWnd, 40,120,100,140, WSCHILD | WSVISIBLE,"Krug","BUTTON",0); obradjena:=1; } ako (wMessage=2) `WM_DESTROY { PostQuitMessage (0) ; obradjena:=1; } ako (wMessage=273) `WM_COMMAND { ako (lParam=ka) { MessageBoxA (0,"Poruka","Pritisnut taster",0); } ako (lParam=kb) { WinExec (" ","c:\windows\sol.exe"); } ako (lParam=kc) { hDC:=GetDC (hWnd); Ellipse(200,200,0,0,hDC); ReleaseDC(hDC,hWnd); } obradjena:=1; } ako (obradjena=0) { DefWindowProcA (lParam,wParam,wMessage,hWnd) ; } } { slog { cijeli cbsize; cijeli style; cijeli * lpfnWndProc; cijeli cbClsExtra; cijeli cbWndExtra; cijeli hInstance; cijeli hIcon; cijeli hCursor; cijeli hbrBackground; karakter * lpszMenuName; karakter * lpszClassName; cijeli hIconSm; } wndclass ; ` window class structure cijeli nCmdShow; karakter * lpszCmdLine; cijeli hPrevInstance; cijeli hInstance; karakter[30] pstr; cijeli funkcija WndProc(cijeli lParam,cijeli wParam,cijeli wMessage,cijeli hWnd) { cijeli obradjena,WSCHILD,WSVISIBLE,hDC; obradjena:=0; ako (wMessage=1) `WM_CREATE { WSCHILD := 1073741824; `$40000000; WSVISIBLE := 268435456; `$10000000; ka:=CreateWindowExA (0,hInstance,0,hWnd, 40,120,20,140, WSCHILD | WSVISIBLE,"Poruka","BUTTON",0); kb:=CreateWindowExA (0,hInstance,0,hWnd, Sl. 10.4.1. 10.5. nCmdShow:=10; hInstance:=GetModuleHandleA (0); wndclass.cbsize:=48; wndclass.style := 0 ; wndclass.lpfnWndProc := WndProc ; wndclass.cbClsExtra := 0 ; wndclass.cbWndExtra := 0 ; wndclass.hInstance := hInstance ; wndclass.hIcon := 0 ; wndclass.hCursor := LoadCursorA (32512,0) ; `IDC_ARROW wndclass.hbrBackground := GetStockObject(2); wndclass.lpszMenuName := 0; wndclass.lpszClassName := "PROBNA" ; wndclass.hIconSm:=0; ako (!(RegisterClassExA (&wndclass))) { 0 ; } inace { hWnd := CreateWindowExA ( 0,hInstance,0,0, 400,400,4,4,13565952, `WS_OVERLAPPEDWINDOW "Prim","PROBNA",512); ShowWindow ( nCmdShow,hWnd) ; UpdateWindow(hWnd) ; dok (GetMessageA (0, 0, 0,&msg)) { TranslateMessage (&msg) ; DispatchMessageA (&msg) ; } msg.wParam ; } } Windows grafička aplikacija Rezime poglavlja Višedimenzionalni nizovi zahtijevaju nešto složeniji algoritam pristupa odgovarajućem elementu niza od jednodimenzionalnih. Pojam varijable je proširen tako da može da predstavlja i element višedimenzionalnog niza, polje sloga ili da predstavlja adresu funkcije koja se može indirektno pozvati navođenjem argumenata u zagradi iza imena varijable. Indirektni poziv predstavlja CALL instrukciju na adresu koja je navedena u pointerskoj varijabli. Slogovi se sastoje od polja koja se upisuju u tabelu identifikatora, ali i svaki definisani slog ima svoju oznaku. Uvijek se pamti koji je zadnji definisani ili korišteni slog. U sadašnjoj verziji jezika moguće je pisati i grafičke aplikacije. 68 Prilog 7: Verzija izvornog koda kompajlera br. 7 program Kompajler; const MAXIDENT = 1024; MAXDIM = 10; DUGAKONST = 'Konstanta prevazilazi liniju'; REALKONST = 'Realna konstanta'; OCEKIVANO = 'Ocekivano '; REDEKLAR='Redeklarisan identifikator'; PROSTNIZ = 'Prosti tip ne moze biti niz'; NEKORARG='Nekorektan broj argumenata'; NEKDODJP = 'Losa dodjela pointeru'; NEDEKL = 'Nedeklarisano '; GRIZRAZ = 'Izraz'; POGRMNOZ = 'Pogresan tip u ' + 'mnozenju ili dijeljenju'; NEDOPFP = ' Nedopustena FP operacija'; NEDOPARIT = 'Nedopusteni tip u aritmetici'; OCEKDOD = 'Ocekivano dodjeljivanje'; NEDODJ ='Izraz se ne moze dodijeliti'; DODJPOINT = 'Losa dodjela pointeru'; TIPUSL = 'Neodgovarajuci tip uslova'; TUSLPET = 'Neodgovarajuci uslov u petlji'; IMEFUN = 'Ocekivano ime funkcije'; DEFFUN = 'Definicija funkcije'; ARGNEKOM = 'Argument nekompatibilan' + ' s operatorom'; OCIDENT = 'Ocekivan Identifikator'; MAXDIMOV ='Maksimalan broj dimenzija'; INDSTATC = 'Indeks statickog niza nije cijeli'; PREVDIM = 'Prevazidjen broj dimenzija'; NESLDIM = 'Ne slaze se broj dimenzija'; POLJEPOS = 'Polje vec postoji'; SLOGPOLJE = 'Samo slogovi mogu imati polja'; NEDEKPOLJE = 'Nedeklarisano polje'; SLOGSLOGU = 'Slog se moze dodijeliti samoslogu'; SLOGRAZDUZ = 'Slogovi razlicite duzine'; INDNOPOINT = 'Indirektna funkcija bez pointera'; SLOGNEPOR = 'Slogovi se ne mogu porediti'; type TVrsta = (funkcija, lokalna, globalna, parametar, polje); TTip = (karakter, cijeli, realni, slog, pkarakter, pcijeli, prealni, pslog); TIdent = record ime: string[20]; duzina: integer; adresa: integer; nivo: integer; vrsta: TVrsta; tip: TTip; pod1: integer; pod2: integer; pod3: integer; ukupdim: integer; dim: array[0..MAXDIM] of integer; end; TZadnjiSlog = record duzina: integer; pozimena: integer; idopisasloga: integer end; var ulaz, izlaz: text; pozicija, trenlabela, brojaclinija, aktnivo: integer; znak: char; linija, realnakonstanta: string; TabIdent: array[0..MAXIDENT] of TIdent; ukupnoident, ukupnoslogova, ukdim: integer; t: TTip; dod: Boolean; zadnji: TZadnjiSlog; end; dimenzije: array[0..MAXDIM]of integer; function UzmiKonstantu (var t: TTip; var dod: Boolean): procedure NoviIdent(pime: string; integer; pduzina: integer; var padresa: integer; pnivo: integer; rezultat: integer; pvrsta: TVrsta; begin ptip: TTip; ppod1: integer; ppod2: rezultat := 0; integer; ppod3: integer); realnakonstanta := ''; var i: integer; while (znak >= '0') and (znak <= '9') do begin begin rezultat := 10 * rezultat + ukupnoident := ukupnoident + 1; ord(znak) - ord('0'); with TabIdent[ukupnoident] do begin realnakonstanta := realnakonstanta ime := pime; + znak; duzina := pduzina; NoviSvaki(false); adresa := padresa; end; nivo := pnivo; if (znak = '.') or (znak = 'e') or vrsta := pvrsta; (znak = 'E') then begin tip := ptip; if znak = '.' then begin pod1 := ppod1; realnakonstanta := realnakonstanta pod2 := ppod2; + znak; pod3 := ppod3; ukupdim := ukdim; NoviSvaki(false); for i := 0 to MAXDIM do while (znak >= '0') and (znak <= dim[i] := dimenzije[i]; '9') do begin realnakonstanta:=realnakonstanta end; + znak; end; NoviSvaki(false); end; procedure NovaLabela(var ImeLabele: end; string); if (znak = 'e') or (znak = 'E') then begin begin trenlabela := trenlabela + 1; realnakonstanta := realnakonstanta Str(trenlabela, ImeLabele); + znak; end; NoviSvaki(false); if (znak = '+') or (znak = '-') procedure Greska(poruka: string); then begin begin realnakonstanta:=realnakonstanta WriteLn(poruka); + znak; WriteLn(brojaclinija, ':', linija); NoviSvaki(false); Close(ulaz); end; Close(izlaz); if (znak<'0')or(znak>'9') then Halt; Greska(REALKONST); end; while (znak >= '0') and (znak <= '9') do begin procedure Emit(st: string); realnakonstanta := begin realnakonstanta+ znak; WriteLn(izlaz, st); NoviSvaki(false); end; end; end; procedure Novi; UzmiKonstantu := 0; begin t := realni; repeat end pozicija := pozicija + 1; else begin if pozicija > Length(linija) then UzmiKonstantu := rezultat; begin t := cijeli; brojaclinija := brojaclinija + 1; end; if not (Eof(ulaz)) then if (znak = ' ') or (znak = '`') then ReadLn(ulaz, linija); Novi; Emit(';' + linija); dod := false; pozicija := 1; end; end; if Length(linija) > 0 then function Slijedi(ocekivano: string; znak := linija[pozicija] dslovoiza: Boolean): Boolean; else var znak := ' '; ureduiza: Boolean; if (znak = '`') then n: integer; pozicija := Length(linija); znak: char; until ((znak > ' ') and (znak <> begin '`')) or Eof(ulaz) if dslovoiza then end; ureduiza := true else begin procedure NoviSvaki(greskakrln: n := pozicija + Length(ocekivano); Boolean); ureduiza := true; begin if Length(linija) >= n then begin pozicija := pozicija + 1; znak := linija[n]; if pozicija > Length(linija) then if ((znak >= 'a') and (znak <= begin 'z')) or if greskakrln then ((znak >= 'A') and (znak <= Greska(DUGAKONST) 'Z')) then else ureduiza := false znak := ' '; end end end; else if ureduiza and (copy(linija, znak := linija[pozicija]; pozicija, end; Length(ocekivano)) = ocekivano) then begin procedure IdiDo(z: char); Slijedi := true; begin pozicija := pozicija + if (znak <> z) then Length(ocekivano) - 1; Greska(OCEKIVANO + z); end Novi; 69 else Slijedi := false; end; function TipDek(imetipa: string; var tip: TTip; stip, ptip: TTip): Boolean; var tipind: TTip; kraj, x, poi: Boolean; begin TipDek := false; poi := false; if Slijedi(imetipa, false) then begin TipDek := true; Novi; if znak = '*' then begin tip := ptip; poi := true; Novi end else tip := stip; ukdim := 0; if znak = '[' then begin if poi then tip := pcijeli else tip := ptip; IdiDo('['); repeat ukdim := ukdim + 1; if ukdim > MAXDIM then Greska(MAXDIMOV); dimenzije[ukdim] := UzmiKonstantu(tipind, x); if tipind <> cijeli then Greska(INDSTATC); kraj := true; if znak = ',' then begin Novi; kraj := false; end; until kraj; IdiDo(']'); end; end end; function SlijediDekTipa(var tip: TTip): Boolean; var a: Boolean; begin a := false; if not (a) then a := TipDek('cijeli', tip, cijeli, pcijeli); if not (a) then a := TipDek('karakter', tip, karakter, pkarakter); if not (a) then a := TipDek('realni', tip, realni, prealni); if not (a) then a := TipDek('slog', tip, slog, pslog); SlijediDekTipa := a; end; realni: DuzinaTipa := 8; slog: DuzinaTipa := zadnji.duzina; else DuzinaTipa := 4; end; end; function NadjiIdent(ident: string; nivo, tuslova, p1: integer): integer; var n, poz: integer; nadjen, Uslov: Boolean; begin n := ukupnoident; nadjen := false; poz := 0; while (n > 0) and (not (nadjen)) do begin case tuslova of 1: Uslov := (TabIdent[n].ime = ident) and (TabIdent[n].vrsta in [lokalna, globalna, parametar, funkcija]) and ((TabIdent[n].nivo = nivo) or (TabIdent[n].nivo = 0)); 2: Uslov := (TabIdent[n].ime = ident) and (TabIdent[n].vrsta in [lokalna, globalna, parametar, funkcija]) and ((TabIdent[n].nivo = nivo)); 3: Uslov := (TabIdent[n].ime = ident) and (TabIdent[n].vrsta = polje) and (TabIdent[n].nivo = nivo) and (TabIdent[n].pod3 = p1); 4: Uslov := (TabIdent[n].nivo = nivo) and (TabIdent[n].pod2 = p1) and (TabIdent[n].vrsta = parametar) else Uslov := false; end; if Uslov then begin nadjen := true; poz := n; end; n := n - 1; end; NadjiIdent := poz; end; procedure UzmiIdent(var ident: string); begin if znak in ['a'..'z', 'A'..'Z'] then begin ident := znak; NoviSvaki(false); end else Greska(OCIDENT); while (znak in ['a'..'z', 'A'..'Z', '0'..'9', '_']) do begin ident := ident + znak; NoviSvaki(false); end; if (znak = ' ') or (znak = '`') then Novi; end; Emit(' PUSH EAX'); Emit(' MOV EAX,0'); repeat Novi; navdim := navdim + 1; if navdim > MAXDIM then Greska(PREVDIM); Emit(' PUSH EAX'); IzrazDodjeljivanja(t1, dod); Emit(' POP EBX'); if znak = ',' then begin dsvedim:=1; for i:=navdim+1 to TabIdent[idpoz].ukupdim do dsvedim:=dsvedim* TabIdent[idpoz].dim[i]; Str(dsvedim, st); Emit(' MOV EDX,' + st); Emit(' MUL EDX'); end; Emit(' ADD EBX,EAX'); Emit(' MOV EAX,EBX'); until znak <> ','; Emit(' POP EBX'); if (navdim <> TabIdent[idpoz].ukupdim) and (not ((navdim = 1) and (TabIdent[idpoz].ukupdim = 0))) then Greska(NESLDIM); IdiDo(']'); case t of pkarakter: begin t := karakter; end; pcijeli: begin Emit(' SAL EAX,2'); t := cijeli; end; prealni: begin Emit(' FSTP ST(0)'); Emit(' SAL EAX,3'); t := realni; end; pslog: begin t := slog; Str(DuzinaTipa(t), st); Emit(' MOV EDX,' + st); Emit(' MUL EDX'); end; else Greska(PROSTNIZ) end; Emit(' ADD EBX,EAX'); case t of karakter: Emit(' MOV AL,[EBX]'); realni: Emit(' FLD QWORD PTR [EBX]') else Emit(' MOV EAX,[EBX]'); end; dod := true; end; procedure StringKonstanta(var t: TTip; var dod: Boolean); var st, strtekst: string; begin NovaLabela(strtekst); Emit('.DATA'); st := 'L' + strtekst + ' DB '''; function DuzinaTipa(tip: TTip): repeat Integer; var NoviSvaki(true); procedure DeklIdent(var ident: string; elem, i: integer; if znak <> '"' then nivo: integer); st := st + znak; begin begin until znak = '"'; UzmiIdent(ident); case tip of cijeli: DuzinaTipa := 4; IdiDo('"'); if NadjiIdent(ident, nivo, 2, 0) <> 0 pcijeli, pkarakter, prealni, pslog: st := st + ''',0'; then begin if copy(st, length(st) - 3, 2) = Greska(REDEKLAR); if ukdim = 0 then '''''' then end; DuzinaTipa := 4 st := 'L' + strtekst + ' DB 0'; else begin Emit(st); procedure IzrazDodjeljivanja elem := 4 * ord(tip = pcijeli) Emit('.CODE'); (var t: TTip; var dod: Boolean); + 1 * ord(tip = pkarakter) + Emit(' MOV EAX,OFFSET L' + strtekst); forward; procedure Blok; forward; 8 * ord(tip = prealni) + t := pkarakter; zadnji.duzina * ord(tip = dod := false; pslog); procedure PokazivacINiz(var t: TTip; var end; dod: Boolean; idpoz: Integer); for i := 1 to ukdim do procedure PEmit(idpoz: Integer); elem := elem * var var dimenzije[i]; t1: TTip; i: integer; navdim,dsvedim,i: Integer; DuzinaTipa := elem; begin st: string; end if TabIdent[idpoz].ukupdim = 0 then end; begin Emit(' MOV EAX,[EBX]') navdim := 0; karakter: DuzinaTipa := 1; 70 else Emit(' MOV EAX,EBX'); ukdim := TabIdent[idpoz].ukupdim; for i := 0 to MAXDIM do dimenzije[i] := TabIdent[idpoz].dim[i]; end; function DeklaracijaSloga(nivo: integer): integer; var ImePolja: string; oznakasloga, podslog, duzinasloga, zapukdim, i, poz: integer; tip: TTip; imaistogtipa: Boolean; zdimenzije: array[0..MAXDIM] of integer; begin zapukdim := ukdim; for i := 0 to MAXDIM do zdimenzije[i] := dimenzije[i]; IdiDo('{'); ukupnoslogova := ukupnoslogova + 1; oznakasloga := ukupnoslogova; duzinasloga := 0; poz := 0; while SlijediDekTipa(tip) do begin if (tip = slog) or (tip = pslog) then podslog := DeklaracijaSloga(nivo) else podslog := oznakasloga; repeat UzmiIdent(ImePolja); poz := NadjiIdent(ImePolja, nivo, 3, podslog); if poz <> 0 then Greska(POLJEPOS); NoviIdent(ImePolja, DuzinaTipa(tip), 0, nivo, polje, tip, podslog, duzinasloga, oznakasloga); duzinasloga := duzinasloga + DuzinaTipa(tip); imaistogtipa := true; if znak = ',' then begin Novi; imaistogtipa := false; end; until imaistogtipa; while (duzinasloga mod 4) <> 0 do duzinasloga := duzinasloga + 1; IdiDo(';'); end; IdiDo('}'); zadnji.duzina := duzinasloga; zadnji.pozimena := poz; zadnji.idopisasloga := OznakaSloga; DeklaracijaSloga := OznakaSloga; ukdim := zapukdim; for i := 0 to MAXDIM do dimenzije[i] := zdimenzije[i]; end; procedure ElementSloga (idpoz: integer; var t: TTip; var dod: Boolean); var poz, nivo, idsloga: integer; Imepolja, st: string; begin if t <> slog then Greska(SLOGPOLJE); nivo := TabIdent[idpoz].nivo; idsloga := TabIdent[idpoz].pod3; while znak = '.' do begin Novi; UzmiIdent(ImePolja); poz := NadjiIdent(ImePolja, nivo, 3, idsloga); if poz = 0 then Greska(NEDEKPOLJE); Str(TabIdent[poz].pod2, st); Emit(' ADD EBX,' + st); t := TabIdent[poz].tip; case t of karakter: Emit(' MOV AL,[EBX]'); realni: Emit(' FLD QWORD PTR [EBX]'); slog: begin idsloga := TabIdent[poz].pod1; zadnji.duzina := TabIdent[poz].duzina; zadnji.pozimena := poz; zadnji.idopisasloga := TabIdent[poz].pod3; end; cijeli: Emit(' MOV EAX,[EBX]'); else PEmit(poz); end; end; end; procedure CijeliNaFPStek(reg: string; osmobitni: Boolean); begin if osmobitni then Emit(' AND ' + reg + ',0FFh'); Emit(' MOV INTTOFP,' + reg); Emit(' FILD DWORD PTR INTTOFP'); end; procedure FPStekUCijeli(reg: string); begin Emit(' ADD ESP,-4'); Emit(' FISTP DWORD PTR [ESP]'); Emit(' POP ' + reg); end; procedure CPUStekCijeliNaFPStek(osmobitni: Boolean); begin if osmobitni then Emit(' AND DWORD PTR [ESP],0FFh'); Emit(' FILD DWORD PTR [ESP]'); Emit(' ADD ESP,4'); end; procedure FPUStekNaStek; begin Emit(' ADD ESP,-8'); Emit(' FSTP QWORD PTR [ESP]'); end; procedure StekNaFPUStek; begin Emit(' FLD QWORD PTR [ESP]'); Emit(' ADD ESP,8'); end; procedure PozivFunkcije (idpoz: integer; var t: TTip; var dod: Boolean); var parametara, N, velsteka, duzprvogsloga, duzdrugogsloga, m1: integer; t1, t2: TTip; ImeFunkcije, st: string; begin ImeFunkcije := TabIdent[idpoz].ime; parametara := 0; velsteka := 0; duzprvogsloga := 0; duzdrugogsloga := 0; if znak <> '(' then begin velsteka := 0; for parametara := 1 to TabIdent[idpoz].pod1 do begin n := NadjiIdent('', idpoz, 4, parametara); velsteka := velsteka + ( (TabIdent[n].duzina - 1) div 4 + 1) * 4; end; Str(velsteka, st); Emit(' MOV EAX,OFFSET ' + imefunkcije + '@' + st); t := pcijeli; dod := false; end else begin IdiDo('('); while (znak <> ')') do begin IzrazDodjeljivanja(t1, dod); if t1 = slog then duzprvogsloga := DuzinaTipa(t1); parametara := parametara + 1; n := NadjiIdent('', idpoz, 4, parametara); if n = 0 then Greska(NEKORARG); t2 := TabIdent[n].tip; if t2 = slog then duzdrugogsloga := TabIdent[n].duzina; if (t1 in [karakter, realni]) and (t2 in [pkarakter, pcijeli, prealni]) then Greska(NEKDODJP); if (t1 = karakter) and (t2 = cijeli) then Emit(' AND EAX,0FFh'); if ((t1 = slog) and (t2 <> slog)) or ((t1 <> slog) and (t2 = slog)) then Greska(SLOGSLOGU); case t2 of slog: begin if duzprvogsloga <> duzdrugogsloga then Greska(SLOGRAZDUZ); m1 := ((duzprvogsloga - 1) div 4 + 1) * 4; velsteka := velsteka + m1; Str(duzprvogsloga, st); Emit(' MOV ECX,' + st); Str(m1, st); Emit(' SUB ESP,' + st); Emit(' MOV ESI,EBX'); Emit(' MOV EDI,ESP'); Emit(' CLD'); Emit(' REP MOVSB'); end; realni: begin velsteka := velsteka + 8; case t1 of realni: ; karakter: CijeliNaFPStek('EAX', true); else CijeliNaFPStek('EAX', false); end; FPUStekNaStek; end else begin velsteka := velsteka + 4; if t1 = realni then FPStekUCijeli('EAX'); Emit(' PUSH EAX'); end; end; if znak <> ')' then IdiDo(','); end; IdiDo(')'); if TabIdent[idpoz].pod1 <> parametara then Greska(NEKORARG); Str(velsteka, st); Emit(' MOV ECX,' + st); Emit(' CALL ' + ImeFunkcije + '@' + st); dod := false; t := TabIdent[idpoz].tip; if t = karakter then Emit(' AND EAX,0FFh'); end; end; procedure IndirektniPoziv(var t: TTip); var m1, velsteka, duzsloga: Integer; straddr, st: string; t1: TTip; begin velsteka := 0; NovaLabela(straddr); Emit('.DATA'); st := 'L' + straddr + ' DD ?'; Emit(st); Emit('.CODE'); Emit(' MOV L' + straddr + ',EAX'); IdiDo('('); while (znak <> ')') do begin IzrazDodjeljivanja(t1, dod); case t1 of slog: begin duzsloga := DuzinaTipa(t1); m1 := ((duzsloga - 1) div 4 + 1) * 4; velsteka := velsteka + m1; Str(duzsloga, st); Emit(' MOV ECX,' + st); Str(m1, st); 71 Emit(' SUB ESP,' + st); Emit(' MOV ESI,EBX'); Emit(' MOV EDI,ESP'); Emit(' CLD'); Emit(' REP MOVSB'); end; realni: begin velsteka := velsteka + 8; FPUStekNaStek; end else begin velsteka := velsteka + 4; Emit(' PUSH EAX'); end; end; if znak <> ')' then IdiDo(','); end; IdiDo(')'); Str(velsteka, st); Emit(' MOV ECX,' + st); Emit(' CALL L' + straddr); case t of pcijeli: t := cijeli; prealni: t := realni; pkarakter: t := karakter; pslog: t := slog; else Greska(INDNOPOINT) end; end; Boolean); var rezultat, poz: integer; st, fpkonst, ime, err: string; begin err := ARGNEKOM; case znak of '-': begin Novi; Faktor(t, dod); case t of cijeli: Emit(' NEG EAX'); realni: Emit(' FCHS'); else Greska(err); end; dod := false; end; '~': begin Novi; Faktor(t, dod); case t of cijeli: Emit(' NOT EAX'); karakter: Emit(' NOT AL'); else Greska(err); end; dod := false; end; '&': begin Novi; Faktor(t, dod); Emit(' MOV EAX,EBX'); procedure Varijabla case t of (idpoz: integer; var t: TTip; var cijeli: t := pcijeli; dod: Boolean; glob: Boolean); karakter: t := pkarakter; var slog: t := pslog; rezultat: integer; realni: begin st: string; t := prealni; begin Emit(' FSTP ST(0)'); rezultat := TabIdent[idpoz].adresa; end; t := TabIdent[idpoz].tip; else Str(rezultat, st); t := pcijeli; if glob then end; Emit(' LEA EBX,GLOBALV[' + st + ']') dod := false; else begin end; if rezultat >= 0 then '*': begin Emit(' LEA EBX,[EBP+' + st + ']') Novi; else Faktor(t, dod); Emit(' LEA EBX,[EBP' + st + ']'); Emit(' MOV EBX,EAX'); end; if t = prealni then begin case t of Emit(' FSTP ST(0)'); karakter: Emit(' MOV AL,[EBX]'); Emit(' FLD QWORD PTR [EBX]'); realni: end Emit(' FLD QWORD PTR [EBX]'); slog: begin else zadnji.duzina := Emit(' MOV EAX,[EBX]'); TabIdent[idpoz].duzina; case t of zadnji.pozimena := idpoz; pcijeli: t := cijeli; zadnji.idopisasloga := pkarakter: begin TabIdent[idpoz].pod3; t := karakter; end; Emit(' AND EAX,0FFh'); pslog: begin end; rezultat:=1; prealni: t := realni; pslog: begin for i:=1 to TabIdent[idpoz]. t := slog; ukupdim do end; rezultat:=rezultat* TabIdent[idpoz].dim[i]; else if rezultat<>0 then Greska(err); zadnji.duzina := end; TabIdent[idpoz].duzina dod := true; div rezultat end; else '!': begin zadnji.duzina:=4; Novi; zadnji.pozimena := idpoz; Faktor(t, dod); zadnji.idopisasloga := case t of TabIdent[idpoz].pod3; cijeli: Emit(' CMP EAX,0'); PEmit(idpoz); karakter: Emit(' CMP AL,0'); end; else Greska(err); cijeli: Emit(' MOV EAX,[EBX]'); end; else PEmit(idpoz); Emit(' SETE AL'); end; Emit(' AND EAX,0FFh'); if TabIdent[idpoz].ukupdim = 0 then dod := false; dod := true t := cijeli; else end; dod := false; '"': begin while znak ='[' do begin StringKonstanta(t, dod); PokazivacINiz(t, dod, idpoz); end; end; '''': begin if znak = '(' then NoviSvaki(true); IndirektniPoziv(t); Emit(' MOV AL,''' + znak + end; ''''); Novi; IdiDo(''''); procedure Faktor(var t: TTip; var dod: t := karakter; end; '0'..'9': begin rezultat := UzmiKonstantu(t, dod); case t of cijeli: begin Str(rezultat, st); Emit(' MOV EAX,' + st); end; realni: begin NovaLabela(fpkonst); Emit('.DATA'); st := 'L' + fpkonst + ' DQ '+ realnakonstanta; Emit(st); Emit('.CODE'); Emit(' FLD L' + fpkonst); end; end; end; '(': begin Novi; IzrazDodjeljivanja(t, dod); IdiDo(')'); end; 'A'..'Z', 'a'..'z': begin UzmiIdent(ime); poz := NadjiIdent(ime, aktnivo, 1, 0); if poz = 0 then Greska(NEDEKL + ime); case TabIdent[poz].vrsta of funkcija: PozivFunkcije(poz, t, dod); lokalna, parametar: Varijabla(poz, t, dod, false); globalna: Varijabla(poz, t, dod, true) end end; else Greska(GRIZRAZ); end; if znak = '.' then ElementSloga(zadnji.pozimena,t,dod); end; procedure Clan(var t: TTip; var dod: Boolean); var z: char; t1, t2: TTip; begin Faktor(t1, dod); t := t1; while (znak in ['*', '/', '%']) do begin z := znak; if t1 <> realni then Emit(' PUSH EAX') else FPUStekNaStek; Novi; Faktor(t2, dod); dod := false; if (not (t1 in [cijeli, karakter, realni])) or (not (t2 in [cijeli, karakter, realni])) then Greska(POGRMNOZ); if (t1 = realni) or (t2 = realni) then begin t := realni; if t2 <> realni then CijeliNaFPStek('EAX', t2 = karakter); if t1 <> realni then CPUStekCijeliNaFPStek(t1 = karakter) else StekNaFPUStek; case z of '*': Emit(' FMUL '); '/': Emit(' FDIVR '); else Greska(NEDOPFP); end end else begin t := cijeli; case z of '*': begin 72 Emit(' POP EBX'); if t1 = karakter then Emit(' AND EBX,0FFh'); if t2 = karakter then Emit(' AND EAX,0FFh'); Emit(' IMUL EBX'); end; '/', '%': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); Emit(' CDQ'); if t1 = karakter then Emit(' AND EAX,0FFh'); if t2 = karakter then Emit(' AND EBX,0FFh'); Emit(' IDIV EBX'); if z = '%' then Emit(' MOV EAX,EDX'); end; end; end; t1 := t; end; end; procedure Izraz(var t: TTip; var dod: Boolean); var z: char; t1, t2: TTip; begin Clan(t1, dod); t := t1; while (znak in ['+', '-', '&', '|', '^']) do begin if t1 <> realni then Emit(' PUSH EAX') else FPUStekNaStek; z := znak; Novi; Clan(t2, dod); dod := false; if (not (t1 in [cijeli, karakter, realni])) or (not (t2 in [cijeli, karakter, realni])) then Greska(NEDOPARIT); if (t1 = realni) or (t2 = realni) then begin t := realni; if t2 <> realni then CijeliNaFPStek('EAX', t2 = karakter); if t1 <> realni then CPUStekCijeliNaFPStek(t1 = karakter) else StekNaFPUStek; case z of '+': Emit(' FADD '); '-': Emit(' FSUBR '); else Greska(NEDOPFP); end end else begin case z of '+': begin Emit(' POP EBX'); if (t1 = karakter) and (t2 = karakter) then begin t := karakter; Emit(' ADD AL,BL'); end else begin t := cijeli; if t1 = karakter then Emit(' AND EBX,0FFh'); if t2 = karakter then Emit(' AND EAX,0FFh'); Emit(' ADD EAX,EBX'); end; end; '-': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); if (t1 = karakter) and (t2 = karakter) then begin t := karakter; Emit(' SUB AL,BL'); end else begin t := cijeli; if t1 = karakter then Emit(' AND EAX,0FFh'); if t2 = karakter then Emit(' AND EBX,0FFh'); Emit(' SUB EAX,EBX'); end; end; '&', '|', '^': begin if (t1 = karakter) and (t2 = karakter) then t := karakter else t := cijeli; Emit(' POP EBX'); case z of '&': Emit(' AND EAX,EBX'); '|': Emit(' OR EAX,EBX'); '^': Emit(' XOR EAX,EBX'); end; end; end; end; t1 := t; end; end; procedure IzrazDodjeljivanja (var t: TTip; var dod: Boolean); var z: char; t1, t2: TTip; dod1: Boolean; duzprvogsloga, duzdrugogsloga: Integer; st: string; begin duzprvogsloga := 0; duzdrugogsloga := 0; Izraz(t1, dod1); if t1 = slog then duzprvogsloga := DuzinaTipa(t1); t := t1; dod := dod1; case znak of ':': begin if not (Slijedi(':=', true)) then Greska(OCEKDOD); if not (dod1) then Greska(NEDODJ); Emit(' PUSH EBX'); if (t1 = realni) then Emit(' FSTP ST(0)'); Novi; IzrazDodjeljivanja(t2, dod); if t2 = slog then duzdrugogsloga := DuzinaTipa(t2); if ((t1 = slog) and (t2 <> slog)) or ((t1 <> slog) and (t2 = slog)) then Greska(SLOGSLOGU); if t1 = slog then begin if duzprvogsloga <> duzdrugogsloga then Greska(SLOGRAZDUZ); Emit(' POP EDI'); Emit(' MOV ESI,EBX'); Emit(' CLD'); Str(duzprvogsloga, st); Emit(' MOV ECX,' + st); end else Emit(' POP EBX'); if (t2 in [karakter, realni]) and (t1 in [pkarakter, pcijeli, prealni]) then Greska(DODJPOINT); if (t1 = realni) and (t2 <> realni) then CijeliNaFPStek('EAX', t2 = karakter); if (t1 <> realni) and (t2 = realni) then FPStekUCijeli('EAX'); case t1 of karakter: Emit(' MOV [EBX],AL'); realni: Emit(' FSTP QWORD PTR [EBX]'); slog: Emit(' REP MOVSB'); else Emit(' MOV [EBX],EAX'); end; t := t1; end; {:} '=', '>', '<', '#': begin if t1 <> realni then Emit(' PUSH EAX') else FPUStekNaStek; z := znak; Novi; Izraz(t2, dod); if (t1 = slog) or (t2 = slog) then Greska(SLOGNEPOR); if t1 <> realni then Emit(' POP EBX'); if (t1 = realni) or (t2 = realni) then begin if t2 <> realni then CijeliNaFPStek('EAX', t2 = karakter); if t1 <> realni then CijeliNaFPStek('EBX', t1 = karakter) else StekNaFPUStek; Emit(' FCOMPP '); Emit(' FSTSW AX'); Emit(' SAHF'); case z of '=': Emit(' SETE AL'); '>': Emit(' SETA AL'); '<': Emit(' SETB AL'); '#': Emit(' SETNE AL'); end; Emit(' AND EAX,0FFh'); t := cijeli; end else begin if (t1 = karakter) and (t2 = karakter) then Emit(' CMP BL,AL') else begin if t1 = karakter then Emit(' AND EAX,0FFh'); if t2 = karakter then Emit(' AND EBX,0FFh'); Emit(' CMP EBX,EAX'); end; case z of '=': Emit(' SETE AL'); '>': Emit(' SETG AL'); '<': Emit(' SETL AL'); '#': Emit(' SETNE AL'); end; Emit(' AND EAX,0FFh'); t := cijeli; end; end end; end; procedure Uslov; var sonda, sinace, skrajuslova: string; begin Novi; IzrazDodjeljivanja(t, dod); if t <> cijeli then Greska(TIPUSL); Emit(' CMP EAX,0'); NovaLabela(sonda); NovaLabela(sinace); NovaLabela(skrajuslova); Emit(' JNE L' + sonda); Emit(' JMP L' + sinace); IdiDo('{'); Emit('L' + sonda + ':'); Blok; Emit(' JMP L' + skrajuslova); Emit('L' + sinace + ':'); if Slijedi('inace', false) then begin Novi; IdiDo('{'); Blok; end; Emit('L' + skrajuslova + ':'); end; procedure Asembler; begin repeat ReadLn(ulaz, linija); 73 if linija <> '\' then Emit(linija); if eof(ulaz) then linija := '\'; until linija[1] = '\'; pozicija := 1; znak := linija[pozicija]; IdiDo('\'); end; procedure Petlja; var sdok, skrajpetlje, suslov: string; begin Novi; NovaLabela(suslov); Emit('L' + suslov + ':'); IzrazDodjeljivanja(t, dod); if t <> cijeli then Greska(TUSLPET); Emit(' CMP EAX,0'); NovaLabela(sdok); NovaLabela(skrajpetlje); Emit(' JNE L' + sdok); Emit(' JMP L' + skrajpetlje); IdiDo('{'); Emit('L' + sdok + ':'); Blok; Emit(' JMP L' + suslov); Emit('L' + skrajpetlje + ':'); end; procedure Blok; begin while znak <> '}' do begin if Slijedi('dok', false) then Petlja else if Slijedi('ako', false) then Uslov else if Slijedi('asembler', false) then Asembler else begin IzrazDodjeljivanja(t, dod); IdiDo(';'); end; end; IdiDo('}'); end; procedure DefFunkcija(ftip: TTip); var parametara, paradresa, lokadresa, pfunkc, i, p3: integer; ImeFunkcije, imeparametra, imevarijable, st: string; tip: TTip; imaistogtipa: Boolean; begin if not (((znak >= 'a') and (znak <= 'z')) or ((znak >= 'A') and (znak <= 'Z'))) then Greska(IMEFUN); DeklIdent(ImeFunkcije, 0); NoviIdent(ImeFunkcije, 4, 0, 0, funkcija, ftip, 0, 0, 0); pfunkc := ukupnoident; aktnivo := pfunkc; IdiDo('('); parametara := 0; lokadresa := 0; paradresa := 0; while znak <> ')' do begin if SlijediDekTipa(tip) then begin if (tip = slog) or (tip = pslog) then p3 := DeklaracijaSloga(pfunkc) else p3 := 0; DeklIdent(ImeParametra, pfunkc); parametara := parametara + 1; paradresa := paradresa + ((DuzinaTipa(tip)-1)div 4+1)*4; NoviIdent(ImeParametra, DuzinaTipa(tip), paradresa, pfunkc, parametar, tip, pfunkc, parametara, p3); end; if znak <> ')' then IdiDo(','); end; IdiDo(')'); for i := ukupnoident downto 0 do if (TabIdent[i].nivo = pfunkc) and (TabIdent[i].vrsta=parametar)then TabIdent[i].adresa := paradresa + 8 - TabIdent[i].adresa; TabIdent[pfunkc].pod1 := parametara; case znak of '{': begin IdiDo('{'); while SlijediDekTipa(tip) do begin if (tip = slog) or (tip = pslog) then p3 := DeklaracijaSloga(pfunkc) else p3 := 0; repeat DeklIdent(ImeVarijable, pfunkc); lokadresa := lokadresa + DuzinaTipa(tip); NoviIdent(ImeVarijable, DuzinaTipa(tip), -lokadresa, pfunkc, lokalna, tip, pfunkc, parametara, p3); imaistogtipa := true; if znak = ',' then begin Novi; imaistogtipa := false; end; until imaistogtipa; while (lokadresa mod 4)<>0do lokadresa := lokadresa + 1; IdiDo(';'); end; Str(paradresa, st); Emit(ImeFunkcije+'@'+st+':'); Emit(' PUSH EBP'); Emit(' MOV EBP,ESP'); Str(lokadresa, st); Emit(' SUB ESP,' + st); Blok; Emit(' MOV ESP,EBP'); Emit(' POP EBP'); Str(paradresa, st); Emit(' RET ' + st); Emit('PUBLIC '+ImeFunkcije+ '@' + st); end; ';': begin Str(paradresa, st); Emit('extrn ' + ImeFunkcije + '@' + st + ':near'); IdiDo(';'); end else Greska(DEFFUN); end; aktnivo := 0; end; procedure Prevedi; var globadresa, p3: Integer; ImeVarijable, st: string; tip: TTip; imaistogtipa: Boolean; begin Emit('.486'); Emit('.MODEL FLAT,STDCALL'); Emit('OPTION CASEMAP:NONE'); Emit('EXTRN ExitProcess@4:NEAR'); Emit('.CODE'); Emit('ULAZ:'); Emit(' FINIT'); Emit(' JMP GLAVNI'); pozicija := 0; globadresa := 0; Novi; while SlijediDekTipa(tip) do begin if Slijedi('funkcija', false) then begin Novi; DefFunkcija(tip); end else begin if (tip = slog) or (tip = pslog) then p3 := DeklaracijaSloga(0) else p3 := 0; repeat DeklIdent(ImeVarijable, 0); NoviIdent(ImeVarijable, DuzinaTipa(tip), globadresa, 0, globalna, tip, 0, 0, p3); globadresa := globadresa + DuzinaTipa(tip); imaistogtipa := true; if znak = ',' then begin Novi; imaistogtipa := false; end; until imaistogtipa; while (globadresa mod 4) <> 0 do globadresa := globadresa + 1; IdiDo(';'); end end; IdiDo('{'); if znak <> '}' then begin Emit('GLAVNI:'); Blok; Emit(' PUSH 0'); Emit(' CALL ExitProcess@4'); Emit('.DATA'); Str(globadresa, st); Emit('GLOBALV DB '+st+' DUP(0)'); Emit('INTTOFP DD 0'); Emit('END ULAZ') end else begin Emit('GLAVNI:'); Emit('END'); end; end; procedure Glavni; var linija: string; begin trenlabela := 0; ukupnoident := 0; aktnivo := 0; ukupnoslogova := 0; Assign(ulaz, paramstr(1)); Assign(izlaz, paramstr(2)); brojaclinija := 0; linija := ''; Reset(ulaz); Rewrite(izlaz); Prevedi; Close(ulaz); Close(izlaz); WriteLn('Prevedeno bez greske'); end; begin Glavni end. 74 11. PREDPROCESIRANJE I OPTIMIZACIJA KODA Došlo se do faze u kojoj se sam kompajler više neće mijenjati. Uočljivo je, međutim, da jeziku nedostaju predefinisani tipovi, konstante te makronaredbe, odnosno uključivanje kompletnih datoteka izvornog koda, kako se iste sekvence koda ne bi morale više puta kucati. Svi ovi problemi se mogu riješiti predprocesorom. Osim toga, već u prvoj verziji kompajlera je uočeno da je generisani kôd prevelik, pa je potrebno pristupiti optimizaciji generisanog koda. 11.1. Struktura kompajlera Predprocesor i postprocesor se nalaze u posebnim modulima (unit) i u suštini predstavljaju velika proširenja dosadašnjih procedura Novi i Emit. Ove procedure su premještene iz glavnog modula u module predpr8.pas i postpr8.pas. Posljednja verzija kompajlera nema oznaka izmjena u odnosu na prethodnu verziju 11.2. Predprocesorska direktiva #definiraj Predprocesor je sličan predprocesoru iz jezika C. Ako se na početku linije predprocesorsku direktivu. Tipična sintaksa direktive #definiraj izgleda ovako: nalazi znak #, to predstavlja #definiraj SIMBOL TekstSimbola U daljnjem radu prilikom obrade linije sve pojave navedenog simbola zamjenjuju se tekstom. Ako je tekst simbola duži od jedne linije, na njenom kraju se stavlja znak \. Primjer: #definiraj PI 3.14159265 #definiraj PETLJA dok(i<2)\ { i:=i+1;} U ovom primjeru je definisana konstanta PI i sada je u korisničkom programu moguće pisati a:=PI/2. Pored ovoga navođenjem simbola PETLJA, zamjenjuje se cijela petlja navedena u njegovom tijelu. Definisanje konstanti predprocesorom rješava pitanje imena tipova. Tako se može navesti: #definiraj KOMPLEKSNI slog {realni x;realni i;} i dalje pisati KOMPLEKSNI a,b,c,d; Uz pomoć predprocesora, čak je moguće uvesti objekte sa jednim nivoom nasljeđivanja. Na slici Sl. 11.2.1 se vidi kako se uz pomoć predprocesora može, uz dosta discipline pri pisanju, postići sintaksa slična sintaksi u objektno orijentisanim jezicima, tj. “metode” (u suštini pointeri na funkcije) , “klase” (zapravo slogovi) i “nasljeđivanje” (ponavljanje istih polja uz pomoć predprocesora). #definiraj METODA cijeli * #definiraj OTAC cijeli p1,p2; METODA a; #definiraj SIN OTAC cijeli p3; #definiraj OBJEKT slog { #definiraj INSTANCE } #definiraj INIT .a:=x; cijeli funkcija x (cijeli a) { 1; ` tijelo metode } Sl. 11.2.1. 11.3. OBJEKT OTAC INSTANCE xxx; OBJEKT SIN INSTANCE yyy; { xxx INIT yyy INIT xxx.p1:=2; yyy.p1:=3; yyy.p3:=3; xxx.a(50); } Rudimentarno OOP uz pomoć predprocesora Direktive uslovnog kompajliranja U jeziku FILDZAN-32 omogućeno je da se određeni dijelovi koda kompajliraju ako je neki simbol definisan (ili nedefiniran) koristeći direktivu #definiraj. U protivnom, linije izvornog koda se ignorišu kao da su komentari. Direktive uslovnog kompajliranja su #postoji, #nepostoji i #dalje. • #postoji SIMBOL Ako je navedeni simbol ranije definisan, naredni dio programa će se prevoditi, a ako ne ignorisat će se. Ovo ignorisanje će ići sve do direktive #dalje • #nepostoji SIMBOL Ako navedeni simbol nije ranije definisan, naredni dio programa će se prevoditi, a ako je definisan ignorisat će se. Ovo ignorisanje će ići sve do direktive #dalje • #dalje Završava blok započet naredbama #postoji ili #nepostoji. 75 #definiraj WINDOWS 1 #postoji WINDOWS MessageBox(0,”Poruka”,”Na ekranu”,0); #dalje #nepostoji WINDOWS UpisiUDatoteku(”Poruka”); #dalje Sl. 11.3.1. Upotreba direktiva #postoji i #nepostoji U primjeru sa slike Sl. 11.3.1 se, ako je definisan simbol WINDOWS, prikazuje poruka koristeći funkciju MessageBox, a ako ne, poruka se upisuje u datoteku. 11.4. Direktiva #dodaj za uključivanje datoteke Sintaksa naredbe za uključivanje kompletne datoteke sa izvornim kodom glasi: #dodaj ImeDatoteke Od mjesta u izvornom kodu programa neposredno iza direktive #dodaj se uključuje kompletna datoteka i sada se generiše asemblerski kôd iz te datoteke, sve dok se ona ne iscrpi. Nakon toga se nastavlja kompajliranje glavne datoteke. Nije dopušteno gniježđenje datoteka Primjer: #dodaj osnovniprozor.h 11.5. Realizacija predprocesora Realizacija predprocesora nije pretjerano složena. Treba definisati bafer od (npr.) 200 K u kome će stojati stringovi koji predstavljaju vrijednost koja se stavlja i niz definicija koje sadrže imena simbola te poziciju u ovom baferu gdje se nalazi dati string. Procedura Novi sada izgleda nešto drugačije nego u sedmoj verziji kompajlera. Kako se direktivom #dodaj može preusmjeriti na drugu ulaznu datoteku, provjerava se koja je ulazna datoteka u pitanju i ReadLn obavlja iz nje. Nakon instrukcije ReadLn se poziva rutina Predprocesiraj. U okviru ove rutine se provjerava da li linija počinje predprocesorskom direktivom. Najviše posla ima ako se prepozna direktiva #definiraj. Ona je implementirana u proceduri PpDefin i najprije rastavi ime simbola od njegove vrijednosti. Definisanje simbola se vrši njegovim dodavanjem u tabelu simbola, a njegova definicija se dodaje u bafer opisa simbola simbola. Direktive #postoji i #nepostoji (implementirane u procedurama PpPostoji i PpNePostoji) provjeravaju prisustvo navedenog simbola u tabeli i tako postave varijablu ObradaLinije na true ili false. U rutini Predprocesiraj se ova varijabla provjeri i ako je jednaka false, linija teksta se proglašava praznom. Direktiva #dalje (implementirana u Predprocesiraj) postavlja tu varijablu na true. Direktiva #dodaj (implementirana u Predprocesiraj) otvara pomoćnu datoteku i preusmjerava čitanje na nju. U drugom dijelu rutine Predprocesiraj se prođe kroz cijelu tabelu predprocesorskih simbola i koristeći paskalsku funkciju Pos pretražuje pojava danih simbola u ulaznoj liniji. Ako ih ima, simbol na tom mjesto u izvornom kodu se zamjenjuje kompletnim stringom koji se nalazi u definiciji. Ako definicija simbola sadrži drugi simbol, ova će petlja ekspandovati i njega. Rutina se zasniva na činjenici da stringovi u 32-bitnim implementacijama Pascala mogu biti veoma dugački. Eventualno portiranje kompajlera u drugi programski jezik treba imati tu činjenicu u vidu. Jezik FILDZAN-32 je završen, uključujući i predprocesor. U prilogu 9 dat je izvorni kôd predprocesora . 11.6. Optimizacija koda Gledano makroskopski, ovaj kompajler generiše veoma kratak kôd. U usporedbi sa bilo kojim kompajlerom viših programskih jezika za Windows, koji u izvršni kôd uključuju velike biblioteke, manje od 3 Kb za prazan program izgleda skoro kao rekord. Razlog ovome je što FILDZAN-32 generiše vrlo mali startni kôd. Ali, posmatrajući pojedinačne naredbe, kako su prevedene, uviđa se da ima jako mnogo nepotrebnih asemblerskih instrukcija. Razlog ovome je što kompajler kada prevodi aritmetičke izraze prilikom nailaska na operator ne zna unaprijed da li 76 će slijediti konstanta, varijabla ili kompletan izraz, pa se priprema za najgori slučaj. To rezultuje vrlo čestim stavljanjem podataka na stek, ili pomoćne registre. Za primjer se može uzeti prevođenje proste instrukcije n:=n+1; Ona se prevodi u ; n:=n+1; LEA EBX,GLOBALV[400] MOV EAX,[EBX] PUSH EBX LEA EBX,GLOBALV[400] MOV EAX,[EBX] PUSH EAX MOV EAX,1 POP EBX ADD EAX,EBX POP EBX MOV [EBX],EAX dok je najkraći mogući kôd ; n:=n+1; INC GLOBALV[400] Uklanjanje nepotrebnih instrukcija se može izvesti modifikacijom procedure Emit. Umjesto da se generisana asemblerska naredba odmah šalje u izlaznu datoteku, ona se najprije stavlja u bafer od 15 instrukcija. Kada se ovaj bafer popuni, prvo se traži nekoliko karakterističnih uzoraka sekvenci asemblerskih naredbi i one se pokušavaju zamijeniti kraćim sekvencama. Ako to ne uspije, naredba koja je najranije ušla u bafer se šalje u izlaznu datoteku i stvara se mjesto za novu naredbu u baferu. Ovo se zove peephole optimizacija. Prepozna li se pseudo instrukcija .END, optimizacija se izvede još jednom i pošalju se u datoteku sve instrukcije iz bafera. Prepoznavanje uzoraka je složen problem i zavisan od konkretnog procesora. Sekvenca koja je na procesoru 386 brža, može biti sporija na procesoru Pentium IV od neke druge sekvence. Ovaj zadatak prilično usporava kompajler, pa će se realizovati optimizovanje samo nekoliko najčešćih uzoraka. Uzorci se sastoje od više instrukcija, a one mogu da sadrže parametre. Parametri se označavaju sa $C1, $C2 za proizvoljne literale, ili sa $N1, $N2 za brojeve. Stoga se se uzorci ne mogu prepoznavati prostim poređenjem, nego je potrebna odgovarajuća funkcija. Ta funkcija se zove Uzorak i ima četiri string parametra: string koji se traži, stvarna vrijednost, varijable u koje vraćamo vrijednosti prvog i drugog $ parametra u uzorku. Primjer uzorak(‘ MOV EAX,$C1’,’ MOV EAX,ECX’,v1,v2) će vratiti true, jer su uzorci slični, u varijabli v1 se dobija string ‘ECX’ dok v2 dobija prazan string. Funkcija uzorak poredi uzorke algoritmom sa slike Sl. 11.6.1. Ako su traženi i stvarni string jednaki, odmah se vrati s tačnom vrijednošću Postavi pokazivače na početak traženog i stvarnog stringa Izvršavaj petlju do kraja traženog stringa Ako se u traženom stringu na datom mjestu nalazi simbol $, uvećaj pokazivač u traženom stringu za 1, provjeri da li slijede simboli C ili N, a iza njih simboli 1 ili 2, oba puta uvećavajući pokazivač u traženom stringu. Ukoliko se prepoznaju sekvence $C1, $C2, $N1 ili $N2 treba ih specijalno obraditi. Specijalna obrada nadovezuje redom znakove stvarnog stringa, stalno uvećavajući njegov pokazivač, na prvu ili drugu izlaznu varijablu sve dok se ne dođe do kraja stvarnog stringa, znaka zarez, a za numeričke konstante i prvog nenumeričkog znaka. Ako su znakovi na trenutnoj poziciji u traženom i stvarnom stringu različiti, izađi iz funkcije s netačnim rezultatom. Uvećaj za jedan pokazivače traženog i stvarnog stringa. Na kraju petlje izađi iz funkcije sa tačnim rezultatom Sl. 11.6.1. Algoritam pretraživanja uzorka Obrada slučajeva za $C i $N sekvence realizovana je u procedurama KarakterSl i BrojSl. 77 ADD $C1,$C2 Ako bilo koji od $C1 ili $C2 sadrži EAX ili EBX, koristi ih. Ako je $C1 jednak ESP relativna promjena ESP je $C2 AND $C1,$C2 Ako bilo koji od $C1 ili $C2 sadrži EAX ili EBX, koristi ih. CALL $C1 Pretpostavlja se da briše EAX, EBX i koristi FPU CDQ Koristi EAX CLD Irelevantna CMP $C1,$C2 Ako bilo koji od $C1 ili $C2 sadrži EAX ili EBX, koristi ih. FADD Koristi FPU FCHS Koristi FPU FCOMPP Koristi FPU FDIVR Koristi FPU FILD $C1 Koristi FPU FINIT Koristi FPU FISTP $C1 Koristi FPU FLD $C1 Koristi FPU FMUL Koristi FPU FSTP $C1 Koristi FPU FSTSW AX Koristi FPU, briše EAX FSUBR Koristi FPU IDIV $C1 Koristi EAX, ako je $C1 jednak EBX, koristi i EBX IMUL $C1 Koristi EAX, ako je $C1 jednak EBX, koristi i EBX JMP $C1 Pretpostavlja se da briše EAX, EBX i koristi FPU JNE $C1 Pretpostavlja se da briše EAX, EBX i koristi FPU LEA $C1,$C2 Ako je $C1 jednak EAX (AL) ili EBX (BL), briše ih. Ako $C2 sadrži EAX ili EBX, koristi ih. MOV $C1,$C2 Ako je $C1 jednak EAX (AL) ili EBX (BL), briše ih. Ako $C2 sadrži EAX ili EBX, koristi ih. Ako $C1 sadrži EAX ili EBX, a nije jednak njima koristi ih. MUL $C1 Koristi EAX, ako je $C1 jednak EBX, koristi i EBX NEG $C1 Ako $C1 sadrži EAX ili EBX, koristi ih. NOT $C1 Ako $C1 sadrži EAX ili EBX, koristi ih. OR $C1,$C2 Ako bilo koji od $C1 ili $C2 sadrži EAX ili EBX, koristi ih. POP $C1 Ako je $C1 jednak EAX ili EBX, briše ih. Relativna promjena ESP je -4 PUSH $C1 Ako $C1 sadrži EAX ili EBX, koristi ih. Relativna promjena ESP je –4 REP MOVSB Irelevantna RET $N1 Relativna promjena ESP je $N1+4 SAHF Koristi EAX SAL EAX,$N1 Koristi EAX SETA AL Briše EAX SETB AL Briše EAX SETE AL Briše EAX SETG AL Briše EAX SETL AL Briše EAX SETNE AL Briše EAX SUB $C1,$C2 Ako bilo koji od $C1 ili $C2 sadrži EAX ili EBX, koristi ih. XOR $C1,$C2 Ako bilo koji od $C1 ili $C2 sadrži EAX ili EBX, koristi ih. Sl. 11.6.2. Efekti pojedinih instrukcija relevantni za optimizaciju 78 Da bi se znalo koje instrukcije iz peephole bafera je moguće izbaciti treba ažurirati sljedeće indikatore: - Da li grupa instrukcija mijenja EAX prije nego ga čita - Da li grupa instrukcija uopšte čita EAX - Da li grupa instrukcija mijenja EBX prije nego ga čita - Da li grupa instrukcija uopšte čita EBX - Da li grupa instrukcija koristi floating point instrukcije - Na kojoj se poziciji nalazi ESP registar u odnosu na početak grupe instrukcija Procedura obradistanje za svaku od instrukcija koja joj se proslijedi ažurira navedenih šest indikatora. Instrukcije koje su korištene za generisanje koda se mogu smjestiti u tabelu na slici Sl. 11.6.2 po njihovom ponašanju: Optimizacijska pravila implementirana u osmoj verziji kompajlera su: 1) Sekvenca PUSH EAX / instrukcije koje ne mijenjaju EAX / POP EAX povlači izbacivanje PUSH EAX i POP EAX instrukcija. Unutar ove sekvence ESP mora biti na istom nivou, dakle sekvenca mora imati jednak broj PUSH i POP instrukcija. Dualno pravilo se primjenjuje ako se zamijene EAX i EBX. 2) Sekvenca PUSH EAX / instrukcije koje ne mijenjaju EBX / POP EBX povlači izbacivanje POP EBX i zamjenu PUSH EAX instrukcije instrukcijom MOV EBX,EAX. Unutar ove sekvence ESP mora biti na istom nivou, dakle sekvenca mora imati jednak broj PUSH i POP instrukcija. Dualno pravilo se primjenjuje ako se zamijene EAX i EBX. 3) Sekvenca LEA EBX,adresa / PUSH EBX / instrukcije koje ne mijenjaju EBX / POP EBX povlači izbacivanje LEA EBX,adresa i PUSH EBX te zamjenu POP EBX instrukcije instrukcijom LEA EBX,adresa. Unutar ove sekvence ESP mora biti na istom nivou, dakle sekvenca mora imati jednak broj PUSH i POP instrukcija 4) Ako nakon instrukcije LEA EBX,adresa slijedi instrukcija koja briše EBX prije instrukcije koja ga koristi, instrukcija LEA EBX, adresa se može obrisati. 5) Ako nakon instrukcije MOV EAX,adresa slijedi instrukcija koja briše EAX prije instrukcije koja ga koristi, instrukcija MOV EAX, adresa se može obrisati. Dualno pravilo se primjenjuje ako se zamijene EAX i EBX. 6) Ako iza instrukcije FLD slijedi sekvenca instrukcija koje ne koriste FPU a nakon njih instrukcija FSTP ST(0) (odbacivanje podatka) instrukcije FLD i FSTP ST(0) se mogu obrisati. 7) U sekvenci ADD ESP,-8 / FSTP QWORD PTR [ESP] / Instrukcije koje ne koriste FPU/ FLD QWORD PTR [ESP] / ADD ESP,8 sve četiri instrukcije koje uokviruju ostale instrukcije se mogu brisati. 8) Instrukcije koje nemaju efekta kao što su MOV EAX,EAX ; MOV EBX,EBX ;ADD EAX,0 ili ADD EBX,0 se mogu brisati 9) Ako su dvije uzastopne iste MOV instrukcije , jedna se može brisati 10) Ako iza MOV registar,konst slijedi ADD registar,konst ovo se može svesti na jednu MOV instrukciju koja dodjeljuje implicitni zbir 11) Ako iza instrukcije MOV registar,konst slijedi NEG registar, to se može zamijeniti sa MOV registar,-konst. Ovim je riješen problem unarnog minusa koji je u nekim jezicima sastavni dio konstante. 12) Ako su dvije uzastopne iste ADD instrukcije , mogu se svesti na jednu sa implicitnim zbirom 13) Sekvence tipa MOV reg1,reg2 / ADD reg3,reg1 / MOV reg1,reg3 se mijenjaju sekvencama ADD reg3,reg2 / MOV reg1,reg3. Umjesto registara ovdje se mogu javljati i memorijske lokacije, a pored ADD instrukcije ista sekvenca je moguća i sa instrukcijama AND, SUB, MOV, OR, XOR. 14) Sekvence tipa PUSH reg1 / MOV reg2,reg3 / MOV reg1,reg4 / POP reg4 znače da se reg1 i reg4 mogu obrisati. Ova sekvenca se javlja kao rezultat drugih optimizacija. Procedura Optimizuj, koja se poziva iz procedure Emit provjerava sve ove slučajeve i izbacuje odnosno zamjenjuje nepotrebne instrukcije. Ovih 14 jednostavnih pravila skraćuju asemblerski generisani program za oko 30 %. Realizacija samog optimizatora je nešto usložnjena kako bi pretraživanje išlo brže. Uvođenje optimizacije usporava proces kompajliranja. Sedma verzija kompajlera je prevodila prethodni primjer na Pentium-u 100 za 0,2 s, dok osmoj verziji za isti zadatak treba oko 2,5 s. 79 11.7. Testni primjer optimizacije Kao testni primjer uzet je program predstavljen u prvoj koloni slike Sl. 11.7.1 : cijeli a; { a:=2; a:=a+a+1; } Izvorni kôd Neoptimizirani kôd iz 7. Verzije kompajlera Uočene redundante sekvence Optimizovani kôd iz 8. verzije cijeli a; { a:=2; a:=a+a+1; } .486 .MODEL FLAT,STDCALL OPTION CASEMAP:NONE EXTRN ExitProcess@4:NEAR .CODE ULAZ: FINIT JMP GLAVNI ;cijeli a; ;{ ; a:=2; GLAVNI: LEA EBX,GLOBALV[0] MOV EAX,[EBX] PUSH EBX MOV EAX,2 POP EBX MOV [EBX],EAX ; a:=a+a+1; LEA EBX,GLOBALV[0] MOV EAX,[EBX] PUSH EBX LEA EBX,GLOBALV[0] MOV EAX,[EBX] PUSH EAX LEA EBX,GLOBALV[0] MOV EAX,[EBX] POP EBX ADD EAX,EBX PUSH EAX MOV EAX,1 POP EBX ADD EAX,EBX POP EBX MOV [EBX],EAX ;} ;} PUSH 0 CALL ExitProcess@4 .DATA GLOBALV DB 4 DUP(0) INTTOFP DD 0 END ULAZ Nepotrebno MOV EAX 13 MOV EAX,[EBX] 14 PUSH EBX 15 MOV EAX,2 Nepotrebno LEA/PUSH/POP 12 LEA EBX,GLOBALV[0] 13 PUSH EBX 14 MOV EAX,2 15 POP EBX Nasao nepotrebno LEA 12 LEA EBX,GLOBALV[0] 13 MOV [EBX],EAX 14; a:=a+a+1; 15 LEA EBX,GLOBALV[0] Nepotrebno MOV EAX 12 MOV EAX,[EBX] 13 PUSH EBX 14 LEA EBX,GLOBALV[0] 15 MOV EAX,[EBX] Nasao nepotrebno LEA 12 LEA EBX,GLOBALV[0] 13 MOV EAX,[EBX] 14 PUSH EAX 15 LEA EBX,GLOBALV[0] Nasao nepotrebno LEA 13 LEA EBX,GLOBALV[0] 14 MOV EAX,[EBX] 15 POP EBX Nepotrebno PUSH /POP EBX 12 PUSH EAX 13 MOV EAX,DWORD PTR GLOBALV[0] 14 POP EBX Nepotrebna trojka 11 MOV EAX,DWORD PTR GLOBALV[0] 12 MOV EBX,EAX 13 MOV EAX,DWORD PTR GLOBALV[0] Nepotrebno PUSH /POP EBX 13 PUSH EAX 14 MOV EAX,1 15 POP EBX Nepotrebno LEA/PUSH/POP 7 LEA EBX,GLOBALV[0] 8 PUSH EBX 9 MOV EBX,DWORD PTR GLOBALV[0] 10 MOV EAX,DWORD PTR GLOBALV[0] 11 ADD EAX,EBX 12 MOV EBX,EAX 13 MOV EAX,1 14 ADD EAX,EBX 15 POP EBX Nasao nepotrebno LEA 10 LEA EBX,GLOBALV[0] 11 MOV [EBX],EAX 12;} 13;} 14 PUSH 0 15 CALL ExitProcess@4 Prevedeno bez greske .486 .MODEL FLAT,STDCALL OPTION CASEMAP:NONE EXTRN ExitProcess@4:NEAR .CODE ULAZ: FINIT JMP GLAVNI ; ;cijeli a; ;{ ; a:=2; GLAVNI: MOV EAX,2 MOV DWORD PTR GLOBALV[0],EAX ; a:=a+a+1; MOV EBX,DWORD PTR GLOBALV[0] MOV EAX,DWORD PTR GLOBALV[0] ADD EAX,EBX MOV EBX,EAX MOV EAX,1 ADD EAX,EBX MOV DWORD PTR GLOBALV[0],EAX ;} ;} PUSH 0 CALL ExitProcess@4 .DATA GLOBALV DB 4 DUP(0) INTTOFP DD 0 END ULAZ Optimalni kôd .486 .MODEL FLAT,STDCALL OPTION CASEMAP:NONE EXTRN ExitProcess@4:NEAR .CODE ULAZ: JMP GLAVNI ; ;cijeli a; ;{ ; a:=2; GLAVNI: MOV DWORD PTR GLOBALV[0],2 ; a:=a+a+1; MOV EAX,DWORD PTR GLOBALV[0] ADD EAX,DWORD PTR GLOBALV[0] INC EAX MOV DWORD PTR GLOBALV[0],EAX ;} ;} PUSH 0 CALL ExitProcess@4 .DATA GLOBALV DB 4 DUP(0) INTTOFP DD 0 END ULAZ Sl. 11.7.1. Primjer rada optimizatora Kada ne bi bilo optimizacije, (kao u verziji 7 kompajlera) prevedeni kôd bi izgledao kao u drugoj koloni. U kompajleru je uključeno da prikazuje sekvence koje pronalazi optimizator nakon zaključka da se one mogu zamijeniti kraćim sekvencama. U trećoj koloni se vidi da je optimizator djelovao ukupno 11 puta u ovako malom programu. 80 Rezultat optimizacije je dat u gornjem dijelu četvrte kolone na slici Sl. 11.7.1. Ovo još nije najbolji kôd koji se može generisati. Uz povećanje broja pravila (što u ovom radu nije učinjeno) može se približiti optimalnom kodu iz donjeg dijela četvrte kolone. I na većim programima uočavaju se uštede od oko 30%-40%, iako je implementirano prilično malo optimizacijskih pravila. 11.8. Rezime poglavlja Predprocesor omogućava zamjenu dijelova koda konstantama, uključivanje čitavih listinga izvornog koda, te uslovno kompajliranje. Predprocesor je baziran na baferu u kome se čuvaju definicije zamjenskih simbola. Promijenjene su procedure Novi i Emit i projekt organizovan u tri modula. Optimizator radi na principu zadrške nekoliko instrukcija i traženja karakterističnih sekvenci koje se zamjenjuju kraćim sekvencama. Pri izboru sekvenci prati se upotreba registara EAX, EBX, ESP i FP steka. Ovim je razvoj jezika, na nivou ovog rada, završen. Sada treba isprobati nekoliko primjera iz realnog svijeta. 81 12. TESTNI PRIMJERI Nakon realizacije posljednje verzije kompajlera slijedi njegovo testiranje. Kompajler je isproban na aplikacijama iz realnog svijeta, iz raznih oblasti primjene. 12.1. Primjer: Baze podataka i korisnički interfejs Pošto su baze podataka uz igre, obradu teksta i sistemski softver najpopularnija kategorija softvera, završni primjer programa u jeziku FILDZAN-32 je mala baza podataka u Accessovom MDB formatu kojoj se pristupa koristeći SQL i ODBC. Ne bi bilo bitne razlike ni da je u pitanju MS SQL Server ili Oracle RDBMS. Sastoji se od jedne tabele koja predstavlja telefonski imenik. Imenik se može pretraživati, a u njega se mogu unositi podaci. Polja u tabeli IMENIK su IME CHAR(20), PREZIME CHAR(20), ADRESA CHAR(20), TELEFON CHAR(20) Ovaj database primjer koristi, pored Windows API funkcija navedenih u prethodnom poglavlju i mnoge API funkcije iz oblasti ODBC-a. Konekcija sa ODBC sistemom se uspostavlja koristeći SQLAllocEnv, za pripremu okruženja, SQLAllocConnect za rezervisanje prostora u memoriji za konekciju, SQLDriverConnect koji zaista vrši konekciju sa datim sistemom za upravljanje bazom podataka. Prostor u memoriji za naredbu se rezerviše koristeći SQLAllocStmt, a oslobađa koristeći SQLFreeStmt. SQL Naredba se izvršava peko funkcije SQLExecDirect. Ako ona vraća podatke, slog se preuzima koristeći SQLFetch, a odgovarajuće polje se dobije funkcijom SQLGetData. Konekcija se prekida sa SQLDisconnect a memorija oslobađa sa SQLFreeConnect. Na slici se vidi prozor sa formularom za pretraživanje i unošenje navedene baze podataka. Na njemu se nalaze četiri labele, četiri editna polja i tri tastera. Obrada poruka koje generišu ovi tasteri se vrši na standardan način, kao u primjeru iz prethodnog poglavlja Sl. 12.1.1. Izgled ekrana demonstracione ODBC aplikacije Kompajliranje i linkovanje ovog primjera zahtijeva još jednu dodatnu biblioteku prilikom linkovanja. komp32v7 odbc.jez odbc.asm ml /c /coff /Fl odbc.asm link /defaultlib: user32.lib kernel32.lib gdi32.lib odbc.lib /subsystem:windows odbc.obj Datoteke odbc.jez i odbc.h sa finalnim primjerima date su na slikama Sl. 12.1.2 i Sl. 12.1.3. 82 SetWindowTextA(prazna,ka); SetWindowTextA(prazna,kb); SetWindowTextA(prazna,kc); SetWindowTextA(prazna,kd); #dodaj odbc.h cijeli funkcija Konekcija() { cijeli velicina,rez; karakter [2000] punistring; rez:=SQLAllocEnv(&ehan); } rez:=SQLAllocConnect(&chan,ehan); rez:=SQLDriverConnect(0,&velicina, 1900, punistring, 70,"DRIVER={Microsoft Access Driver (*.mdb)};DBQ=test.mdb",hWnd,chan); rez:=SQLAllocStmt(&shan,chan); } cijeli funkcija Diskonekcija() { cijeli rez; rez:=SQLFreeStmt(0,shan); rez:=SQLDisconnect(chan); rez:=SQLFreeConnect(chan); } cijeli funkcija Insert() { karakter [500] komanda; karakter * kk; karakter [30] polje; karakter [2] navodnik; cijeli rez; navodnik [0]:=39;navodnik[1]:=0; komanda[0]:=0; lstrcat( "INSERT INTO IMENIK(IME,PREZIME,ADRESA,TELEFON) VALUES(" ,komanda); GetWindowTextA(30,polje,ka); NAV;POLJE;NAV;ZAREZ; GetWindowTextA(30,polje,kb); NAV;POLJE;NAV;ZAREZ; GetWindowTextA(30,polje,kc); NAV;POLJE;NAV;ZAREZ; GetWindowTextA(30,polje,kd); NAV;POLJE;NAV; lstrcat(")",komanda); ako (lstrlenA(polje)>4) { Konekcija(); rez:=SQLExecDirect(lstrlenA(komanda),komanda,shan); Diskonekcija(); } inace { MessageBoxA(0,"Greska","Kratak broj",0);} } cijeli funkcija Select() { karakter[500] komanda; karakter [2] navodnik; karakter [30] polje; cijeli rez,indikator; navodnik [0]:=39;navodnik[1]:=0; komanda[0]:=0; lstrcat( "SELECT IME,PREZIME,ADRESA,TELEFON FROM IMENIK WHERE 1=1 " ,komanda); GetWindowTextA(30,polje,ka); ako (lstrlenA(polje))>1 { lstrcat( " AND IME=",komanda);NAV;POLJE;NAV; } GetWindowTextA(30,polje,kb); ako (lstrlenA(polje))>1 { lstrcat( " AND PREZIME=",komanda);NAV;POLJE;NAV; } GetWindowTextA(30,polje,kc); ako (lstrlenA(polje))>1 { lstrcat( " AND ADRESA=",komanda);NAV;POLJE;NAV; } GetWindowTextA(30,polje,kd); ako (lstrlenA(polje))>1 { lstrcat( " AND TELEFON=",komanda);NAV;POLJE;NAV; } Konekcija(); rez:=SQLExecDirect(lstrlenA(komanda),komanda,shan); rez:=SQLFetch(shan); rez:=SQLGetData(&indikator,30,polje,SQLCHAR,1,shan); SetWindowTextA(polje,ka); rez:=SQLGetData(&indikator,30,polje,SQLCHAR,2,shan); SetWindowTextA(polje,kb); rez:=SQLGetData(&indikator,30,polje,SQLCHAR,3,shan); SetWindowTextA(polje,kc); rez:=SQLGetData(&indikator,30,polje,SQLCHAR,4,shan); SetWindowTextA(polje,kd); Diskonekcija(); } cijeli funkcija PraznaForma() { karakter [1] prazna; prazna[0]:=0; Sl. 12.1.2. cijeli funkcija WndProc(cijeli lParam,cijeli wParam,cijeli wMessage,cijeli hWnd) { cijeli obradjena; obradjena:=0; ako (wMessage=1) `WM_CREATE { ka:=CreateWindowExA(0,hInstance,0,hWnd,20,120,20,140, UOKVIRENO,0,"EDIT",0); kb:=CreateWindowExA(0,hInstance,0,hWnd,20,120,60,140, UOKVIRENO,0,"EDIT",0); kc:=CreateWindowExA(0,hInstance,0,hWnd,20,120,100,140, UOKVIRENO,0,"EDIT",0); kd:=CreateWindowExA(0,hInstance,0,hWnd,20,120,140,140, UOKVIRENO,0,"EDIT",0); ke:=CreateWindowExA(0,hInstance,0,hWnd,20,120,180,140, UOKVIRENO,"Nadji","BUTTON",0); kf:=CreateWindowExA(0,hInstance,0,hWnd,20,120,220,140, UOKVIRENO,"Unesi","BUTTON",0); kk:=CreateWindowExA(0,hInstance,0,hWnd,20,120,260,140, UOKVIRENO,"Prazna forma","BUTTON",0); kg:=CreateWindowExA (0,hInstance,0,hWnd,20,120,20,10, UOKVIRENO,"Ime ","STATIC",0); kh:=CreateWindowExA (0,hInstance,0,hWnd,20,120,60,10, UOKVIRENO,"Prezime ","STATIC",0); ki:=CreateWindowExA(0,hInstance,0,hWnd,20,120,100,10, UOKVIRENO,"Adresa ","STATIC",0); kj:=CreateWindowExA(0,hInstance,0,hWnd,20,120,140,10, UOKVIRENO,"Telefon ","STATIC",0); obradjena:=1; } ako (wMessage=2) `WM_QUIT {PostQuitMessage (0) ; obradjena:=1; } ako (wMessage=273) `WM_COMMAND { ako (lParam=ke) { Select(); } ako (lParam=kf) { Insert(); } ako (lParam=kk) { PraznaForma(); } obradjena:=1; } ako (obradjena=0) { DefWindowProcA lParam,wParam,wMessage,hWnd); } } { nCmdShow:=10; hInstance:=GetModuleHandleA (0); wndclass.cbsize:=48; wndclass.style := 0 ; wndclass.lpfnWndProc := WndProc ; wndclass.cbClsExtra := 0 ; wndclass.cbWndExtra := 0 ; wndclass.hInstance := hInstance ; wndclass.hIcon := 0 ; wndclass.hCursor := LoadCursorA (32512,0) ; wndclass.hbrBackground := GetStockObject(3); wndclass.lpszMenuName := 0; wndclass.lpszClassName := "PROBNA" ; wndclass.hIconSm:=0; ako (!(RegisterClassExA (&wndclass))) { 0 ; } inace { hWnd := CreateWindowExA ( 0,hInstance,0,0, 400,400,4,4,13565952, "ODBC Database Demo","PROBNA",512); ShowWindow ( nCmdShow,hWnd) ; UpdateWindow(hWnd) ; dok (GetMessageA (0, 0, 0,&msg)) { TranslateMessage (&msg) ; DispatchMessageA (&msg) ; } msg.wParam ; } } Datoteka ODBC.JEZ 83 cijeli funkcija RegisterClassExA(cijeli * wndclass); cijeli funkcija ShowWindow ( cijeli a,cijeli b) ; cijeli funkcija UpdateWindow(cijeli hWnd) ; cijeli funkcija GetMessageA (cijeli a, cijeli b, cijeli c,cijeli * d); cijeli funkcija TranslateMessage (cijeli * d) ; cijeli funkcija DispatchMessageA (cijeli * d) ; cijeli funkcija CreateWindowExA(cijeli a,cijeli b,cijeli c, cijeli d,cijeli e,cijeli f,cijeli g,cijeli h,cijeli i, karakter * j,karakter * k,cijeli l); cijeli funkcija LoadCursorA ( cijeli a,cijeli b) ; cijeli funkcija GetStockObject ( cijeli a) ; cijeli funkcija PostQuitMessage ( cijeli a) ; cijeli funkcija DefWindowProcA (cijeli a, cijeli b, cijeli c,cijeli d); cijeli funkcija MessageBoxA (cijeli a, karakter * b, karakter * c,cijeli d); cijeli funkcija GetModuleHandleA ( cijeli a) ; cijeli funkcija lstrcat ( karakter * a,karakter * b) ; cijeli funkcija GetWindowTextA (cijeli a, karakter * b,cijeli c); cijeli funkcija SetWindowTextA (karakter * b,cijeli c); cijeli * TargetValue,cijeli TargetType,cijeli ColumnNumber, cijeli StatementHandle); cijeli hWnd ; slog { cijeli hwnd; cijeli message; cijeli wParam; cijeli lParam; cijeli time; slog { cijeli x; cijeli y; } pt; } msg ; ` a message structure slog { cijeli cbsize; cijeli style; cijeli * lpfnWndProc; cijeli funkcija SQLAllocEnv(cijeli * EnvironHandle); cijeli cbClsExtra; cijeli funkcija SQLAllocConnect(cijeli * cijeli cbWndExtra; ConnectionHandle,cijeli EnvironHandle); cijeli hInstance; cijeli funkcija SQLDriverConnect(cijeli cijeli hIcon; DriverCompletion,cijeli * StringLengthDPtr, cijeli hCursor; cijeli BufferLength, cijeli * OutConnectionString, cijeli hbrBackground; cijeli StringLengthJ,cijeli * InConnectionString,cijeli karakter * lpszMenuName; WindowHandle, karakter * lpszClassName; cijeli ConnectionHandle); cijeli hIconSm; ` DRIVER={Microsoft Access Driver (*.mdb)};DBQ= } wndclass ; ` window class structure cijeli funkcija SQLAllocStmt(cijeli * StatementHandle,cijeli ConnectionHandle); cijeli nCmdShow; cijeli funkcija SQLExecDirect(cijeli TextLen,cijeli * karakter * lpszCmdLine; StatementText,cijeli StatementHandle); cijeli hPrevInstance; cijeli funkcija SQLDisconnect(cijeli ConnectionHandle); cijeli hInstance; cijeli funkcija SQLFreeConnect(cijeli ConnectionHandle); cijeli ka,kb,kc,kd,ke,kf,kg,kh,ki,kj,kk; cijeli funkcija lstrlenA (karakter * a); cijeli ehan,chan,shan; cijeli funkcija wvsprintfA(realni * broj,karakter * format, karakter * bafer ); #definiraj UOKVIRENO 1350631424 cijeli funkcija SQLFreeStmt(cijeli fOption,cijeli hstmt); #definiraj NAV lstrcat(navodnik,komanda) cijeli funkcija SQLFetch(cijeli StatementHandle); #definiraj POLJE lstrcat(polje,komanda) cijeli funkcija SQLGetData(cijeli * StrLenOrInd,cijeli #definiraj ZAREZ lstrcat(",",komanda) BufferLength, #definiraj SQLDRIVERPROMPT 2 #definiraj SQLCHAR 1 Sl. 12.1.3. 12.2. Datoteka ODBC.H Primjer: Multimedija Na slici Sl. 12.2.1 je dat prosti program koji šalje na zvučnik sadržaj WAV datoteke, koristeći funkciju PlaySound. Ovaj primjer ujedno ilustruje učitavanje dinamičkih biblioteka. Funkcija LoadLibraryA učitava cijelu dinamičku biblioteku, dok funkcija GetProcAddress vraća adresu pojedine procedure u njoj. cijeli * PlaySound; cijeli funkcija LoadLibraryA(karakter * ime); cijeli funkcija GetProcAddress(karakter * ime,cijeli hl); cijeli hl; { hl:=LoadLibraryA("WINMM.DLL"); PlaySound:=GetProcAddress("PlaySound",hl); PlaySound(131072,0,"c:\PJESMA.WAV"); } Sl. 12.2.1. 12.3. Datoteka sound.jez Primjer: Web Server U jeziku FILDZAN-32 napisan je mali Web server, sposoban da prikazuje statičke web stranice sa hiperlinkovima, na mašini, lokalnoj mreži ili Internetu. Web server koristi Winsock biblioteku, odnosno funkcije WSAStartup (inicijalizacija okruženja), WSACleanup (uklanjanje okruženja), accept (prihvatanje konekcije i njeno povezivanje s soketom), closesocket (uklanjanje soketa iz tabele), send (slanje podataka prijemnom soketu) , recv (prijem podatka od drugog soketa), socket (kreiranje krajnje tačke za komunikaciju i vraćanje soketa), listen (slušanje da li u konekciji nailazi neki soket i bind (dodjela lokalnog imena neimenovanom soketu). Listing programa dat je na slici Sl. 12.3.1. Princip Web servera je u suštini jednostavan. Nakon što je povezan soket da osluškuje port 80 (HTTP) očekuje se zahtjev od strane klijenta. U okviru ovog zahtjeva obično dolazi komanda GET praćena imenom datoteke i verzijom protokola. Nakon parsiranja imena, otvara se datoteka sa tim imenom i njen sadržaj se pošalje klijentskom soketu koristeći funkciju send. 84 #definiraj HTTPPORT 80 #definiraj CETRSTOCETIRI "HTTP/1.1\ 404 Content-Type: text/html \ <h1>Nema stranice</h1><hr><i>Ibrik\ Web Server, v1.0-(c) 2002-2003 by \ Kenan Kalajdzic" #definiraj CETRSTO "HTTP/1.1 400 \ Content-Type: text/html <h1>Bad \ Request</h1><hr><i>Ibrik Web \ Server, v1.0 - (c) 2002-2003 by \ Kenan Kalajdzic" #definiraj INDEXPAGE "/index.htm" #definiraj WEBDIR "D:/thp/%s" #definiraj METODLEN 16 #definiraj PAGELEN 256 #definiraj SOCKADDRIN slog { \ karakter fam1,fam2,port1,port2; \ cijeli inaddr; karakter [8] \ sinzero; } #definiraj BUFSIZE 1024 #definiraj SOCKET cijeli #definiraj SOCKSTREAM 1 #definiraj SOCKETERROR (-1) #definiraj INVALIDSOCKET (~0) #definiraj INADDRANY 0 #definiraj PFINET 2 #definiraj STRADDRINLEN 16 #definiraj FILEATTRIBUTENORMAL 128 #definiraj OPENEXISTING 3 #definiraj GENERICREAD 2147483648 #definiraj INVALIDHANDLEVALUE (-1) #definiraj WSADATA slog { cijeli \ wVersion;\ cijeli wHighVersion;\ karakter [257] szDescription;\ karakter [129] szSystemStatus;\ cijeli iMaxSocketsiMaxUdpDg;\ karakter * lpVendorInfo;} SOCKET sd, newsd; cijeli f,imebr; cijeli wsVersion; cijeli bytes, pos; karakter [BUFSIZE] buf; karakter * ptr, ptr2 ; SOCKADDRIN sin, rhost; cijeli rlen; cijeli dalje,petlja; WSADATA wsaData; cijeli funkcija WSAStartup (cijeli * adr,cijeli ver); cijeli funkcija WSACleanup (); cijeli funkcija GetVersion (); cijeli funkcija accept(cijeli * a,cijeli * b,cijeli c); cijeli funkcija closesocket(cijeli socket); cijeli funkcija send(cijeli a, cijeli b, karakter * c,cijeli d); cijeli funkcija socket(cijeli a,cijeli b,cijeli c); cijeli funkcija listen(cijeli a,cijeli b); cijeli funkcija bind(cijeli a,cijeli * sockp,cijeli sock); cijeli funkcija wvsprintfA(cijeli * kom,karakter * fmt,karakter * dest); cijeli funkcija CreateFileA(cijeli hTemplateFile, cijeli dwFlagsAndAttributes,cijeli dwCreationDisposition, karakter * lpSecurityAttributes, cijeli dwShareMode,cijeli dwDesiredAccess,karakter * lpFileName, ); cijeli funkcija ReadFile( cijeli lpOverlapped, cijeli * lpNumberOfBytesRead, cijeli nNumberOfBytesToRead, cijeli * lpBuffer, cijeli hFile); cijeli funkcija CloseHandle(cijeli hobject); cijeli funkcija MessageBoxA(cijeli opcije,karakter * poruka, karakter * naslov,cijeli handle);cijeli funkcija ExitProcess(cijeli kod); petlja :=1; bytes := 1; dok (bytes # 0 ) & petlja { dalje:=1; bytes := recv(0,BUFSIZE-pos, &buf[pos], newsd); ako (bytes = SOCKETERROR) { ako (closesocket(newsd) = SOCKETERROR) { errexit("closesocket"); } dalje :=0; } ako(hasnewline(buf)&dalje) { dalje := 0; petlja := 0; } ako dalje { pos := pos+bytes; } } getstr( req.page, getstr(req.method, buf, METODLEN),PAGELEN); dalje :=1; ako (lstrcmp("GET", req.method)){ dalje :=1; send(0,100,CETRSTO,newsd); ako (closesocket(newsd) = SOCKETERROR) { errexit("closesocket"); } dalje := 0; } ako(!lstrcmp("/",req.page)& dalje) { lstrcpy(INDEXPAGE,req.page); } ako dalje { imebr:=req.page; imebr:=imebr+1; wvsprintfA(&imebr,WEBDIR,buf); f := CreateFileA(0, FILEATTRIBUTENORMAL, OPENEXISTING,0,0, GENERICREAD,buf); ako f = INVALIDHANDLEVALUE { send(0,80, CETRSTOCETIRI,newsd); ako (closesocket(newsd)<0){ errexit("closesocket"); } dalje:=0; } inace { petlja:=1; dok (petlja ) { ako (!ReadFile(0,&bytes, BUFSIZE,buf,f)) { petlja:=0; } ako (bytes = 0) { petlja:=0; } ako petlja { ako send(0,bytes,buf, newsd) =SOCKETERROR) { petlja:=0; } } } ako (!CloseHandle(f)) { errexit("CloseHandle"); } } ako (closesocket(newsd) = SOCKETERROR) { errexit("closesocket"); } } } cijeli funkcija recv(cijeli a,cijeli b,cijeli * c,cijeli sock); cijeli funkcija lstrcmp(karakter * a,karakter * b); cijeli funkcija lstrcpy(karakter * a,karakter * b); slog { karakter [METODLEN] method; karakter [PAGELEN] page; } req; cijeli funkcija hasnewline(karakter * ptr) { cijeli ima,n; ima:=0; dok (* ptr # 0) & (ima =0) { ako (* ptr = 13) { * ptr := 0; ima:=1; } ptr:=&(ptr[1]); } n:=ima; } karakter * funkcija getstr(karakter * dest, karakter * src, cijeli max) { karakter * rez; karakter m; max := max-1; dok ( src[0] # ' ') & (max >0) { dest[0] := src[0]; src := &(src[1]); dest := &(dest[1]); max := max-1; } * dest := 0; rez := &(src[1]); } cijeli funkcija errexit(karakter * title) { MessageBoxA(0,"Upozorenje", title,0); WSACleanup(); ExitProcess(-1); } { ako (GetVersion() < 2147483648) { wsVersion := 2; ` Win NT } inace { wsVersion := 257; ` Win 9x } ako (WSAStartup (&wsaData,wsVersion )){ errexit("WSAStartup"); } sd:= socket(0,SOCKSTREAM,PFINET); ako (sd=INVALIDSOCKET) { errexit("socket"); } sin.fam1 := PFINET; sin.fam2 := 0; sin.port1 := 0; sin.port2 := HTTPPORT; sin.inaddr := INADDRANY; ako (bind(STRADDRINLEN,&sin,sd)= SOCKETERROR){ errexit("bind"); } ako (listen(1,sd)=SOCKETERROR) { errexit("listen"); } dok (1 ) { rlen := STRADDRINLEN; newsd:=accept(&rlen,&rhost,sd); ako (newsd= INVALIDSOCKET) { errexit("accept"); } pos := 0; bytes :=0; dok (bytes < BUFSIZE) { buf[bytes]:=0; bytes := bytes+1; } Sl. 12.3.1. Web server } 85 12.4. Primjer: Numerička analiza Pogledati primjer “Metoda sekante” na slici Sl. 9.7.1 s obzirom da se očuvala kompatibilnost sa tom verzijom kompajlera. 12.5. Rezime poglavlja Završni primjeri pokazuju zrelost koju je jezik dostigao. Unatoč jednostavnom optimizatoru i kompajleru, izvršne verzije svih testnih programa su dužine ispod 10 kilobajta. Raznovrsnost oblasti a već odlično demonstrira da se ovim kompajlerom mogu praviti gotovo sve klasične aplikacije. Testni primjeri su poslužili za otkrivanje grešaka u kompajleru, ali i pokazali da je sa ovom verzijom jezika moguće praviti aplikacije iz oblasti korisničkog interfejsa, baza podataka, multimedije, dvodimenzionalne i trodimenzionalne grafike, lokalnih i globalnih mreža, numeričke analize i gotovo svih drugih oblasti softvera. FILDZAN-32 definitivno nije najjednostavniji programski jezik za realizaciju ovih aplikacija, ali je jedan od rijetkih koji pruža uvid u internu implementaciju softvera. 86 Prilog 8: Verzija izvornog koda kompajlera br. 8, glavni program program Kompajler; uses predpr8, postpr8; const MAXIDENT = 1024; MAXDIM = 10; DUGAKONST = 'Konstanta prevazilazi liniju'; REALKONST = 'Realna konstanta'; OCEKIVANO = 'Ocekivano '; REDEKLAR = 'Redeklarisan identifikator'; PROSTNIZ = 'Prosti tip ne moze biti niz'; NEKORARG = 'Nekorektan broj argumenata'; NEKDODJP = 'Losa dodjela pointeru'; NEDEKL = 'Nedeklarisano '; GRIZRAZ = 'Izraz'; POGRMNOZ = 'Pogresan tip u ' + 'mnozenju ili dijeljenju'; NEDOPFP = ' Nedopustena FP operacija'; NEDOPARIT = 'Nedopusteni tip u aritmetici'; OCEKDOD = 'Ocekivano dodjeljivanje'; NEDODJ = 'Izraz se ne moze dodijeliti'; DODJPOINT = 'Losa dodjela pointeru'; TIPUSL = 'Neodgovarajuci tip uslova'; TUSLPET = 'Neodgovarajuci uslov u petlji'; IMEFUN = 'Ocekivano ime funkcije'; DEFFUN = 'Definicija funkcije'; ARGNEKOM = 'Argument nekompatibilan' + ' s operatorom'; OCIDENT = 'Ocekivan Identifikator'; MAXDIMOV = 'Maksimalan broj dimenzija'; INDSTATC = 'Indeks statickog niza nije cijeli'; PREVDIM = 'Prevazidjen broj dimenzija'; NESLDIM = 'Ne slaze se broj dimenzija'; POLJEPOS = 'Polje vec postoji'; SLOGPOLJE = 'Samo slogovi mogu imati polja'; NEDEKPOLJE = 'Nedeklarisano polje'; SLOGSLOGU = 'Slog se moze dodijeliti samo slogu'; SLOGRAZDUZ = 'Slogovi razlicite duzine'; INDNOPOINT = 'Indirektna funkcija bez pointera'; SLOGNEPOR = 'Slogovi se ne mogu porediti'; type TVrsta = (funkcija, lokalna, globalna, parametar, polje); TTip = (karakter, cijeli, realni, slog, pkarakter, pcijeli, prealni, pslog); TIdent = record ime: string[20]; duzina: integer; adresa: integer; nivo: integer; vrsta: TVrsta; tip: TTip; pod1: integer; pod2: integer; pod3: integer; ukupdim: integer; dim: array[0..MAXDIM] of integer; end; TZadnjiSlog = record duzina: integer; pozimena: integer; idopisasloga: integer end; var trenlabela, aktnivo: integer; realnakonstanta: string; TabIdent: array[0..MAXIDENT] of TIdent; ukupnoident, ukupnoslogova, ukdim: integer; t: TTip; dod: Boolean; zadnji: TZadnjiSlog; dimenzije: array[0..MAXDIM] of integer; procedure NoviIdent(pime: string; pduzina: integer; padresa: integer; pnivo: integer; pvrsta: TVrsta; ptip: TTip; ppod1: integer; ppod2: integer; ppod3: integer); var i: integer; begin ukupnoident := ukupnoident + 1; with TabIdent[ukupnoident] do begin ime := pime; duzina := pduzina; adresa := padresa; nivo := pnivo; vrsta := pvrsta; tip := ptip; pod1 := ppod1; pod2 := ppod2; pod3 := ppod3; ukupdim := ukdim; for i := 0 to MAXDIM do dim[i] := dimenzije[i]; end; end; procedure NovaLabela(var ImeLabele: string); begin trenlabela := trenlabela + 1; Str(trenlabela, ImeLabele); end; procedure Greska(poruka: string); begin WriteLn(poruka); WriteLn(brojaclinija, ':', linija); Close(ulaz); Close(izlaz); Halt; end; procedure NoviSvaki(greskakrln: Boolean); begin pozicija := pozicija + 1; if pozicija > Length(linija) then begin if greskakrln then Greska(DUGAKONST) else znak := ' '; end else znak := linija[pozicija]; end; procedure IdiDo(z: char); begin if (znak <> z) then Greska(OCEKIVANO + z); Novi; end; + znak; NoviSvaki(false); while (znak >= '0') and (znak <= '9') do begin realnakonstanta := realnakonstanta + znak; NoviSvaki(false); end; end; if (znak = 'e') or (znak = 'E') then begin realnakonstanta := realnakonstanta + znak; NoviSvaki(false); if (znak = '+') or (znak = '-') then begin realnakonstanta := realnakonstanta + znak; NoviSvaki(false); end; if (znak < '0') or (znak > '9') then Greska(REALKONST); while (znak >= '0') and (znak <= '9') do begin realnakonstanta := realnakonstanta + znak; NoviSvaki(false); end; end; UzmiKonstantu := 0; t := realni; end else begin UzmiKonstantu := rezultat; t := cijeli; end; if (znak = ' ') or (znak = '`') then Novi; dod := false; end; function Slijedi(ocekivano: string; dslovoiza: Boolean): Boolean; var ureduiza: Boolean; n: integer; znak: char; begin if dslovoiza then ureduiza := true else begin n := pozicija + Length(ocekivano); ureduiza := true; if Length(linija) >= n then begin znak := linija[n]; if ((znak >= 'a') and (znak <= 'z')) or ((znak >= 'A') and (znak <= 'Z')) then ureduiza := false end end; if ureduiza and (copy(linija, pozicija, Length(ocekivano)) = ocekivano) then begin Slijedi := true; pozicija := pozicija + Length(ocekivano) - 1; end else Slijedi := false; end; function UzmiKonstantu (var t: TTip; var dod: Boolean): integer; var function TipDek(imetipa: string; var rezultat: integer; tip: TTip; begin stip, ptip: TTip): Boolean; rezultat := 0; var realnakonstanta := ''; tipind: TTip; while (znak >= '0') and (znak <= '9') kraj, x, poi: Boolean; do begin begin rezultat := 10 * rezultat + TipDek := false; ord(znak) - ord('0'); poi := false; realnakonstanta := realnakonstanta if Slijedi(imetipa, false) then begin + znak; TipDek := true; NoviSvaki(false); Novi; end; if znak = '*' then begin if (znak = '.') or (znak = 'e') or tip := ptip; (znak = 'E') then begin poi := true; if znak = '.' then begin Novi realnakonstanta := realnakonstanta 87 end else tip := stip; ukdim := 0; if znak = '[' then begin if poi then tip := pcijeli else tip := ptip; IdiDo('['); repeat ukdim := ukdim + 1; if ukdim > MAXDIM then Greska(MAXDIMOV); dimenzije[ukdim] := UzmiKonstantu(tipind, x); if tipind <> cijeli then Greska(INDSTATC); kraj := true; if znak = ',' then begin Novi; kraj := false; end; until kraj; IdiDo(']'); end; end end; function SlijediDekTipa(var tip: TTip): Boolean; var a: Boolean; begin a := false; if not (a) then a := TipDek('cijeli', tip, cijeli, pcijeli); if not (a) then a := TipDek('karakter', tip, karakter, pkarakter); if not (a) then a := TipDek('realni', tip, realni, prealni); if not (a) then a := TipDek('slog', tip, slog, pslog); SlijediDekTipa := a; end; (TabIdent[n].vrsta in [lokalna, globalna, parametar, funkcija]) and ((TabIdent[n].nivo = nivo) or (TabIdent[n].nivo = 0)); 2: Uslov := (TabIdent[n].ime = ident) and (TabIdent[n].vrsta in [lokalna, globalna, parametar, funkcija]) and ((TabIdent[n].nivo = nivo)); 3: Uslov := (TabIdent[n].ime = ident) and (TabIdent[n].vrsta = polje) and (TabIdent[n].nivo = nivo) and (TabIdent[n].pod3 = p1); 4: Uslov := (TabIdent[n].nivo = nivo) and (TabIdent[n].pod2 = p1) and (TabIdent[n].vrsta = parametar) else Uslov := false; end; if Uslov then begin nadjen := true; poz := n; end; n := n - 1; end; NadjiIdent := poz; end; procedure UzmiIdent(var ident: string); begin if znak in ['a'..'z', 'A'..'Z'] then begin ident := znak; NoviSvaki(false); end else Greska(OCIDENT); while (znak in ['a'..'z', 'A'..'Z', '0'..'9', '_']) do begin ident := ident + znak; NoviSvaki(false); end; if (znak = ' ') or (znak = '`') then Novi; end; Emit(' MOV EAX,EBX'); until znak <> ','; Emit(' POP EBX'); if (navdim <> TabIdent[idpoz].ukupdim) and (not ((navdim = 1) and (TabIdent[idpoz].ukupdim = 0))) then Greska(NESLDIM); IdiDo(']'); case t of pkarakter: begin t := karakter; end; pcijeli: begin Emit(' SAL EAX,2'); t := cijeli; end; prealni: begin Emit(' FSTP ST(0)'); Emit(' SAL EAX,3'); t := realni; end; pslog: begin t := slog; Str(DuzinaTipa(t), st); Emit(' MOV EDX,' + st); Emit(' MUL EDX'); end; else Greska(PROSTNIZ) end; Emit(' ADD EBX,EAX'); case t of karakter: Emit(' MOV AL,[EBX]'); realni: Emit(' FLD QWORD PTR [EBX]') else Emit(' MOV EAX,[EBX]'); end; dod := true; end; procedure StringKonstanta(var t: TTip; var dod: Boolean); var st, strtekst: string; begin NovaLabela(strtekst); Emit('.DATA'); st := 'L' + strtekst + ' DB '''; repeat function DuzinaTipa(tip: TTip): NoviSvaki(true); procedure DeklIdent(var ident: string; Integer; if znak <> '"' then nivo: integer); var st := st + znak; begin elem, i: integer; until znak = '"'; UzmiIdent(ident); begin IdiDo('"'); if NadjiIdent(ident, nivo, 2, 0) <> 0 case tip of st := st + ''',0'; then cijeli: DuzinaTipa := 4; if copy(st, length(st) - 3, 2) = Greska(REDEKLAR); pcijeli, pkarakter, prealni, pslog: '''''' then end; begin st := 'L' + strtekst + ' DB 0'; if ukdim = 0 then Emit(st); procedure IzrazDodjeljivanja DuzinaTipa := 4 Emit('.CODE'); (var t: TTip; var dod: Boolean); else begin Emit(' MOV EAX,OFFSET L' + strtekst); forward; elem := 4*ord(tip = pcijeli)+ t := pkarakter; procedure Blok; forward; 1 * ord(tip = pkarakter) + dod := false; 8 * ord(tip = prealni) + procedure PokazivacINiz(var t: TTip; var end; zadnji.duzina * ord(tip = dod: Boolean; idpoz: Integer); pslog); var for i := 1 to ukdim do procedure PEmit(idpoz: Integer); t1: TTip; elem := elem * dimenzije[i]; var navdim,dsvedim,i: Integer; DuzinaTipa := elem; i: integer; st: string; end begin begin end; if TabIdent[idpoz].ukupdim = 0 then navdim := 0; karakter: DuzinaTipa := 1; Emit(' MOV EAX,[EBX]') Emit(' PUSH EAX'); realni: DuzinaTipa := 8; else Emit(' MOV EAX,0'); slog: DuzinaTipa := zadnji.duzina; Emit(' MOV EAX,EBX'); repeat else ukdim := TabIdent[idpoz].ukupdim; Novi; DuzinaTipa := 4; for i := 0 to MAXDIM do navdim := navdim + 1; end; dimenzije[i] := if navdim > MAXDIM then end; TabIdent[idpoz].dim[i]; Greska(PREVDIM); end; Emit(' PUSH EAX'); function NadjiIdent(ident: string; IzrazDodjeljivanja(t1, dod); nivo, tuslova, p1: integer): integer; function DeklaracijaSloga(nivo: Emit(' POP EBX'); var integer): integer; if znak = ',' then begin n, poz: integer; var dsvedim:=1; nadjen, Uslov: Boolean; ImePolja: string; for i:=navdim+1 to begin oznakasloga, podslog, duzinasloga, TabIdent[idpoz].ukupdim do n := ukupnoident; zapukdim, i, poz: integer; dsvedim:=dsvedim* nadjen := false; tip: TTip; TabIdent[idpoz].dim[i]; poz := 0; imaistogtipa: Boolean; Str(dsvedim, st); while (n > 0) and (not (nadjen)) do zdimenzije: array[0..MAXDIM] of Emit(' MOV EDX,' + st); begin integer; Emit(' MUL EDX'); case tuslova of begin end; 1: Uslov := (TabIdent[n].ime = zapukdim := ukdim; Emit(' ADD EBX,EAX'); ident) and 88 for i := 0 to MAXDIM do zdimenzije[i] := dimenzije[i]; IdiDo('{'); ukupnoslogova := ukupnoslogova + 1; oznakasloga := ukupnoslogova; duzinasloga := 0; poz := 0; while SlijediDekTipa(tip) do begin if (tip = slog) or (tip = pslog) then podslog := DeklaracijaSloga(nivo) else podslog := oznakasloga; repeat UzmiIdent(ImePolja); poz := NadjiIdent(ImePolja, nivo, 3, podslog); if poz <> 0 then Greska(POLJEPOS); NoviIdent(ImePolja, DuzinaTipa(tip), 0, nivo, polje, tip, podslog, duzinasloga, oznakasloga); duzinasloga := duzinasloga + DuzinaTipa(tip); imaistogtipa := true; if znak = ',' then begin Novi; imaistogtipa := false; end; until imaistogtipa; while (duzinasloga mod 4) <> 0 do duzinasloga := duzinasloga + 1; IdiDo(';'); end; IdiDo('}'); zadnji.duzina := duzinasloga; zadnji.pozimena := poz; zadnji.idopisasloga := OznakaSloga; DeklaracijaSloga := OznakaSloga; ukdim := zapukdim; for i := 0 to MAXDIM do dimenzije[i] := zdimenzije[i]; end; procedure ElementSloga (idpoz: integer; var t: TTip; var dod: Boolean); var poz, nivo, idsloga: integer; Imepolja, st: string; begin if t <> slog then Greska(SLOGPOLJE); nivo := TabIdent[idpoz].nivo; idsloga := TabIdent[idpoz].pod3; while znak = '.' do begin Novi; UzmiIdent(ImePolja); poz := NadjiIdent(ImePolja, nivo, 3, idsloga); if poz = 0 then Greska(NEDEKPOLJE); Str(TabIdent[poz].pod2, st); Emit(' ADD EBX,' + st); t := TabIdent[poz].tip; case t of karakter: Emit(' MOV AL,[EBX]'); realni: Emit(' FLD QWORD PTR [EBX]'); slog: begin idsloga := TabIdent[poz].pod1; zadnji.duzina := TabIdent[poz].duzina; zadnji.pozimena := poz; zadnji.idopisasloga := TabIdent[poz].pod3; end; cijeli: Emit(' MOV EAX,[EBX]'); else PEmit(poz); end; end; end; procedure CijeliNaFPStek(reg: string; osmobitni: Boolean); begin if osmobitni then Emit(' AND ' + reg + ',0FFh'); Emit(' MOV INTTOFP,' + reg); Emit(' FILD DWORD PTR INTTOFP'); end; procedure FPStekUCijeli(reg: string); begin Emit(' ADD ESP,-4'); Emit(' FISTP DWORD PTR [ESP]'); Emit(' POP ' + reg); end; procedure CPUStekCijeliNaFPStek(osmobitni: Boolean); begin if osmobitni then Emit(' AND DWORD PTR [ESP],0FFh'); Emit(' FILD DWORD PTR [ESP]'); Emit(' ADD ESP,4'); end; procedure FPUStekNaStek; begin Emit(' ADD ESP,-8'); Emit(' FSTP QWORD PTR [ESP]'); end; procedure StekNaFPUStek; begin Emit(' FLD QWORD PTR [ESP]'); Emit(' ADD ESP,8'); end; procedure PozivFunkcije (idpoz: integer; var t: TTip; var dod: Boolean); var parametara, N, velsteka, duzprvogsloga, duzdrugogsloga, m1: integer; t1, t2: TTip; ImeFunkcije, st: string; begin ImeFunkcije := TabIdent[idpoz].ime; parametara := 0; velsteka := 0; duzprvogsloga := 0; duzdrugogsloga := 0; if znak <> '(' then begin velsteka := 0; for parametara := 1 to TabIdent[idpoz].pod1 do begin n := NadjiIdent('', idpoz, 4, parametara); velsteka := velsteka + ( (TabIdent[n].duzina - 1) div 4 + 1) * 4; end; Str(velsteka, st); Emit(' MOV EAX,OFFSET ' + imefunkcije + '@' + st); t := pcijeli; dod := false; end else begin IdiDo('('); while (znak <> ')') do begin IzrazDodjeljivanja(t1, dod); if t1 = slog then duzprvogsloga := DuzinaTipa(t1); parametara := parametara + 1; n := NadjiIdent('', idpoz, 4, parametara); if n = 0 then Greska(NEKORARG); t2 := TabIdent[n].tip; if t2 = slog then duzdrugogsloga := TabIdent[n].duzina; if (t1 in [karakter, realni]) and (t2 in [pkarakter, pcijeli, prealni]) then Greska(NEKDODJP); if (t1 = karakter) and (t2 = cijeli) then Emit(' AND EAX,0FFh'); if ((t1 = slog) and (t2 <> slog)) or ((t1 <> slog) and (t2 = slog)) then Greska(SLOGSLOGU); case t2 of slog: begin if duzprvogsloga <> duzdrugogsloga then Greska(SLOGRAZDUZ); m1 := ((duzprvogsloga - 1) div 4 + 1) * 4; velsteka := velsteka + m1; Str(duzprvogsloga, st); Emit(' MOV ECX,' + st); Str(m1, st); Emit(' SUB ESP,' + st); Emit(' MOV ESI,EBX'); Emit(' MOV EDI,ESP'); Emit(' CLD'); Emit(' REP MOVSB'); end; realni: begin velsteka := velsteka + 8; case t1 of realni: ; karakter: CijeliNaFPStek('EAX', true); else CijeliNaFPStek('EAX', false); end; FPUStekNaStek; end else begin velsteka := velsteka + 4; if t1 = realni then FPStekUCijeli('EAX'); Emit(' PUSH EAX'); end; end; if znak <> ')' then IdiDo(','); end; IdiDo(')'); if TabIdent[idpoz].pod1 <> parametara then Greska(NEKORARG); Str(velsteka, st); Emit(' MOV ECX,' + st); Emit(' CALL ' + ImeFunkcije + '@' + st); dod := false; t := TabIdent[idpoz].tip; if t = karakter then Emit(' AND EAX,0FFh'); end; end; procedure IndirektniPoziv(var t: TTip); var m1, velsteka, duzsloga: Integer; straddr, st: string; t1: TTip; begin velsteka := 0; NovaLabela(straddr); Emit('.DATA'); st := 'L' + straddr + ' DD ?'; Emit(st); Emit('.CODE'); Emit(' MOV L' + straddr + ',EAX'); IdiDo('('); while (znak <> ')') do begin IzrazDodjeljivanja(t1, dod); case t1 of slog: begin duzsloga := DuzinaTipa(t1); m1 := ((duzsloga - 1) div 4 + 1) * 4; velsteka := velsteka + m1; Str(duzsloga, st); Emit(' MOV ECX,' + st); Str(m1, st); Emit(' SUB ESP,' + st); Emit(' MOV ESI,EBX'); Emit(' MOV EDI,ESP'); Emit(' CLD'); Emit(' REP MOVSB'); end; realni: begin velsteka := velsteka + 8; FPUStekNaStek; end else begin velsteka := velsteka + 4; Emit(' PUSH EAX'); end; end; if znak <> ')' then IdiDo(','); end; IdiDo(')'); 89 Str(velsteka, st); Emit(' MOV ECX,' + st); Emit(' CALL L' + straddr); case t of pcijeli: t := cijeli; prealni: t := realni; pkarakter: t := karakter; pslog: t := slog; else Greska(INDNOPOINT) end; end; procedure Varijabla (idpoz: integer; var t: TTip; var dod: Boolean; glob: Boolean); var rezultat: integer; st: string; begin rezultat := TabIdent[idpoz].adresa; t := TabIdent[idpoz].tip; Str(rezultat, st); if glob then Emit(' LEA EBX,GLOBALV[' + st + ']') else begin if rezultat >= 0 then Emit(' LEA EBX,[EBP+' + st + ']') else Emit(' LEA EBX,[EBP' + st + ']'); end; case t of karakter: Emit(' MOV AL,[EBX]'); realni: Emit(' FLD QWORD PTR [EBX]'); slog: begin zadnji.duzina := TabIdent[idpoz].duzina; zadnji.pozimena := idpoz; zadnji.idopisasloga := TabIdent[idpoz].pod3; end; pslog: begin rezultat:=1; for i:=1 to TabIdent[idpoz]. ukupdim do rezultat:=rezultat* TabIdent[idpoz].dim[i]; if rezultat<>0 then zadnji.duzina := TabIdent[idpoz]. duzina div rezultat else zadnji.duzina:=4; zadnji.pozimena := idpoz; zadnji.idopisasloga := TabIdent[idpoz].pod3; PEmit(idpoz); end; cijeli: Emit(' MOV EAX,[EBX]'); else PEmit(idpoz); end; if TabIdent[idpoz].ukupdim = 0 then dod := true else dod := false; while znak ='[' do begin PokazivacINiz(t, dod, idpoz); end; if znak = '(' then IndirektniPoziv(t); end; procedure Faktor(var t: TTip; var dod: Boolean); var rezultat, poz: integer; st, fpkonst, ime, err: string; begin err := ARGNEKOM; case znak of '-': begin Novi; Faktor(t, dod); case t of cijeli: Emit(' NEG EAX'); realni: Emit(' FCHS'); else Greska(err); end; dod := false; end; '~': begin Novi; Faktor(t, dod); case t of cijeli: Emit(' NOT EAX'); karakter: Emit(' NOT AL'); else Greska(err); end; dod := false; end; '&': begin Novi; Faktor(t, dod); Emit(' MOV EAX,EBX'); case t of cijeli: t := pcijeli; karakter: t := pkarakter; slog: t := pslog; realni: begin t := prealni; Emit(' FSTP ST(0)'); end; else t := pcijeli; end; dod := false; end; '*': begin Novi; Faktor(t, dod); Emit(' MOV EBX,EAX'); if t = prealni then begin Emit(' FSTP ST(0)'); Emit(' FLD QWORD PTR [EBX]'); end else Emit(' MOV EAX,[EBX]'); case t of pcijeli: t := cijeli; pkarakter: begin t := karakter; Emit(' AND EAX,0FFh'); end; prealni: t := realni; pslog: begin t := slog; end; else Greska(err); end; dod := true; end; '!': begin Novi; Faktor(t, dod); case t of cijeli: Emit(' CMP EAX,0'); karakter: Emit(' CMP AL,0'); else Greska(err); end; Emit(' SETE AL'); Emit(' AND EAX,0FFh'); dod := false; t := cijeli; end; '"': begin StringKonstanta(t, dod); end; '''': begin NoviSvaki(true); Emit(' MOV AL,''' + znak + ''''); Novi; IdiDo(''''); t := karakter; end; '0'..'9': begin rezultat := UzmiKonstantu(t, dod); case t of cijeli: begin Str(rezultat, st); Emit(' MOV EAX,' + st); end; realni: begin NovaLabela(fpkonst); Emit('.DATA'); st := 'L' + fpkonst + ' DQ '+realnakonstanta; Emit(st); Emit('.CODE'); Emit(' FLD L' + fpkonst); end; end; end; '(': begin Novi; IzrazDodjeljivanja(t, dod); IdiDo(')'); end; 'A'..'Z', 'a'..'z': begin UzmiIdent(ime); poz := NadjiIdent(ime, aktnivo, 1, 0); if poz = 0 then Greska(NEDEKL + ime); case TabIdent[poz].vrsta of funkcija: PozivFunkcije(poz, t, dod); lokalna, parametar: Varijabla(poz, t, dod, false); globalna: Varijabla(poz, t, dod, true) end end; else Greska(GRIZRAZ); end; if znak = '.' then ElementSloga(zadnji.pozimena,t,pod); end; procedure Clan(var t: TTip; var dod: Boolean); var z: char; t1, t2: TTip; begin Faktor(t1, dod); t := t1; while (znak in ['*', '/', '%']) do begin z := znak; if t1 <> realni then Emit(' PUSH EAX') else FPUStekNaStek; Novi; Faktor(t2, dod); dod := false; if (not (t1 in [cijeli, karakter, realni])) or (not (t2 in [cijeli, karakter, realni])) then Greska(POGRMNOZ); if (t1 = realni) or (t2 = realni) then begin t := realni; if t2 <> realni then CijeliNaFPStek('EAX', t2 = karakter); if t1 <> realni then CPUStekCijeliNaFPStek(t1 = karakter) else StekNaFPUStek; case z of '*': Emit(' FMUL '); '/': Emit(' FDIVR '); else Greska(NEDOPFP); end end else begin t := cijeli; case z of '*': begin Emit(' POP EBX'); if t1 = karakter then Emit(' AND EBX,0FFh'); if t2 = karakter then Emit(' AND EAX,0FFh'); Emit(' IMUL EBX'); end; '/', '%': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); Emit(' CDQ'); if t1 = karakter then Emit(' AND EAX,0FFh'); if t2 = karakter then Emit(' AND EBX,0FFh'); Emit(' IDIV EBX'); if z = '%' then Emit(' MOV EAX,EDX'); end; 90 if t2 <> realni then CijeliNaFPStek('EAX', t2 = karakter); if t1 <> realni then CijeliNaFPStek('EBX', t1 = karakter) else procedure Izraz(var t: TTip; var dod: StekNaFPUStek; procedure IzrazDodjeljivanja Boolean); Emit(' FCOMPP '); (var t: TTip; var dod: Boolean); var Emit(' FSTSW AX'); var z: char; Emit(' SAHF'); z: char; t1, t2: TTip; case z of t1, t2: TTip; begin '=': Emit(' SETE AL'); dod1: Boolean; Clan(t1, dod); '>': Emit(' SETA AL'); duzprvogsloga, duzdrugogsloga: t := t1; '<': Emit(' SETB AL'); Integer; while (znak in ['+', '-', '&', '|', '#': Emit(' SETNE AL'); st: string; '^']) do begin end; begin if t1 <> realni then Emit(' AND EAX,0FFh'); duzprvogsloga := 0; Emit(' PUSH EAX') t := cijeli; duzdrugogsloga := 0; else end Izraz(t1, dod1); FPUStekNaStek; else begin if t1 = slog then z := znak; if (t1 = karakter) and (t2 = duzprvogsloga := DuzinaTipa(t1); Novi; karakter) then t := t1; Clan(t2, dod); Emit(' CMP BL,AL') dod := dod1; dod := false; else begin case znak of if (not (t1 in [cijeli, karakter, if t1 = karakter then ':': begin realni])) or Emit(' AND EAX,0FFh'); if not (Slijedi(':=', true)) (not (t2 in [cijeli, karakter, if t2 = karakter then then realni])) then Emit(' AND EBX,0FFh'); Greska(OCEKDOD); Greska(NEDOPARIT); Emit(' CMP EBX,EAX'); if not (dod1) then if (t1 = realni) or (t2 = realni) end; Greska(NEDODJ); then begin case z of Emit(' PUSH EBX'); t := realni; '=': Emit(' SETE AL'); if (t1 = realni) then if t2 <> realni then '>': Emit(' SETG AL'); Emit(' FSTP ST(0)'); CijeliNaFPStek('EAX', t2 = '<': Emit(' SETL AL'); Novi; karakter); '#': Emit(' SETNE AL'); IzrazDodjeljivanja(t2, dod); if t1 <> realni then end; if t2 = slog then CPUStekCijeliNaFPStek(t1 = Emit(' AND EAX,0FFh'); duzdrugogsloga := karakter) t := cijeli; DuzinaTipa(t2); else end; if ((t1 = slog) and (t2 <> StekNaFPUStek; end slog)) or case z of end; ((t1 <> slog) and (t2 = slog)) '+': Emit(' FADD '); end; then '-': Emit(' FSUBR '); Greska(SLOGSLOGU); else procedure Uslov; if t1 = slog then begin Greska(NEDOPFP); var if duzprvogsloga <> end sonda, sinace, skrajuslova: string; duzdrugogsloga then end begin Greska(SLOGRAZDUZ); else begin Novi; Emit(' POP EDI'); case z of IzrazDodjeljivanja(t, dod); Emit(' MOV ESI,EBX'); '+': begin if t <> cijeli then Emit(' CLD'); Emit(' POP EBX'); Greska(TIPUSL); Str(duzprvogsloga, st); if (t1 = karakter) and (t2 Emit(' CMP EAX,0'); Emit(' MOV ECX,' + st); = karakter) then begin NovaLabela(sonda); end t := karakter; NovaLabela(sinace); else Emit(' ADD AL,BL'); NovaLabela(skrajuslova); Emit(' POP EBX'); end Emit(' JNE L' + sonda); if (t2 in [karakter, realni]) else begin Emit(' JMP L' + sinace); and t := cijeli; IdiDo('{'); (t1 in [pkarakter, pcijeli, if t1 = karakter then Emit('L' + sonda + ':'); prealni]) then Emit(' AND EBX,0FFh'); Blok; Greska(DODJPOINT); if t2 = karakter then Emit(' JMP L' + skrajuslova); if (t1 = realni) and (t2 <> Emit(' AND EAX,0FFh'); Emit('L' + sinace + ':'); realni) then Emit(' ADD EAX,EBX'); if Slijedi('inace', false) then begin CijeliNaFPStek('EAX', t2 = end; Novi; karakter); end; IdiDo('{'); if (t1 <> realni) and (t2 = '-': begin Blok; realni) then Emit(' MOV EBX,EAX'); end; FPStekUCijeli('EAX'); Emit(' POP EAX'); Emit('L' + skrajuslova + ':'); case t1 of if (t1 = karakter) and (t2 end; karakter: = karakter) then begin Emit(' MOV [EBX],AL'); t := karakter; procedure Asembler; realni: Emit(' SUB AL,BL'); Emit(' FSTP QWORD PTR[EBX]'); begin end repeat slog: Emit(' REP MOVSB'); else begin ReadLn(ulaz, linija); else t := cijeli; if linija <> '\' then Emit(' MOV [EBX],EAX'); if t1 = karakter then Emit(linija); end; Emit(' AND EAX,0FFh'); if eof(ulaz) then t := t1; if t2 = karakter then linija := '\'; end; {:} Emit(' AND EBX,0FFh'); until linija[1] = '\'; '=', '>', '<', '#': begin Emit(' SUB EAX,EBX'); pozicija := 1; if t1 <> realni then end; znak := linija[pozicija]; Emit(' PUSH EAX') end; IdiDo('\'); else '&', '|', '^': begin end; FPUStekNaStek; if (t1 = karakter) and (t2 z := znak; = karakter) then procedure Petlja; Novi; t := karakter var Izraz(t2, dod); else sdok, skrajpetlje, suslov: string; if (t1 = slog) or (t2 = slog) t := cijeli; begin then Emit(' POP EBX'); Novi; Greska(SLOGNEPOR); case z of NovaLabela(suslov); if t1 <> realni then '&': Emit(' AND EAX,EBX'); Emit('L' + suslov + ':'); Emit(' POP EBX'); '|': Emit(' OR EAX,EBX'); IzrazDodjeljivanja(t, dod); if (t1 = realni) or (t2 = '^': Emit(' XOR EAX,EBX'); if t <> cijeli then realni) then begin end; end; end; t1 := t; end; end; end; end; end; t1 := t; end; end; 91 Greska(TUSLPET); Emit(' CMP EAX,0'); NovaLabela(sdok); NovaLabela(skrajpetlje); Emit(' JNE L' + sdok); Emit(' JMP L' + skrajpetlje); IdiDo('{'); Emit('L' + sdok + ':'); Blok; Emit(' JMP L' + suslov); Emit('L' + skrajpetlje + ':'); end; procedure Blok; begin while znak <> '}' do begin if Slijedi('dok', false) then Petlja else if Slijedi('ako', false) then Uslov else if Slijedi('asembler', false) then Asembler else begin IzrazDodjeljivanja(t, dod); IdiDo(';'); end; end; IdiDo('}'); end; procedure DefFunkcija(ftip: TTip); var parametara, paradresa, lokadresa, pfunkc, i, p3: integer; ImeFunkcije, imeparametra, imevarijable, st: string; tip: TTip; imaistogtipa: Boolean; begin if not (((znak >= 'a') and (znak <= 'z')) or ((znak >= 'A') and (znak <= 'Z'))) then Greska(IMEFUN); DeklIdent(ImeFunkcije, 0); NoviIdent(ImeFunkcije, 4, 0, 0, funkcija, ftip, 0, 0, 0); pfunkc := ukupnoident; aktnivo := pfunkc; IdiDo('('); parametara := 0; lokadresa := 0; paradresa := 0; while znak <> ')' do begin if SlijediDekTipa(tip) then begin if (tip = slog) or (tip = pslog) then p3 := DeklaracijaSloga(pfunkc) else p3 := 0; DeklIdent(ImeParametra, pfunkc); parametara := parametara + 1; paradresa := paradresa + ((DuzinaTipa(tip) - 1) div 4 + 1) * 4; NoviIdent(ImeParametra, DuzinaTipa(tip), paradresa, pfunkc, parametar, tip, pfunkc, parametara, p3); end; if znak <> ')' then IdiDo(','); end; IdiDo(')'); for i := ukupnoident downto 0 do if (TabIdent[i].nivo = pfunkc) and (TabIdent[i].vrsta = parametar) then TabIdent[i].adresa := paradresa + 8 - TabIdent[i].adresa; TabIdent[pfunkc].pod1 := parametara; case znak of '{': begin IdiDo('{'); while SlijediDekTipa(tip) do begin if (tip = slog) or (tip = pslog) then p3 := DeklaracijaSloga(pfunkc) else p3 := 0; repeat DeklIdent(ImeVarijable, pfunkc); lokadresa := lokadresa + DuzinaTipa(tip); NoviIdent(ImeVarijable, DuzinaTipa(tip), -lokadresa, pfunkc, lokalna, tip, pfunkc, parametara, p3); imaistogtipa := true; if znak = ',' then begin Novi; imaistogtipa := false; end; until imaistogtipa; while (lokadresa mod 4) <> 0 do lokadresa := lokadresa + 1; IdiDo(';'); end; Str(paradresa, st); Emit(ImeFunkcije + '@' + st + ':'); Emit(' PUSH EBP'); Emit(' MOV EBP,ESP'); Str(lokadresa, st); Emit(' SUB ESP,' + st); Blok; Emit(' MOV ESP,EBP'); Emit(' POP EBP'); Str(paradresa, st); Emit(' RET ' + st); Emit('PUBLIC ' + ImeFunkcije + '@' + st); end; ';': begin Str(paradresa, st); Emit('extrn ' + ImeFunkcije + '@' + st + ':near'); IdiDo(';'); end else Greska(DEFFUN); end; aktnivo := 0; end; procedure Prevedi; var globadresa, p3: Integer; ImeVarijable, st: string; tip: TTip; imaistogtipa: Boolean; begin Emit('.486'); Emit('.MODEL FLAT,STDCALL'); Emit('OPTION CASEMAP:NONE'); Emit('EXTRN ExitProcess@4:NEAR'); Emit('.CODE'); Emit('ULAZ:'); Emit(' FINIT'); Emit(' JMP GLAVNI'); pozicija := 0; globadresa := 0; Novi; while SlijediDekTipa(tip) do begin if Slijedi('funkcija', false) then begin Novi; DefFunkcija(tip); end else begin if (tip=slog) or (tip=pslog) then p3 := DeklaracijaSloga(0) else p3 := 0; repeat DeklIdent(ImeVarijable, 0); NoviIdent(ImeVarijable, DuzinaTipa(tip), globadresa, 0, globalna, tip, 0, 0, p3); globadresa := globadresa + DuzinaTipa(tip); imaistogtipa := true; if znak = ',' then begin Novi; imaistogtipa := false; end; until imaistogtipa; while (globadresa mod 4) <> 0 do globadresa := globadresa + 1; IdiDo(';'); end end; IdiDo('{'); if znak <> '}' then begin Emit('GLAVNI:'); Blok; Emit(' PUSH 0'); Emit(' CALL ExitProcess@4'); Emit('.DATA'); Str(globadresa, st); Emit('GLOBALV DB '+st+' DUP(0)'); Emit('INTTOFP DD 0'); Emit('END ULAZ') end else begin Emit('GLAVNI:'); Emit('END'); end; end; procedure Glavni; var linija: string; begin initpp; trenlabela := 0; ukupnoident := 0; aktnivo := 0; ukupnoslogova := 0; Assign(ulaz, paramstr(1)); Assign(izlaz, paramstr(2)); brojaclinija := 0; linija := ''; Reset(ulaz); Rewrite(izlaz); Prevedi; Close(ulaz); Close(izlaz); WriteLn('Prevedeno bez greske'); end; begin Glavni end. 92 Prilog 9: Verzija izvornog koda kompajlera br. 8, predprocesor unit predpr8; interface procedure Novi; procedure InitPp; var ulaz, privulaz: text; pozicija, brojaclinija: integer; znak: char; linija: string; implementation uses postpr8; const MAXCHAR = 200000; MAXDEFINICIJE = 50; type Tdefinicije = record ime: string[20]; pocetak: integer; kraj: integer; end; var bafer: array[1..MAXCHAR] of char; definicije: array[1..MAXDEFINICIJE] of TDefinicije; bafertop: integer; deftop: integer; glavnadat: Boolean; ObradaLinije: Boolean; procedure InitPp; begin bafertop := 0; deftop := 0; glavnadat := true; ObradaLinije := true; end; procedure PpDefin; var duz, i, n: integer; radi: Boolean; imes: string; if glavnadat then ReadLn(ulaz, linija) else ReadLn(privulaz, linija); end; end; definicije[deftop].kraj := bafertop; end; linija := ''; end; procedure PpPostoji; var imes: string; postoji: Boolean; i: integer; begin imes := copy(linija, 10, Length(linija) - 9); postoji := false; for i := 1 to deftop do if definicije[i].ime = imes then postoji := true; if not (postoji) then Obradalinije := false else ObradaLinije := true; linija := ''; end; procedure PpNePostoji; var imes: string; postoji: Boolean; i: integer; begin imes := copy(linija, 12, Length(linija) - 11); postoji := false; for i := 1 to deftop do if definicije[i].ime = imes then postoji := true; if postoji then Obradalinije := false else ObradaLinije := true; linija := ''; end; begin duz := Length(linija); if deftop < MAXDEFINICIJE then deftop := deftop + 1; n := 12; imes := ''; radi := true; procedure Predprocesiraj; while (n <= duz) and radi do begin if linija[n] in ['a'..'z', 'A'..'Z'] var i, n, j, duz: integer; then imes, glava, rep: string; imes := imes + linija[n] mijenjano: Boolean; else begin radi := false; if linija = '#dalje' then begin n := n + 1; obradalinije := true; end; linija := ''; if imes <> '' then begin end; definicije[deftop].ime := imes; if not (obradalinije) then definicije[deftop].pocetak := linija := ''; bafertop; duz := Length(linija); radi := true; if duz > 11 then while radi do begin if copy(linija, 1, 11) = radi := false; '#definiraj ' then if Length(linija) > 0 then PpDefin; if linija[Length(linija)] = '\' if duz > 9 then then begin if copy(linija, 1, 9) = '#postoji ' radi := true; then linija := copy(linija, 1, PpPostoji; Length(linija) - 1); if duz > 11 then end; if copy(linija, 1, 11) = for i := n to Length(linija) do '#nepostoji ' then begin PpNePostoji; if bafertop < MAXCHAR then bafertop := bafertop + 1; if duz > 7 then bafer[bafertop] := linija[i]; if (copy(linija, 1, 7) = '#dodaj ') n := 1; and glavnadat then begin end; imes := copy(linija, 8, if radi then begin Length(linija) - 7); Assign(privulaz, imes); Reset(privulaz); glavnadat := false; linija := ''; end; repeat mijenjano:=false; for i := 1 to deftop do repeat n := Pos(definicije[i].ime, linija); if (n + Length(definicije[i].ime)) <= Length(linija) then if linija[n +Length( definicije[i].ime)] in ['a'..'z', 'A'..'Z'] then n := 0; if n > 1 then if linija[n - 1] in ['a'..'z', 'A'..'Z'] then n := 0; if n > 0 then begin glava := copy(linija,1,n-1); rep := copy(linija, n + Length(definicije[i].ime), Length(linija)); linija := glava; for j := definicije[i].pocetak + 1 to definicije[i].kraj do linija := linija + bafer[j]; linija := linija + rep; mijenjano:=true; end; until n <= 0; until not(mijenjano) end; procedure Novi; begin repeat pozicija := pozicija + 1; if pozicija > Length(linija) then begin brojaclinija := brojaclinija + 1; if glavnadat and not (Eof(ulaz)) then begin ReadLn(ulaz, linija); Predprocesiraj; end else begin if not (glavnadat) and not (Eof(privulaz)) then begin ReadLn(privulaz, linija); Predprocesiraj; end else begin if not (glavnadat) then begin glavnadat := true; Close(privulaz); end; end; end; Emit(';' + copy(linija, 1, 250)); pozicija := 1; end; if Length(linija) > 0 then znak := linija[pozicija] else znak := ' '; if (znak = '`') then pozicija := Length(linija); until ((znak > ' ') and (znak <> '`')) or Eof(ulaz); end; end. 93 Prilog 10: Verzija izvornog koda kompajlera br. 8, postprocesor-optimizator unit postpr8; interface procedure Emit(st: string); var izlaz: text; implementation const dubina = 15; da = true; ne = false; var bafer: array[1..dubina] of string; vrhbafera: integer; briseeax, koristieax, briseebx, koristiebx, koristifpu: Boolean; dubinasteka: integer; function StrToInt(st: string): integer; var i, s, rez: integer; begin rez := 0; if st[1] = '-' then s := 2 else s := 1; for i := s to Length(st) do rez := 10 * rez + (ord(st[i]) ord('0')); if st[1] = '-' then rez := -rez; StrToInt := rez; end; procedure KarakterSl(var char1: string; var radi: Boolean; tekst: string; var pt: integer); var radi2: Boolean; begin char1 := ''; radi2 := true; if pt > Length(tekst) then radi := false else while radi2 do begin char1 := char1 + tekst[pt]; pt := pt + 1; if pt > Length(tekst) then radi2 := false else begin if tekst[pt] = ',' then radi2 := false end; end; end; radi: Boolean; begin pt := 1; pu := 1; char1 := ''; char2 := ''; radi := true; if Length(tekst) = 0 then radi := false; if uporedba = tekst then Uzorak := true else begin while (pu <= Length(uporedba)) and radi do begin if uporedba[pu] = '$' then begin pu := pu + 1; case uporedba[pu] of 'C': begin pu := pu + 1; case uporedba[pu] of '1': begin KarakterSl(char1, radi, tekst, pt); end; '2': begin KarakterSl(char2, radi, tekst, pt); end; end; end; 'N': begin pu := pu + 1; case uporedba[pu] of '1': begin BrojSl(char1, radi, tekst, pt); end; '2': begin BrojSl(char2, radi, tekst, pt); end; end; end; end end else begin if uporedba[pu] <> tekst[pt] then radi := false; pt := pt + 1; end; pu := pu + 1; end; Uzorak := radi; end; end; procedure Status(breax, koreax, brebx, korebx: Boolean; dubst: integer; korfpu: Boolean); begin briseeax := breax; koristieax := koreax; briseebx := brebx; koristiebx := korebx; koristifpu := korfpu; dubinasteka := dubinasteka + dubst; end; procedure BrojSl(var char1: string; var radi: Boolean; tekst: string; var pt: Integer); var radi2: Boolean; begin char1 := ''; radi2 := true; if pt > Length(tekst) then radi := false procedure LeaMovSt(var c1, c2: string; else begin var koreax, korebx, breax, brebx: if (tekst[pt] < '0') or (tekst[pt] > Boolean); '9') then begin radi := false; if (c1 = 'EAX') or (c1 = 'AL') then while radi2 do begin breax := true; char1 := char1 + tekst[pt]; if (c1 = 'EBX') or (c1 = 'BL') then pt := pt + 1; brebx := true; if pt > Length(tekst) then if ((Pos('EAX', c1) > 0) and (c1 <> radi2 := false 'EAX')) else begin or (Pos('EAX', c2) > 0) if (tekst[pt] < '0') or or (c2 = 'AL') then (tekst[pt] > '9') then koreax := true; radi2 := false if ((Pos('EBX', c1) > 0) and (c1 <> end; 'EBX')) end; or (Pos('EBX', c2) > 0) or end (Pos('BL', c2) > 0) then end; korebx := true; end; function Uzorak(uporedba, tekst: string; procedure PopSt(var c1, c2: string; var var char1, char2: string): Boolean; incsp: integer; var breax, brebx: var Boolean); pu, pt: integer; begin if (c1 = 'EAX') then breax := true; if (c1 = 'EBX') then brebx := true; incsp := 4; end; procedure PushSt(var c1, c2: string; var incsp: integer; var koreax, korebx: Boolean); begin if Pos('EAX', c1) > 0 then koreax := true; if Pos('EBX', c1) > 0 then korebx := true; incsp := -4; end; procedure AddSubst(var c1, c2: string; var incsp: integer; var koreax, korebx: Boolean; sub: Boolean); begin if c1 = 'ESP' then incsp := StrToInt(c2); if sub then incsp := -incsp; if (Pos('EAX', c1) > 0) or (Pos('EAX', c2) > 0) or (c1 = 'AL') or (c2 = 'AL') then koreax := true; if (Pos('EBX', c1) > 0) or (Pos('EBX', c2) > 0) or (c1 = 'BL') or (c2 = 'BL') then korebx := true; end; procedure LogicalSt(var c1, c2: string; var koreax, korebx: Boolean); begin if (Pos('EAX', c1) > 0) or (Pos('EAX', c2) > 0) or (c1 = 'AL') or (c2 = 'AL') then koreax := true; if (Pos('EBX', c1) > 0) or (Pos('EBX', c2) > 0) or (c1 = 'BL') or (c2 = 'BL') then korebx := true; end; procedure SkokSt(var breax, brebx, korfp: Boolean); begin breax := true; brebx := true; korfp := true; end; procedure DivMulSt(var koreax, korebx: Boolean; var c1: string); begin koreax := true; if (Pos('EBX', c1) > 0) then korebx := true; end; procedure ObradiStanje(tr: string); var c1, c2: string; breax, koreax, brebx, korebx, korfp: Boolean; incsp: integer; prvoslovo, drugoslovo: char; begin breax := false; koreax := false; brebx := false; korebx := false; incsp := 0; korfp := true; if Length(tr) > 3 then begin prvoslovo := tr[2]; drugoslovo := tr[3]; end else begin prvoslovo := ' '; drugoslovo := ' '; end; if prvoslovo < 'K' then 94 case prvoslovo of 'A': begin if Uzorak(' ADD $C1,$C2', tr, c1, c2) then AddSubst(c1, c2, incsp, koreax, korebx, false) else if Uzorak(' AND $C1,$C2', tr, c1, c2) then LogicalSt(c1, c2, koreax, korebx) end; 'C': begin if Uzorak(' CALL $C1', tr, c1, c2) then SkokSt(breax, brebx, korfp) else if Uzorak(' CDQ', tr, c1, c2) then koreax := true else if Uzorak(' CLD', tr, c1, c2) then c1 := c1 else if Uzorak(' CMP $C1,$C2', tr, c1, c2) then LogicalSt(c1, c2, koreax, korebx) end; 'F': begin case drugoslovo of 'A': begin if Uzorak(' FADD ', tr, c1, c2) then korfp := true end; 'C': begin if Uzorak(' FCHS', tr, c1, c2) then korfp := true else if Uzorak(' FCOMPP ', tr, c1, c2) then korfp := true end; 'D': begin if Uzorak(' FDIVR ', tr, c1, c2) then korfp := true end; 'I': begin if Uzorak(' FILD $C1', tr, c1, c2) then korfp := true else if Uzorak(' FINIT', tr, c1, c2) then korfp := true else if Uzorak(' FISTP $C1', tr, c1, c2) then korfp := true end; 'L': begin if Uzorak(' FLD $C1', tr, c1, c2) then korfp := true end; 'M': begin if Uzorak(' FMUL ', tr, c1, c2) then korfp := true end; 'S': begin if Uzorak(' FSTP $C1', tr, c1, c2) then korfp := true else if Uzorak(' FSTSW AX', tr, c1, c2) then korfp := true else if Uzorak(' FSUBR ', tr, c1, c2) then korfp := true end end end; 'I': begin if Uzorak(' IDIV $C1', tr, c1, c2) then DivMulSt(koreax, korebx, c1) else if Uzorak(' IMUL $C1', tr, c1, c2) then DivMulSt(koreax, korebx, c1) end; 'J': begin if Uzorak(' JMP $C1', tr, c1, c2) then SkokSt(breax, brebx, korfp) else if Uzorak(' JNE $C1', tr, c1, c2) then SkokSt(breax, brebx, korfp) end; end; if prvoslovo >= 'K' then case prvoslovo of 'L': begin if Uzorak(' LEA $C1,$C2', tr, c1, c2) then LeaMovSt(c1, c2, koreax, korebx, breax, brebx) end; 'M': begin if Uzorak(' MOV $C1,$C2', tr, c1, c2) then LeaMovSt(c1, c2, koreax, korebx, breax, brebx) else if Uzorak(' MUL $C1', tr, c1, c2) then DivMulSt(koreax, korebx, c1) end; 'N': begin if Uzorak(' NEG $C1', tr, c1, c2) then LogicalSt(c1, c2, koreax, korebx) else if Uzorak(' NOT $C1', tr, c1, c2) then LogicalSt(c1, c2, koreax, korebx) end; 'O': begin if Uzorak(' OR $C1,$C2', tr, c1, c2) then LogicalSt(c1, c2, koreax, korebx) end; 'P': begin if Uzorak(' POP $C1', tr, c1, c2) then PopSt(c1, c2, incsp, breax, brebx) else if Uzorak(' PUSH $C1', tr, c1, c2) then PushSt(c1, c2, incsp, koreax, korebx) end; 'R': begin if Uzorak(' REP MOVSB', tr, c1, c2) then c1 := c1 else if Uzorak(' RET $N1', tr, c1, c2) then incsp := StrToInt(c1) + 4 end; 'S': begin case drugoslovo of 'A': begin if Uzorak(' SAHF', tr, c1, c2) then koreax := true else if Uzorak(' SAL EAX,$N1', tr, c1, c2) then koreax := true end; 'E': begin if Uzorak(' SETA AL', tr, c1, c2) then breax := true else if Uzorak(' SETB AL', tr, c1, c2) then breax := true else if Uzorak(' SETE AL', tr, c1, c2) then breax := true else if Uzorak(' SETG AL', tr, c1, c2) then breax := true else if Uzorak(' SETL AL', tr, c1, c2) then breax := true else if Uzorak(' SETNE AL',tr, c1, c2) then breax := true end; 'U': begin if Uzorak(' SUB $C1,$C2', tr, c1, c2) then AddSubst(c1, c2, incsp, koreax, korebx, true) end end end; 'X': begin if Uzorak(' XOR $C1,$C2', tr, c1, c2) then LogicalSt(c1, c2, koreax, korebx) end; end; Status(breax, koreax, brebx, korebx, incsp, korfp); end; procedure Dump(what: string; j, i: integer); var k: integer; begin WriteLn(what); for k := j to i do WriteLn(k, bafer[k]); ReadLn; end; procedure Obrisi(n: integer); var i: integer; begin for i := n + 1 to dubina do bafer[i - 1] := bafer[i]; vrhbafera := vrhbafera - 1; end; procedure PushEaxOptim(pusheax: Boolean; var j: integer); var i: integer; izlaz, mebx, meax: Boolean; begin dubinasteka := 0; Status(ne, ne, ne, ne, 0, ne); izlaz := false; meax := false; mebx := false; i := j; repeat i := i + 1; if i >= vrhbafera then izlaz := true; if (dubinasteka = 0) and not (izlaz) then begin if (bafer[i] = ' POP EAX') and not (meax) then begin //dump('Nepotrebno PUSH/POP EAX',j,i); Obrisi(i); if pusheax then Obrisi(j) else bafer[j] := ' MOV EAX,EBX'; izlaz := true; end; if (bafer[i] = ' POP EBX') and not (mebx) then begin //dump('Nepotrebno PUSH /POP EBX',j,i); Obrisi(i); if pusheax then bafer[j] := ' MOV EBX,EAX' else Obrisi(j); izlaz := true; end; end; if not (izlaz) then ObradiStanje(bafer[i]); if briseeax and not (meax) then meax := true; if briseebx and not (mebx) then mebx := true; until izlaz; end; 95 procedure LeaEbxOptim(var j: integer; adresa: string); var i, k, n: integer; c1, c2, p: string; izlaz: Boolean; zaebx := true else izlaz := true; i := j; repeat i := i + 1; if i >= vrhbafera then izlaz := true; begin if not (izlaz) then begin dubinasteka := 0; ObradiStanje(bafer[i]); Status(ne, ne, ne, ne, 0, ne); if zaeax then begin izlaz := false; if koristieax then i := j; izlaz := true; if i + 1 < vrhbafera then if briseeax then begin if Uzorak(' PUSH EBX', bafer[i + //dump(' Nepotrebno MOV EAX ',j,i); 1], c1, c2) then begin Obrisi(j); ObradiStanje(bafer[i + 1]); izlaz := true; i := i + 2; end; repeat end; if i >= vrhbafera then if zaebx then begin izlaz := true; if koristiebx then if not (izlaz) then izlaz := true; ObradiStanje(bafer[i]); if briseebx then begin if (dubinasteka = 0) and not //dump(' Nepotrebno MOV EBX ',j,i); (izlaz) then Obrisi(j); if Uzorak(' POP EBX', izlaz := true; bafer[i], c1, c2) then begin end; //dump('Nepotrebno LEA/PUSH/POP',j,i); end; bafer[i] := ' LEA EBX,' + adresa; end Obrisi(j + 1); until izlaz; Obrisi(j); end; izlaz := true; end; procedure FldOptim(var j: integer); i := i + 1; var until izlaz; i: integer; end izlaz: Boolean; else begin begin i := i + 1; Status(ne, ne, ne, ne, 0, ne); repeat izlaz := false; if i >= vrhbafera then i := j; izlaz := true; repeat if not (izlaz) then i := i + 1; ObradiStanje(bafer[i]); if i >= vrhbafera then if (koristiebx) and not (izlaz) izlaz := true; then begin if not (izlaz) then begin if Pos('[EBX]', bafer[i]) < 1 ObradiStanje(bafer[i]); then if koristifpu then izlaz := true; izlaz := true; end; if bafer[i] = ' FSTP ST(0)' then if (briseebx) and not (izlaz) begin then begin //dump(' Nepotrebno FLD/FSTP ',j,i); // dump('Nasao nepotrebno LEA',j,i); Obrisi(i); for k := j + 1 to i - 1 do Obrisi(j); begin izlaz := true; n := Pos('[EBX]', end; bafer[k]); if (i < vrhbafera - 1) and not if n >= 1 then begin (izlaz) then if Pos('EAX', bafer[k]) > if (bafer[i] = ' ADD ESP,-8') 0 then and p := 'DWORD PTR ' (bafer[i + 1] = else ' FSTP QWORD PTR [ESP]') p := ''; then bafer[k] := begin copy(bafer[k], 1, n - 1) i := i + 2; + p + adresa + dubinasteka := 0; copy(bafer[k], n + 5, while (i < vrhbafera - 1) and Length(bafer[k]) - n not (izlaz) do begin 4); ObradiStanje(bafer[i]); end; if (bafer[i] = end; ' FLD QWORD PTR [ESP]') Obrisi(j); and (bafer[i + 1] = izlaz := true; ' ADD ESP,8') and end; (dubinasteka = 0) then i := i + 1; begin until izlaz; // dump('Nepotr. FP na ESP stek',j,i+1); end; bafer[i + 1] := bafer[j]; Obrisi(i); end; Obrisi(j + 2); Obrisi(j + 1); procedure MovViskaOptim(var j: integer; Obrisi(j); c1: string); izlaz := true; var end; i: integer; i := i + 1; izlaz, zaeax, zaebx: Boolean; end; begin end; Status(ne, ne, ne, ne, 0, ne); end izlaz := false; until izlaz; zaeax := false; end; zaebx := false; if (c1 = 'EAX') or (c1 = 'AL') then procedure Jednostruke(var j: integer); zaeax := true begin else if c1 = 'EBX' then if (bafer[j] = ' MOV EAX,EAX') or (bafer[j] = ' MOV EBX,EBX') or (bafer[j] = ' ADD EAX,0') or (bafer[j] = ' ADD EBX,0') then begin // dump('Nepotrebna instrukcija',j,j); Obrisi(j); end end; procedure Parovi(var j: integer); var c1, c2, c3, c4, nep, st: string; begin nep := 'Nepotreban par'; if bafer[j][1] = 'M' then begin if Uzorak(' MOV $C1,$C2', bafer[j], c1, c2) and Uzorak(' MOV $C1,$C2', bafer[j + 1], c3, c4) then begin if ((c1 = c4) and (c2 = c3)) or ((c1 = c3) and (c2 = c4)) then begin // dump(nep,j,j+1); Obrisi(j + 1); end; end else if Uzorak(' MOV $C1,$N2', bafer[j], c1, c2) and Uzorak(' ADD $C1,$N2', bafer[j + 1], c3, c4) then begin if c1 = c3 then begin // dump(nep,j,j+1); Str(StrToInt(c2) + StrToInt(c4), st); bafer[j] := ' MOV ' + c1 + ',' + st; Obrisi(j + 1); end; end else if Uzorak(' MOV $C1,$N2', bafer[j], c1, c2) and (bafer[j + 1] = ' NEG AX') then begin // dump(nep,j,j+1); bafer[j] := ' MOV ' + c1 + '-' + c2; Obrisi(j + 1); end; end else if Uzorak(' ADD $C1,$N2', bafer[j], c1, c2) and Uzorak(' ADD $C1,$N2', bafer[j + 1], c3, c4) then begin if c1 = c3 then begin // dump(nep,j,j+1); Str(StrToInt(c2) + StrToInt(c4), st); bafer[j] := ' ADD ' + c1 + ',' + st; Obrisi(j + 1); end; end; end; procedure Trojke(var j: integer); var c1, c2, c3, c4, c5, c6, nep: string; begin nep := 'Nepotrebna trojka'; if Uzorak(' MOV $C1,$C2', bafer[j], c1, c2) and Uzorak(' MOV $C1,$C2', bafer[j + 2], c5, c6) // Izvrnuto zbog brzine and ( (Uzorak(' ADD $C1,$C2', bafer[j + 1], c3, c4)) or (Uzorak(' AND $C1,$C2', bafer[j + 1], c3, c4)) or (Uzorak(' SUB $C1,$C2', bafer[j + 1], c3, c4)) or (Uzorak(' XOR $C1,$C2', bafer[j + 1], c3, c4)) or (Uzorak(' MOV $C1,$C2', bafer[j + 1], c3, c4)) or (Uzorak(' OR $C1,$C2', bafer[j + 1], c3, c4))) then begin if (c1 = c4) and (c1 = c5) then begin // dump(nep,j,j+2); if copy(bafer[j + 1], 2, 2) <> 'OR' then bafer[j + 1] := copy(bafer[j + 96 1], 1, 5) + c3 + ',' + c2 else bafer[j + 1] := copy(bafer[j + 1], 1, 4) + c3 + ',' + c2; Obrisi(j); end; end; end; end; bafer[vrhbafera] := st; if Length(st) >= 3 then if copy(st, 1, 3) = 'END' then begin Optimizuj; for i := 1 to vrhbafera do WriteLn(izlaz, bafer[i]); end end; procedure Cetvorke(var j: integer); var end. c1, c2, c3, c4, c5, c6, c7, c8, nep: string; begin nep := 'Nepotrebna cetvorka'; if Uzorak(' PUSH $C1', bafer[j], c1, c2) and Uzorak(' POP $C1', bafer[j + 3], c7, c8) // Izvrnuto zbog brzine and Uzorak(' MOV $C1,$C2', bafer[j + 1], c3, c4) and Uzorak(' MOV $C1,$C2', bafer[j + 2], c5, c6) and (c1 = c5) and (c3 = c6) and (c6 = c7) then begin // dump(nep,j,j+4); if (Pos('DWORD', c4) < 1) and (c4 <> 'EAX') and (c4 <> 'EBX') and (c4 <> 'ECX') then c4 := 'DWORD PTR ' + c4; bafer[j] := ' MOV ' + c3 + ',' + c1; bafer[j + 1] := ' MOV ' + c1 + ',' + c4; Obrisi(j + 3); Obrisi(j + 2); end; end; procedure Optimizuj; var c1, c2: string; j: integer; begin j := 1; while j <= vrhbafera - 1 do begin if (Length(bafer[j]) > 3) and (bafer[j][1] = ' ') then begin if Uzorak(' PUSH EAX', bafer[j], c1, c2) then PushEaxOptim(true, j); if Uzorak(' PUSH EBX', bafer[j], c1, c2) then PushEaxOptim(false, j); if Uzorak(' MOV $C1,$C2', bafer[j], c1, c2) then MovViskaOptim(j, c1); if Uzorak(' LEA EBX,$C1', bafer[j], c1, c2) then LeaEbxOptim(j, c1); if Uzorak(' FLD $C1', bafer[j], c1, c2) then FldOptim(j); if j < vrhbafera - 3 then Cetvorke(j); if j < vrhbafera - 2 then Trojke(j); if j < vrhbafera - 1 then Parovi(j); Jednostruke(j); end; j := j + 1; end; end; procedure Emit(st: string); var i: integer; begin if st = '.486' then begin vrhbafera := 0; dubinasteka := 0; end; vrhbafera := vrhbafera + 1; if vrhbafera >= dubina then Optimizuj; if vrhbafera > dubina then begin WriteLn(izlaz, bafer[1]); Obrisi(1); vrhbafera := dubina; 97 Prilog 11: Prikaz finalne verzije jezika FILDZAN-32 u EBNF Program = { (DeklaracijaVarijabli | DeklaracijaFunkcije) } "{" ( {DeklaracijaVarijabli} Blok | "}" ) . DeklaracijaVarijabli = ImeTipa Identifikator { "," Identifikator } ";" { ImeTipa Identifikator { "," Identifikator } ";"} . ImeTipa = ( "cijeli" ["*"] [DeklaracioniDimenzijskiModifikator] | "realni" ["*"] [DeklaracioniDimenzijskiModifikator] | "karakter" ["*"] [DeklaracioniDimenzijskiModifikator] | "slog" ["*"] DeklaracijaSloga [DeklaracioniDimenzijskiModifikator] ) . DeklaracijaFunkcije = ImeTipa "funkcija" Identifikator "(" [ ImeTipa Identifikator { "," ImeTipa Identifikator } ] ")" ( ";" | "{" [DeklaracijaVarijabli] Blok ) . DeklaracioniDimenzijskiModifikator = "[" NumerickaKonstanta { "," NumerickaKonstanta } "]" . DeklaracijaSloga = "{" ImeTipa Identifikator { "," Identifikator } ";" { ImeTipa Identifikator { "," Identifikator } ";" } "}" . Blok = { ( "dok" Petlja | "ako" Uslov | IzrazDodjeljivanja ";" | "asembler" AsemblerskiModul) } "}" . Uslov = IzrazDodjeljivanja "{" Blok [ "inace" "{" Blok ] . Petlja = IzrazDodjeljivanja "{" Blok . AsemblerskiModul = {BiloKojiZnak} "\" . IzrazDodjeljivanja = Izraz [ ( ("="| "#" | ">" | "<" ) Izraz | ":=" IzrazDodjeljivanja ) ] . Izraz = Clan { ("-" | "+" | "&" | "|" | "^") Clan } . Clan = Faktor { ("*" | "/" | "%") Faktor } . Faktor = ( ("-" | "~" | "&" | "*" | "!") Faktor | NumerickaKonstanta | "(" IzrazDodjeljivanja ")" | Varijabla | '"' StringKonstanta | PozivFunkcije | "'" BiloKojiZnakOsimNavodnika "'" ) [( "." Identifikator | ListaIndeksa ) { ( "." Identifikator | ListaIndeksa ) } ) ]. Varijabla = Identifikator [ ( "(" [ IzrazDodjeljivanja { "," IzrazDodjeljivanja } ] ")" . StringKonstanta = { BiloKojiZnakOsimNavodnika } '"' . ListaIndeksa = "[" IzrazDodjeljivanja { "," IzrazDodjeljivanja } "]" . PozivFunkcije = Identifikator "(" [ IzrazDodjeljivanja { "," IzrazDodjeljivanja } ] ")" . NumerickaKonstanta = Cifra { Cifra } [ "." Cifra { Cifra } ] [ "E" [ ( "+" | "-" )] Cifra { Cifra } ] . Identifikator = Slovo { Slovo | Cifra | "_" } . Slovo = ("A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" ) . Cifra = ("0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ) . BiloKojiZnakOsimNavodnika = (Slovo | Cifra | "~" | "!" | "@" | "#" | "$" | "%" | "^" | "&" | "*" | "(" | ")" | "-" | "_" | "=" | "+" | "[" | "{" | "]" | "}" | "|" | "\" | ":" | ";" | "<" | "," | "." | ">" | "/" | "?" | "`" | ")" ) . BiloKojiZnak = (BiloKojiZnakOsimNavodnika | '"' | "'" ) . 98 13. TEORIJA JEZIKA I PARSIRANJA Kompajler razvijen u prethodnim poglavljima razvijen je spiralnom metodom, pri čemu je veća pažnja posvećivana generisanju koda nego sintaksnoj i semantičkoj analizi. U složenijim kompajlerima sintaksna analiza može biti veoma zahtjevna, i ova slika o razvoju kompajlera neće biti kompletna bez uvoda u teoriju formalnih gramatika i parsiranja. 13.1. Formalne gramatike Formalna gramatika je način opisa formalnog jezika, tj. skupa nizova simbola sastavljenih iz određenog konačnog alfabeta. Ime je dobila formalna gramatika zbog analogije sa konceptom gramatike u ljudskim jezicima. Osnovna ideja iza ovih gramatika je da se generišu nizovi znakova koji počinju specijalnim startnim simbolom i primjene pravila koja određuju kako se određena kombinacija simbola može zamijeniti drugom kombinacijom simbola. Na primjer, ako se alfabet sastoji od znakova 'a' i 'b', a startni simbol je 'S', uz sljedeća pravila: 1. S -> aSb 2. S -> ba tada se može napisati "S" kao "aSb" zamjenom simbola 'S' sa "aSb" (pravilo 1), a zatim prepisati "aSb" kao "aaSbb" primjenom istog pravila. To se ponavlja sve dok rezultat ne sadrži samo simbole iz alfabeta. U našem primjeru može se dalje prepisati S kao što slijedi: S -> aSb -> aaSbb -> aababb. Jezik ove gramatike se onda sastoji od svih stringova koji se mogu generisati na ovaj način: ba, abab, aababb, aaababbb, itd. 13.2. Kontekstno osjetljiva gramatika Kontekstno osjetljiva gramatika je formalna gramatika G = (N, T, P, S) čija su sva pravila P oblika αAβ -> αγβ gdje A neterminalni simbol, α i β su nizovi neterminalnih i terminalnih simbola, a γ neprazan niz neterminalnih i terminalnih simbola , uz dodatno pravilo koje je dopušteno ako se S ne nalazi sa desne strane nijednog pravila: S -> ε Gdje je ε prazan niz Pojam “Kontekstno osjetljiva” potiče od činjenice da α i β definišu kontekst u kome se A može transformisati sa γ ili ne. To je različito od kontekstno slobodnih gramatika gdje se kontekst neterminalnih simbola ne uzima u razmatranje. Formalni jezik opisan kontekstno osjetljivom gramatikom se naziva kontekstno osjetljiv jezik. U prirodnim jezicima je čest slučaj da riječ nije odgovarajuća na određenom mjestu u datom kontekstu. 13.3. Nesažimajuća gramatika Druga definicija kontekstno osjetljive gramatike definiše je kao formalnu gramatiku koja ima ograničenje na pravila α -> β u skupu P tako da je | α | ? | β | gdje je | α | dužina simbola α. Takva gramatika se zove nesažimajuća gramatika jer nijedno od pravila ne smanjuje veličinu niza simbola koji se razvija. Iako različite, kontekstno osjetljiva i nesažimajuća gramatika su ekvivalentne jer definišu istu klasu jezika osim što nesažimajuća gramatika ne može generisati jezik koji sadrži simbol praznog prostora. Ali, ako se jezik L može opisati kontekstno osjetljivom gramatikom, on se (izuzev praznog simbola) može predstaviti i nesažimajućom gramatikom. 13.4. Kontekstno slobodna gramatika Kontekstno slobodna gramatika je formalna gramatika čija su sva pravila oblika: V -> w Gdje je V neterminalni simbol, a w niz koji se sastoji od terminalnih i/ili neterminalnih. Pojam kontekstno slobodna znači da se varijabla V uvijek može zamijeniti sa w, bez obzira u kojem je kontekstu. Formalni jezik je kontekstno slobodan ako postoji kontekstno slobodna gramatika koja ga generiše. Kontekstno slobodnom gramatikom se definišu gotovo svi programski jezici i na bazi nje se prave parseri/sintaksni analizatori. 13.5. Regularna gramatika Regularna gramatika je formalna gramatika u kojoj sva pravila imaju jedan od sljedećih oblika: A -> a gdje je A neterminalni simbol dok je a terminalni simbol 99 A -> aB gdje su A i B neterminalni simbol dok je a terminalni simbol A -> ε gdje je A neterminalni simbol Alternativno, drugo pravilo se može pisati kao A -> Ba. Primjer: Gramatika G sa N = {S, A}, Σ = {a, b, c}, P pravila su S -> aS S -> bA A -> ε A -> cA i S kao startni simbol. Ova gramatika opisuje isti jezik kao regularni izraz a*bc*. Regularna gramatika opisuje konačne automate i regularne jezike. Koristi se u leksičkoj analizi. 13.6. Parsiranje Prevođenje iz jednog jezika u drugi zahtjeva parsiranje. Parsiranje je proces identifikacije strukture podataka. Ono određuje da li ulazni podaci imaju određenu strukturu. Da bi se obavilo parsiranje potrebna je gramatika, koja će definisati skup pravila. Pravila su određeni uzorci podataka koja dalje mogu da imaju reference na druga pravila. Zavisno od skupa pravila mogu se definisati parseri odozgo prema dolje ili odozdo prema gore. 13.7. LL Parsiranje Prevodilac ne generiše rečenice u izvornom jeziku, nego ih prepoznaje. To znači da koraci koji vode do konstrukcije rečenice moraju biti izvedeni iz gotove rečenice. Dok je za jezike kao što je Pascal taj zadatak relativno jednostavan, dosta je složen za jezike poput Fortrana ili C++a. Razvijajući programski jezik FILDZAN32 bez posebnog navođenja korišten je način parsiranja odozgo nadolje, takozvani rekurzivni silazak. Gramatike jezika Pascal i Modula 2 se definišu tako da se može primijeniti ovaj način parsiranja. Suština metoda je da se kreće od startnog simbola (npr. “program”) i pokušava dobiti rečenica primjenom sekvence pravila. To se čini gledajući sljedeći terminalni simbol na ulazu. Kao ilustracija ove metode neka posluži sljedeća jednostavna gramatika: G N T S P = = = = = { N , T , S , P } { A , B } { x , y , z } A A : B : B : xB z yB (1) (2) (3) Ako treba parsirati rečenicu xyyz, koja je sastavljena od terminalnih simbola ove gramatike, kreće se od ciljnog simbola i ulaznog niza Rečenička forma S = A Ulazni niz xyyz Nad rečeničkom formom 1 se primjeni jedino moguće pravilo (1) da se dobije Rečenička forma xB Ulazni niz xyyz Za sada je u redu, jer se slažu početni simboli rečeničke forme i ulaznog niza. Stoga treba iz neterminalnog simbola B izvesti yyz. Rečenička forma B Ulazni niz yyz Može se odabrati bilo pravilo (2) ili (3) u obradi neterminalnog simbola B, ali se iz ulaznog stringa vidi da je (3) pravi izbor. Primjenom tog pravila dobija se: Rečenička forma yB Ulazni niz yyz Što znači da se iz neterminalnog simbola B mora izvesti yz. Rečenička forma B Ulazni niz yz To nas ponovo vodi do pravila (3) i dobijamo 100 Rečenička forma yB Ulazni niz yz što povlači da se iz neterminalnog simbola B mora izvesti terminalni simbol z direktno, što se postiže pravilom (2). Primjer rečenica koje se ne mogu prepoznati ovom gramatikom su xxxx ili xyyyy. Ova metoda se zove LL(k) parsiranje. Naziv potiče od toga što se ulazni string skenira s lijeva na desno (prvo L) primjenjujući pravila na prvi lijevi neterminalni simbol (drugo L) gledajući maksimalno k terminalnih simbola da se odredi koje pravilo primijeniti u datom stanju. U našem primjeru, k=1, te LL(1) je najčešći slučaj LL(k) parsiranja. Lako je napisati LL(1) parser, ali pisanje gramatike u takvom obliku zna biti složen posao, pogotovo što se ne može svaka gramatika transformisati u ovaj oblik. Evo primjera kako se mogu vršiti potrebne transformacije da bi se dobila LL(1) kompatibilna gramatika: Neka je u nekoj gramatici REPEAT petlja predstavljena u obliku: RepeatStatement = | "REPEAT" StatementSequence "UNTIL" Condition "REPEAT" StatementSequence "FOREVER" . Oba oblika počinju rezervisanom riječju REPEAT, što zbunjuje parser. Ali, ako se definiše: RepeatStatement TailRepeatStatement = = "REPEAT" StatementSequence TailRepeatStatement . "UNTIL" Condition | "FOREVER" . nema problema s parsiranjem. No, u sljedećem slučaju Statement IfStatement = = IfStatement | OtherStatement . "IF" Condition "THEN" Statement | "IF" Condition "THEN" Statement "ELSE" Statement . čak nakon rastavljanja pravila i dalje postoji neodređenost. Statement IfStatement IfTail = = = IfStatement | OtherStatement . "IF" Condition "THEN" Statement "ELSE" Statement | e . IfTail . (1, 2) (3) (4, 5) Ova neodređenost se obično rješava pravilom da ELSE se odnosi na zadnji THEN. U FILDZAN-32, ovaj problem je izbjegnut, uvođenjem obaveznih vitičastih zagrada u naredbi ako. 13.8. LR Parsiranje Drugi popularni način parsiranja je LR(k) parsiranje. Ove oznake predstavljaju da se u ovoj metodi ulazni podaci čitaju sa Lijeva na desno, razvijajući stalno krajnji desni (Right) simbol, gledajući unaprijed najviše k simbola. U praksi je k najčešće 1 ili 0. Tehnika je bazirana na principu odozdo nagore. Kreće se od ulazne sekvence i praveći redukcije, teži se da se dođe do ciljnog simbola. Redukcija rečenice se ne postiže zamjenom desne strane pravila čija lijeva strana sadrži odgovarajući neterminalni simbol, nego zamjenom lijeve strane pravila koje se slaže sa desnom stranom. Parsiranje odozdo nagore može koristiti stek za parsiranje koji sadrži dio mogućih rečeničnih formi terminalnih i neterminalnih simbola. Svaki put kada se čita terminalni simbol iz ulaznog stringa, on se smješta na stek za parsiranje, zatim se ispituju elementi na vrhu steka da se vidi da li se može obaviti redukcija. Neki terminalni simboli mogu dugo stojati na steku sve dok se ne oslobode. To je različito od parsera sa rekurzivnim spuštanjem koji oslobađa terminalne simbole čim ih je pročitao i koji smješta neterminalne komponente parcijalne rečenične forme samo implicitno kao niz nedovršenih poziva potprograma za obradu neterminalnih simbola. Evo primjera za gramatiku koja nije LL(1) tipa definisanu kao Goal Expression Term = = = Expression "." . Expression "-" Term "a" | Term . I treba parsirati ulazni niz "a - a - a ." . Ovo su akcije koje će se obaviti Step 1 2 3 4 5 6 7 8 9 10 11 12 13 Action read reduce reduce read read reduce reduce read read reduce reduce read reduce Using production a 4 3 a 4 2 a 4 2 . 1 Stack a Term Expression Expression Expression Expression Expression Expression Expression Expression Expression Expression Goal - a - Term - a - Term . (1) (2, 3) (4) 101 Cilj je dostignut i rečenica je ispravna Ipak, postavlja se pitanje u ovom primjeru zašto nije korišteno pravilo Goal=Expression kada je reduciran string "a" u Expression nakon koraka 3? Da bi se primijenila redukcija, naravno da je potrebno da lijeva strana pravila bude na steku za parsiranje, ali je samo po sebi nedovoljno. Kada postoji više mogućih desnih strana koje se slažu sa elementima na vrhu steka za parsiranje, pravi parser treba da primjeni odgovarajuću strategiju, gledajući unaprijed ulazni string da odluči koje će pravilo primijeniti. Ovakvi parseri se upravljaju tablicama, gdje odgovarajuća strategija u odgovarajućem trenutku biva određena gledanjem u pravougaonu matricu, čija jedna dimenzija predstavlja stanje parsiranja (tj. poziciju koju je parser dosegao unutar gramatičkih pravila) , a druga predstavlja trenutni simbol (tj. terminalni ili neterminalni simbol gramatike). Elementi tabele prihvataju ulazni string kao korektan, odbacuju kao nekorektan, prelaze u druga stanja ili vrše redukciju primjenom odgovarajućeg pravila. Umjesto smještanja na stek samih simbola kako je bilo navedeno u prethodnom primjeru, algoritam za parsiranje smješta ili skida elemente koji predstavljaju stanje parsiranja - shift operacije koje smještaju novodosegnuto stanje na stek i reduce operacije koje skidaju onoliko elemenata sa steka koliko je simbola na desnoj strani pravila koje se primjenjuje. Algoritam se može opisati kao: BEGIN GetSYM(InputSymbol); (* first Sym in sentence *) State := 1; Push(State); Parsing := TRUE; REPEAT Entry := Table[State, InputSymbol]; CASE Entry.Action OF shift: State := Entry.NextState; Push(State); IF IsTerminal(InputSymbol) THEN GetSYM(InputSymbol) (* accept *) END reduce: FOR I := 1 TO Length(Rule[Entry].RightSide) DO Pop END; State := Top(Stack); InputSymbol := Rule[Entry].LeftSide; reject: Report(Failure); Parsing := FALSE accept: Report(Success); Parsing := FALSE END UNTIL NOT Parsing END Algoritam je jednostavan, ali je pravljenje tabele za parsiranje dosta teško. Ovdje neće biti navedeno kako se to radi, ali za gornji primjer tabela za parsiranje može izgledati ovako (bez elemenata za odbacivanje) Symbol Goal Expression Term Accept Shift 2 Shift 3 "a" "-" "." State 1 2 3 4 5 6 Shift 6 Shift 4 Shift 5 Reduce 3 Reduce 4 Reduce 1 Reduce 3 Reduce 4 Reduce 2 Reduce 2 Shift 4 Parsiranje stringa "a - a - a ." će teći na sljedeći način:. State 1 4 1 3 1 2 5 4 5 6 1 2 5 4 5 6 1 2 1 Symbol a Term Expression a Term Expression a . Term . Expression . Goal Stack Action 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Shift to state 4, accept a Reduce by (4) Term = a Shift to state 3 Reduce by (3) Expression = Term Shift to state 2 Shift to state 5, accept Shift to state 4, accept a Reduce by (4) Term = a Shift to state 6 Reduce by (2) Expression = Expression - Term Shift to state 2 Shift to state 5, accept Shift to state 4, accept a Reduce by (4) Term = a Shift to state 6 Reduce by (2) Expression = Expression - Term Shift to state 2 Reduce by (1) Goal = Expression Accept as completed 4 3 2 2 2 2 2 5 5 4 5 5 6 2 2 2 2 2 5 5 4 5 5 6 2 102 Tablice mogu biti dosta velike pa se u memoriji često smještaju pomoću metoda za rijetke matrice. Kao u slučaju LL(1) parsera potrebno je osigurati da se izbjegnu neodređenosti između pravila koje se nazivaju "Shift/reduce" konflikti. Pravljenje tablica i provjera konflikta se ostavlja generatorima parsera. LR(k) parsiranje je mnogo moćnije od LL(k) parsiranja, i intuitivno konstruisane gramatike zahtijevaju daleko manje transformacija da se napravi gramatika iz koje se može generisati LR(k) parser. Na primjer, LR(k) parsiranje podržava lijevu rekurziju, dok LL(k) ne podržava. Također, tablice predstavljaju brži način parsiranja od velikog broja uslova. LR parseri imaju prednost u lakšem dodavanju oporavka od grešaka. Nedostaci LR parsera u odnosu na LL parsere su u veličini tablica koje LR parseri oni moraju imati, težem dodavanju semantike i generisanog koda i često čudnim porukama o greškama. 13.9. Generatori parsera Pravljenje parsera je toliko standardiziran posao da postoje i programi koji ih generišu iz opisa gramatike jezika. Mogu se podijeliti na generatore leksičkih analizatora, generatore LR parsera i generatore LL parsera. Najpoznatiji generator leksičkih analizatora je LEX, i njegova besplatna varijanta FLEX. Leksički analizator generisan ovakvim programom je, na primjer, sposoban da ključnu riječ BEGIN prizna kao jedan simbol, dok riječ BEGI predstavlja četiri simbola. Slijedi dio ulazne datoteke koja se koristi za generisanje leksičkog analizatora (skanera) koji prepoznaje programski jezik Pascal, a koju prihvata YACC. [a-zA-Z]([a-zA-Z0-9])* if (is_keyword(yytext, kw)) {return(kw);} else {return(IDENTIFIER);} ":=" return(ASSIGNMENT); '({NQUOTE}|'')+' return(CHARACTER_STRING); ":" return(COLON); "," return(COMMA); [0-9]+ return(DIGSEQ); "." return(DOT); ".." return(DOTDOT); "=" return(EQUAL); ">=" return(GE); ">" return(GT); "[" return(LBRAC); "<=" return(LE); LEX sarađuje sa generatorom LR parsera YACC (Yet Another Compiler Compiler) čija se besplatna varijanta zove Bison. Iz definicije gramatike kakva je data na kraju klasične knjige Kernighan-Ritchie, "Programski jezik C" može se generisati parser, obično napisan u jeziku C, zajedno sa tabelama. Na slici je dat dio ulazne datoteke koja se koristi za generisanje parsera koji prepoznaje programski jezik Pascal, a koju prihvata YACC. program : program_heading semicolon block DOT ; program_heading : _PROGRAM identifier | _PROGRAM identifier LPAREN identifier_list RPAREN ; identifier_list : identifier_list comma identifier | identifier ; block : label_declaration_part constant_definition_part type_definition_part variable_declaration_part procedure_and_function_declaration_part statement_part ; module : constant_definition_part type_definition_part variable_declaration_part procedure_and_function_declaration_part ; Parseri LEX i YACC su izrađeni i u verzijama koje generišu izvorni kod parsera u drugim programskim jezicima pored jezika C. Tako na primjer program TPLY - TP Lex and Yacc generiše izvorni kod za Turbo Pascal. Eikhound je generator generalizovanih LR parsera koji može prevesti svaku kontekstno slobodnu gramatiku, uključujući i one koje generišu shift/reduce konflikte. Jedan od generatora LL(1) parsera zove se COCO/R i napravljen je u različitim verzijama za razne jezike izvornog koda koji se generiše. Prednost ovog generatora je u vrlo preglednom ulaznom formatu (standardni BNF) i čitljivom izlaznom kodu. Ovaj generator iz iste ulazne datoteke pravi i leksičke analizatore. . Na slici je dat dio ulazne datoteke koja se koristi za generisanje leksičkog analizatora (skanera) koji prepoznaje programski jezik Pascal, a koju prihvata COCO/R. 103 TOKENS identifier integer real string = = = letter { letter | digit } . digit { digit } | digit { digit } CONTEXT ("..") . digit { digit } "." digit { digit } [ "E" ["+" | "-"] digit { digit } ] | digit { digit } "E" ["+" | "-"] digit { digit } . = "'" { noQuote1 | "''" } "'" . PRODUCTIONS Pascal ExternalFiles Block DeclarationPart = "program" NewIdent [ ExternalFiles ] ";" Block "." . = "(" NewIdentList ")" . = DeclarationPart StatementPart . = LabelDeclarations ConstDefinitions TypeDefinitions VarDeclarations { ProcDeclarations } . /* ---------------------------------------------------------------- */ LabelDeclarations = [ "label" Labels ";" ] . Labels = Label { "," Label } . Label = UnsignedInt . /* -------------------------------------------------------------------- */ ConstDefinitions = [ "const" ConstDef { ConstDef } ] . ConstDef = NewIdent "=" Constant ";" . O načinu pripreme ulaznih datoteka za spomente generatore parsera potrebno je pročitati njihovu dokumentaciju. Generatori parsera se inače zovu i kompajler-kompajleri. 13.10. Rezime poglavlja Detaljnije znanje o pravljenju kompajlera može se steći upoznavanjem teorije formalne lingvistike i parsiranja. Gramatika programskog jezika je definisana skupom neterminalnih simbola, skupom terminalnih simbola, jezičkim pravilima i početnim ili ciljnim simbolom. Gramatike se dijele na formalne, kontekstno neovisne, kontekstno osjetljive i regularne. Za kontekstno neovisne gramatike se prave parseri koji obavljaju sintaksnu analizu. LL parsiranje je metoda koja radi od vrha ka dnu razvijajući stalno ulazni string i zavisno od sljedećeg terminalnog simbola poziva odgovarajući potprogram. LR parsiranje koristi stek i tablice kako bi se prepoznao odgovarajući jezički pojam i ova metoda ide odozdo nagore. LR parseri pokrivaju širu klasu gramatika od LL parsera. Parseri se mogu praviti generatorima parsera kakvi su Yacc i COCO/R. 104 14. OSNOVNI WIN32 API PROGRAM Nakon što je napisan kompajler, slijedi pisanje sistemskih funkcija. Sretna je okolnost što operativni sistem Windows već ima ogroman broj sistemskih funkcija tako da je samo potrebno pozivati ih. Radi razumijevanja rada testnih aplikacija, kao i razumijevanja koncepta sistemskih poziva pod operativnim sistemom Windows, slijedi nekoliko lekcija koje govore o načinu korištenja Windows sistemskih funkcija. 14.1. Hello World Najprimitivniji FILDZAN32 Windows program izgleda kao na slici Sl. 14.1.1. Cijeli funkcija MessageBoxA(cijeli a,karakter * b, karakter * c, cijeli d); { MessageBoxA(0,"Zdravo", "Fildzanski pozdrav", 0); 0; } Sl. 14.1.1. 14.2. Primitivni Win32 program Prosti Prozor Programi koji prikazuju prozor na ekranu imaju standardizovani izgled kao na slici Sl. 14.2.1: cijeli funkcija RegisterClassExA(cijeli * wndclass); cijeli funkcija ShowWindow ( cijeli a,cijeli b) ; cijeli funkcija UpdateWindow(cijeli hWnd) ; cijeli funkcija GetMessageA (cijeli a, cijeli b, cijeli c,cijeli * d); cijeli funkcija TranslateMessage (cijeli * d) ; cijeli funkcija DispatchMessageA (cijeli * d) ; cijeli funkcija CreateWindowExA(cijeli a,cijeli b,cijeli c, cijeli d,cijeli e,cijeli f, cijeli g,cijeli h,cijeli i, karakter * j,karakter * k,cijeli l); cijeli funkcija LoadCursorA ( cijeli a,cijeli b) ; cijeli funkcija LoadIconA ( cijeli a,cijeli b) ; cijeli funkcija DestroyWindow ( cijeli a) ; cijeli funkcija PostQuitMessage ( cijeli a) ; cijeli funkcija DefWindowProcA (cijeli a, cijeli b, cijeli c,cijeli d); cijeli funkcija MessageBoxA (cijeli a, karakter * b, karakter * c,cijeli d); cijeli funkcija WinExec (karakter * b, karakter * c); cijeli funkcija GetModuleHandleA ( cijeli a) ; cijeli hInstance; karakter * klasa; slog { cijeli cbSize; cijeli style; cijeli * lpfnWndProc; cijeli cbClsExtra; cijeli cbWndExtra; cijeli hInstance; cijeli hIcon; cijeli hCursor; cijeli hbrBackground; karakter * lpszMenuName; karakter * lpszClassName; cijeli hIconSm; } wc; ` Klasa prozora cijeli hwnd; slog { cijeli hwnd; cijeli message; cijeli wParam; cijeli lParam; cijeli time; slog { cijeli x; cijeli y; } pt; } Msg; ` Poruka ako (msg=16){ DestroyWindow(hwnd); obrada:=1;}` WM_CLOSE ako (msg=2) {PostQuitMessage(0); obrada:=1;} `WM_DESTROY ako (obrada#1) { DefWindowProcA(lParam,wParam,msg,hwnd); } inace {0;} } ` Glavni program { ` Korak 1: Registracija prozorske klase hInstance:=GetModuleHandleA(0); wc.cbSize := 48; wc.style := 0; wc.lpfnWndProc := WndProc; wc.cbClsExtra := 0; wc.cbWndExtra := 0; wc.hInstance := hInstance; wc.hIcon := LoadIconA(32512,0); `IDI_APPLICATION wc.hCursor := LoadCursorA(32512,0); ` IDC_ARROW wc.hbrBackground := 6; `COLOR_WINDOW_FRAME wc.lpszMenuName := 0; wc.lpszClassName := "FILDZANKLASA"; wc.hIconSm := LoadIconA(32512,0); `IDI_APPLICATION ` ` Korak 4: Prozorska procedura cijeli funkcija WndProc(cijeli lParam, cijeli wParam, cijeli } msg, cijeli hwnd) { cijeli obrada; obrada:=0; ako (!RegisterClassExA(&wc)) { MessageBoxA(0, "Greska","Neuspjela registracija!",0); } inace { Korak 2: Kreiranje prozora hwnd:=CreateWindowExA(0,hInstance,0,0,120,140, 100,200, 13565952, ` ,WS_OVERLAPPEDWINDOW "Windows aplikacija","FILDZANKLASA",512); ako (hwnd = 0) { MessageBoxA(0, "Greska","Neuspjelo kreiranje!",0); } inace { ShowWindow(10,hwnd); `SW_SHOW UpdateWindow(hwnd); ` Korak 3: Petlja poruka dok (GetMessageA(0,0,0,&Msg) > 0) { TranslateMessage(&Msg); DispatchMessageA(&Msg); } Msg.wParam; } } Sl. 14.2.1. Osnovni prozor Ovo je jedan od najkraćih primjera koji generiše osnovni prozor pod Windowsom. Slijedi objašnjenje rada u četiri koraka. 105 14.3. Korak 1: Registracija prozorske klase Prozorska klasa čuva informacije o tipu prozora uključujući njegovu prozorsku proceduru koja ga kontroliše, male i velike ikone prozora i pozadinske boje, Na ovaj način moguće je registrovati klasu jednom i kreirati prozora koliko se želi bez specificiranja svih tih atributa svaki put, mada se oni mogu po želji mijenjati za pojedinačne prozore. Prozorske klase nemaju veze sa C++ klasama. ` Korak 1: Registracija prozorske klase hInstance:=GetModuleHandleA(0); wc.cbSize := 48; wc.style := 0; wc.lpfnWndProc := WndProc; wc.cbClsExtra := 0; wc.cbWndExtra := 0; wc.hInstance := hInstance; wc.hIcon := LoadIconA(32512,0); `IDI_APPLICATION wc.hCursor := LoadCursorA(32512,0); ` IDC_ARROW wc.hbrBackground := 6; `COLOR_WINDOW_FRAME wc.lpszMenuName := 0; wc.lpszClassName := "FILDZANKLASA"; wc.hIconSm := LoadIconA(32512,0); `IDI_APPLICATION ako (!RegisterClassExA(&wc)) { MessageBoxA(0, "Greska","Neuspjela registracija!",0); } inace { Ovaj se kod koristi u glavnom programu za registraciju prozorske klase. Sada će se popuniti struktura WNDCLASSEX i poziva funkcija RegisterClassEx() Članovi strukture utiču na klasu prozora kako slijedi: cbSize : Veličina strukture. style : Stil klase, CS_xxxxx, on se obično postavlja na 0.. lpfnWndProc :Pokazivač na proceduru koja obraðuje poruke za ovu klasu prozora. cbClsExtra : Količina dodatnih podataka alociranih za ovu klasu u memoriji. Obično 0. cbWndExtra: Količina dodatnih podataka u memoriji alociranih po prozoru. Obično 0... hInstance : Handle koji pokazuje na instancu aplikacije (dobiven funkcijom GetModuleHandle) hIcon : Velika (32x32) ikona koja se prikazuje prilikom AltTab. hCursor : Kurzor koji se prikazuje preko prozora ove klase. hbrBackground: Oznaka četke za pozadinu za postavljanje boje ovog prozora lpszMenuName: Ime menija u resursnom dijelu datoteke za prozore ove klase lpszClassName: Ime kojim se klasa identificira hIconSm : Mala (16x16) ikona koja se pojavljuje u taskbaru i u gornjem lijevom uglu prozora. U praksi se ova struktura ne pamti, nego se najčešæe kopira, niti ima potrebe pamtiti je. Neophodno je imati help datoteke kada se želi modifikovati neki od parametara.. Nakon što je ova struktura popunjena, poziva se RegisterClassEx i provjeravaju greške. U slučaju greške prikaže se poruka i prekida program izlaskom iz glavnog programa. 14.4. Korak 2: Kreiranje prozora Nakon što je klasa registrovana, slijedi kreiranje prozora pomoću nje. To se radi pomoću funkcije CreateWindowEx, čiji će parametri sada biti objašnjeni.. ` Korak 2: Kreiranje prozora hwnd:=CreateWindowExA(0,hInstance,0,0,120,140, 100,200, 13565952, ` ,WS_OVERLAPPEDWINDOW "Windows aplikacija","FILDZANKLASA",512); ako (hwnd = 0) { MessageBoxA(0, "Greska","Neuspjelo kreiranje!",0); } inace { Zadnji parametar, 512 je prošireni windows stil koji daje drugačiji izgled ivice. Može se eksperimentirati i sa drugim vrijednostima.. 106 Ime klase "FILDZANKLASA" kaže sistemu kakvu vrstu prozora da kreira. U datom primjeru, treba kreirati prozor od klase koja je upravo registrovana, pa će se njeno ime i koristiti. Nakon toga se navodi ime prozora ili naslov koji se prikazuje u naslovnom dijelu prozora.. Parametar koji u datom primjeru ima vrijednost 13565952 (WS_OVERLAPPEDWINDOW) je parametar stila prozora. Ima više različitih stilova i korisno je eksperimentisati sa njima da se vidi šta koji radi.. Sljedeća četiri parametra (120,140,100,200) su visina prozora, širina prozora, y koordinata i x koordinata x i y koordinate gornjeg lijevog ugla i širina i visina prozora. Jedinice su u pikselima, ishodište koordinatnog sistema je gornji lijevi ugao, tako da y osa raste prema dolje, a x osa prema desno. Sljedeća četiri parametra (0,hinstance,0,0) su pokazivač na dodatne podatke o kreiranju prozora, te hendlovi na instancu aplikacije, meni i roditeljski prozor. Ekranska unosna polja ili dugmad predstavljaju podprozore i za njih je potrebno postaviti vrijednost Parent. U ovom primjeru, ovo je glavni prozor i on nema roditeljskog prozora.. Čest uzrok grešaka u programima je što se ne provjerava rezultat funkcija. CreateWindow() često pada i kod iskusnih programera, stoga je potrebno uvijek provjeravati njen rezultat! ako (hwnd = 0) { MessageBoxA(0, "Greska","Neuspjelo kreiranje!",0); } Nakon što je prozor kreiran i provjerena ispravnost njegovog hendla, sada je potrebno prikazati i ažurirati prozor. Konstanta 10 (SW_SHOW) znači da se prozor treba prikazati. ShowWindow(10,hwnd); `SW_SHOW UpdateWindow(hwnd); 14.5. Korak 3: Petlja poruka Ovo je srce cijelog programa, praktično sve što program radio prolazi kroz ovu tačku. ` Korak 3: Petlja poruka dok (GetMessageA(0,0,0,&Msg) > 0) { TranslateMessage(&Msg); DispatchMessageA(&Msg); } Msg.wParam; } GetMessage() preuzima poruku iz reda čekanja korisničke aplikacije. Svaki put kada korisnik pomjeri miša, otkuca nešto na tastaturi, klikne na meni prozora ili uradi mnogo drugih stvari, poruke se generišu od strane sistema i smjeste u red čekanja korisničkog programa. Pozivom GetMessage() zahtijeva se da se sljedeća poruka izbaci iz reda čekanja i preda programu za procesiranje. Ako nema poruke GetMessage prelazi u čekanje do nailaska nove. Ukoliko to predstavlja problem, neki programi koriste poruku PeekMessage() koja radi isto kao GetMessage, samo što nastavlja rad ako u redu čekanja nema novih poruka.. TranslateMessage() dodatno procesira poruke tastature kao što je generisanje poruka WM_CHAR da se šalju zajedno sa WM_KEYDOWN porukom. Poruka DispatchMessage šalje poruku prozoru kome je poruka namijenjena. To može biti glavni prozor aplikacije, ali i bilo koji drugi prozor, korisnička kontrola ili neki prozor kreiran od strane sistema ili druge aplikacije. O tome ne treba brinuti jer se je jedini zadatak programa da preuzme i pošalje poruku, a sistem rješava kako će opna doći do odgovarajućeg prozora.. 14.6. Korak 4: Prozorska procedura Ako je petlja poruka srce programa, prozorska procedura je njegov mozak. Na ovom mjestu se obraðuju sve poruke poslane prozoru.. ` Korak 4: Prozorska procedura cijeli funkcija WndProc(cijeli lParam, cijeli wParam, cijeli msg, cijeli hwnd) { cijeli obrada; obrada:=0; ako (msg=16){ DestroyWindow(hwnd); obrada:=1;} ` Poruka WM_CLOSE ako (msg=2) {PostQuitMessage(0); obrada:=1;} ` Poruka WM_DESTROY ako (obrada#1) { DefWindowProcA(lParam,wParam,msg,hwnd); } inace {0;} } Prozorska procedura se poziva za svaku poruku. HWND parametar je hendl prozora, tj. onaj na koga se poruka odnosi. To je bitan podatak jer svi prozori iste klase dijele istu prozorsku proceduru, pa se oni meðusobno razlikuju po HWND parametru. 107 WM_CLOSE se šalje kada korisnik pritisne taster Close ili Alt+F4. To će izazvati uništavanje prozora i inače, ali je ovdje obrada izdvojena kako bi se mogao dodati eventualni kod koji posprema ostale podatke prije uništenja prozora, kao što je upit korisnika za snimanje datoteka.. Poziv funkcije DestroyWindow() šalje poruku WM_DESTROY prozoru koji treba biti uništen, uništavajući potom sve njegove podprozore. Na prijem ove poruke poziva se funkcija PostQuitMessage. Ova funkcija šalje WM_QUIT petlji za prozore. Ova se poruka nikada ne dobija, jer ona izaziva da GetMessage() vrati netačnu vrijednost čime se prekida obrada poruka. 14.7. Obrada poruka Sada prozor postoji mada može da radi jedino ono što mu omogućava DefWindowProc(), proširivanja, maksimiziranja, ali nikakav drugi kod. Dodatne funkcionalnosti se mogu dodavati obradom pojedinačnih poruka. Obrada poruke predstavlja širenje prozorske procedure dodavanjem aktivnosti u slučaju prijema poruke. U proceduru WndProc() dodaće se kod koji prikazuje ime programa kada se klikne mišem unutar prozora. Trenutno u WndProc postoji sljedeće: ` Korak 4: Prozorska procedura cijeli funkcija WndProc(cijeli lParam, cijeli wParam, cijeli msg, cijeli hwnd) { cijeli obrada; obrada:=0; ako (msg=16){ DestroyWindow(hwnd); obrada:=1;} ` Poruka WM_CLOSE ako (msg=2) {PostQuitMessage(0); obrada:=1;} ` Poruka WM_DESTROY ako (obrada#1) { DefWindowProcA(lParam,wParam,msg,hwnd); } inace {0;} } Da se obradi klik na lijevi taster miša, dodaje se obrada poruke WM_LBUTTONDOWN. Obrada poruke znači njeno dodavanje u WndProc kao na sljedećoj slici: ` Korak 4: Prozorska procedura cijeli funkcija WndProc(cijeli lParam, cijeli wParam, cijeli msg, cijeli hwnd) { cijeli obrada; obrada:=0; ako (msg=16){ DestroyWindow(hwnd); obrada:=1;} ` Poruka WM_CLOSE ako (msg=2) {PostQuitMessage(0); obrada:=1;} ` Poruka WM_DESTROY ako (msg=513) { ` DODANO obrada:=1;} ` Poruka WM_LBUTTONDOWN ` DODANO ako (obrada#1) { DefWindowProcA(lParam,wParam,msg,hwnd); } inace {0;} } Sada treba napisati šta će se dogoditi kada se uđe u taj dio programa. Kod koji se želi dodati je prikaz imena datoteke korisničkog programima. U kasnijim primjerima će se samo prikazivati kod koji se želi integrisati u program, u cilju smanjenja kucanja.. GetModuleFileNameA (MAXPATH, szFileName, hInstance); MessageBoxA(0, "This program is:",szFileName, hwnd); Gore prikazani kod će se izvršiti kada se klikne mišem na formu programa i dodaje se u osnovnu Windows aplikaciju: ` Korak 4: Prozorska procedura cijeli funkcija WndProc(cijeli lParam, cijeli wParam, cijeli msg, cijeli hwnd) { cijeli obrada; obrada:=0; ako (msg=16){ DestroyWindow(hwnd); obrada:=1;} ` Poruka WM_CLOSE ako (msg=2) {PostQuitMessage(0); obrada:=1;} ` Poruka WM_DESTROY ako (msg=513) { ` GetModuleFileNameA (MAXPATH, szFileName, hInstance); MessageBoxA(0, "This program is:",szFileName, hwnd); obrada:=1;} ` Poruka WM_LBUTTONDOWN ` ako (obrada#1) { DefWindowProcA(lParam,wParam,msg,hwnd); } inace {0;} } Nakon modifikacije ovog koda treba ga kompajlirati. Klik na prozor izaziva poruku sa imenom EXE programa. Dodane su varijable hInstance i szFileName. Prvi parametar funkcije GetModuleFIleName je HINSTANCE koji se odnosi na izvršni program (dakle EXE datoteka). Ta se vrijednost dobija funkcijom GetModuleHandle, koja za parametar NULL vraća oznaku datoteke u kojoj se nalazi proces koji ju je pozvao. Drugi parametar funkcije je pokazivač na mjesto gdje će se primiti ime datoteke i staza do navedenog modula i taj parametar je tima LPTSTR, odnosno pokazivač niz karaktera.: 108 #definiraj MAXPATH 260 cijeli funkcija GetModuleFileNameA (cijeli a,karakter * b,cijeli c); karakter [MAXPATH] szFileName; MAX_PATH definiše maksimalnu veličinu imena datoteke. Nakon poziva GetModuleFileName, bafer szFileName će se napuniti stringom koji sadrži ime naše EXE datoteke. Taj parametar se prosljeðuje funkciji MessageBox, čime se prikaže na ekranu.. Ukoliko dodavanje koda nije rezultovalo ispravnim kompajliranjem, slijedi kompletan kod. cijeli funkcija RegisterClassExA(cijeli * wndclass); cijeli funkcija ShowWindow ( cijeli a,cijeli b) ; cijeli funkcija UpdateWindow(cijeli hWnd) ; cijeli funkcija GetMessageA (cijeli a, cijeli b, cijeli c,cijeli * d); cijeli funkcija TranslateMessage (cijeli * d) ; cijeli funkcija DispatchMessageA (cijeli * d) ; cijeli funkcija CreateWindowExA(cijeli a,cijeli b,cijeli c, cijeli d,cijeli e,cijeli f, cijeli g,cijeli h,cijeli i, karakter * j,karakter * k,cijeli l); cijeli funkcija LoadCursorA ( cijeli a,cijeli b) ; cijeli funkcija LoadIconA ( cijeli a,cijeli b) ; cijeli funkcija DestroyWindow ( cijeli a) ; cijeli funkcija PostQuitMessage ( cijeli a) ; cijeli funkcija DefWindowProcA (cijeli a, cijeli b, cijeli c,cijeli d); cijeli funkcija MessageBoxA (cijeli a, karakter * b, karakter * c,cijeli d); cijeli funkcija WinExec (karakter * b, karakter * c); cijeli funkcija GetModuleHandleA ( cijeli a) ; #definiraj MAXPATH 260 cijeli funkcija GetModuleFileNameA (cijeli a,karakter * b,cijeli c); karakter [MAXPATH] szFileName; cijeli hInstance; karakter * klasa; slog { cijeli cbSize; cijeli style; cijeli * lpfnWndProc; cijeli cbClsExtra; cijeli cbWndExtra; cijeli hInstance; cijeli hIcon; cijeli hCursor; cijeli hbrBackground; karakter * lpszMenuName; karakter * lpszClassName; cijeli hIconSm; } wc; ` Klasa prozora cijeli hwnd; slog { cijeli hwnd; cijeli message; cijeli wParam; cijeli lParam; cijeli time; slog { cijeli x; cijeli y; } pt; } Msg; ` Poruka ako (msg=16){ DestroyWindow(hwnd); obrada:=1;} `WM_CLOSE ako (msg=2) {PostQuitMessage(0); obrada:=1;} `WM_DESTROY ako (msg=513) { ` GetModuleFileNameA (MAXPATH, szFileName, hInstance); MessageBoxA(0, "This program is:",szFileName, hwnd); obrada:=1;} ` Poruka WM_LBUTTONDOWN ` ako (obrada#1) { DefWindowProcA(lParam,wParam,msg,hwnd); } inace } ` Glavni program { ` Korak 1: Registracija prozorske klase hInstance:=GetModuleHandleA(0); wc.cbSize := 48; wc.style := 0; wc.lpfnWndProc := WndProc; wc.cbClsExtra := 0; wc.cbWndExtra := 0; wc.hInstance := hInstance; wc.hIcon := LoadIconA(32512,0); `IDI_APPLICATION wc.hCursor := LoadCursorA(32512,0); ` IDC_ARROW wc.hbrBackground := 6; `COLOR_WINDOW_FRAME wc.lpszMenuName := 0; wc.lpszClassName := "FILDZANKLASA"; wc.hIconSm := LoadIconA(32512,0); `IDI_APPLICATION ` ` Korak 4: Prozorska procedura cijeli funkcija WndProc(cijeli lParam, cijeli wParam, cijeli msg, cijeli hwnd) { cijeli obrada; } obrada:=0; 14.8. {0;} ako (!RegisterClassExA(&wc)) { MessageBoxA(0, "Greska","Neuspjela registracija!",0); } inace { Korak 2: Kreiranje prozora hwnd:=CreateWindowExA(0,hInstance,0,0,120,140, 100,200, 13565952, ` ,WS_OVERLAPPEDWINDOW "Windows aplikacija","FILDZANKLASA",512); ako (hwnd = 0) { MessageBoxA(0, "Greska","Neuspjelo kreiranje!",0); } inace { ShowWindow(10,hwnd); `SW_SHOW UpdateWindow(hwnd); ` Korak 3: Petlja poruka dok (GetMessageA(0,0,0,&Msg) > 0) { TranslateMessage(&Msg); DispatchMessageA(&Msg); } Msg.wParam; } } Šta je to poruka? Razumijevanje petlje poruka i cijele strukture u kojoj se šalju poruke windows programa je od suštinskog značaja za pisanje svega osim najtrivijalnijih poruka. Sada će se malo više pažnje posvetiti cijelom procesu radi izbjegavanja kasnijih konfuzija. Pogled na datoteke zaglavlja u kompajlerima za C pokazuje sljedeće definicije: #define WM_INITDIALOG #define WM_COMMAND 0x0110 0x0111 #define WM_LBUTTONDOWN 0x0201 Poruke se koriste za komunikaciju između mnogih podsistema. Ukoliko se želi da neki prozor ili kontrola (koja je samo specijalizovani prozor) obavi neku akciju, šalje joj se poruka. Drugi prozor može takođe da zahtjeve za aktivnosti našeg 109 prozora pozove porukom. Ako se dogodi kucanje na tastaturi ili pomicanje miša sistem šalje poruku prozoru na koji poruka utiče. Zadatak prozorske procedure je da odgovori na navedene poruke. Svaka poruka Windowsa može da ima do dva parametra, wParam i lParam. Unatoč imenu, pod Win32 oba parametra su 32 bitna. Ove parametre ne koristi svaka poruka, a i one koje ih koriste mogu ih interpretirati na različite načine. Tako na primjer, poruka WM_CLOSE ne koristi ni jedan parametar, a poruka WM_COMMAND koristi oba. U Parametru wParam kod poruke WM_COMMAND se u višoj riječi nalaz notifikacijska poruka, a u nižoj identifikator kontrole koja je poslala poruku. U parametru lParam se nalazi handle prozora ili kontrole koji je poslao poruku. Slanje poruke se vrši funkcijama PostMessage() ili SendMessage(). PostMessage() samo smjesti poruku u red čekanja i odmah se vrati, tako da poruka može ali i ne mora biti obrađena. SendMessage() šalje poruku direktno prozoru i ne vraća se dok prozor ne završi procesiranje poruke. Na ovaj način moguće je, na primjer, zatvoriti prozor slanjem poruke WM_CLOSE tom prozoru koristeći funkciju PostMessage(0,0,WM_CLOSE,hwnd); 14.9. Komunikacija sa dijaloškim prozorima Dijaloškim prozorima se šalju poruke u svrhu komunikacije sa njim Poruka pojedinoj kontroli na dijalogu se može poslati korištenjem funkcije GetDlgItem() koja na bazi identifikatora vraća hendl kontrole i zatim upotrebom funkcije SendMessage () ili upotrebom SendDlgItemMessage() koja kombinuje oba koraka. 14.10. Šta je red čekanja poruka? Ukoliko u trenutku obrade poruke WM_PAINT korisnik otkuca nešto na tastaturi, šta se treba dogoditi? Prekinuti iscrtavanje da bi se obradili tasteri ili ih ignorisati. Nijedno rješenje nije dobro, nego postoji red čekanja u koji se smještaju poruke kada se pošalju i nakon obrade ovih poruka one se uklanjaju. To omogućuje da se poruke ne gube dok se obrađuju druge poruke. 14.11. Šta je petlja poruka dok (GetMessageA(0,0,0,&Msg) > 0) { TranslateMessage(&Msg); DispatchMessageA(&Msg); } Petlja poruka poziva GetMessage() koja pregleda red čekanja. Ako je red čekanja prazan, program se zaustavlja i čeka da se poruka pojavi. Kada se desi događaj koji ubacuje poruku u red čekanja (npr. pritisak na taster miša), GetMessage() vraća pozitivnu vrijednost indicirajući da postoji poruka koja se treba obraditi i da je ona napunjena članovima MSG strukture koja joj je dodijeljena. Ova funkcija vraća vrijednost 0 ako primi poruku WM_QUIT i negativnu vrijednost ako se dogodila greška. Preuzimanje poruke u Msg varijablu i njeno prosljeđivanje funkciji TranslateMessage() je opcionalni korak koji prevodi virtualni taster u karakterske poruke. Nakon što je to urađeno, poruka se prosljeđuje funkciji DispatchMessage(). Ova funkcija provjeri kojem je prozoru namijenjena i traži prozorsku proceduru koja obrađuje taj prozor. Nakon toga poziva tu proceduru šaljući kao parametar hendl prozora, poruku, wParam i lParam. U prozorskoj proceduri se provjeri poruka i njeni parametri i obrađuje po želji. Ukoliko se poruka posebno ne obrađuje, poziva se DefWindowProc() koja obavlja podrazumijevane akcije, što često znači da se ništa ne radi. Po završetku prozorske procedure, DispatchMessage() se vrati i petlja se ponovo izvršava. Prozorska procedura se ne poziva magično iz sistema, nju zapravo poziva korisnički program funkcijom DispatchMessage. Ukoliko se to želi, isti efekat se može postići korištenjem GetWindowLong() funkcije koja za navedeni hendl nalazi prozorsku proceduru i direktno je zvati indirektnim pozivom funkcije. Ipak to neće raditi u složenijim aplikacijama, pošto su neki efekti koje implicitno radi DispatchMessage zanemareni. Aplikacija provodi većinu vremena u petlji za poruke. Kada se želi izaći iz te petlje, GetMessage() treba da vrati vrijednost 0 da se dođe do kraja WinMain funkcije. To obavlja PostQuitMessage(). Ona u red čekanja dodaje poruku WM_QUIT i umjesto vraćanja pozitivne vrijednosti GetMessage() puni Msg strukturu i vraća vrijednost 0. Polje wParam strukture Msg sadrži vrijednost koja je proslijeđena funkciji PostQuitMessage i ona se može ili ignorisati ili iskoristiti kao izlazni kod pri završetku procesa. 14.12. Rezime poglavlja Aplikacije koje nemaju prozore se mogu pisati na klasični način. Windows aplikacije sa prozorima su bazirane na petljama i porukama. Svaka windows aplikacija, koja treba da prikaže standardni prozor ima četiri faze: pripremu i registraciju prozorske klase, kreiranje prozora, petlju poruka i obradu poruka u prozorskoj proceduri. Slanje poruke u glavnoj petlji automatski pokreće proceduru za obradu prozora, a ova procedura je definisana u prozorskoj klasi. 110 15. KORISNIČKI INTERFEJS I GRAFIČKE PRIMITIVE Jedan od najvažnijih zadataka aplikacija napisanih u bilo kom programskom jeziku je komunikacija sa korisnikom. U ovom poglavlju će biti riječi o tome kako se mogu primati ulazni podaci od korisnika pod operativnim sistemom Windows, prilagođeno za FILDZAN-32.Prema načinu interakcije sa korisnikom, postoje tri vrste aplikacija, servisi koji nemaju nikakvu interakciju osim kroz konfiguracione datoteke ili Registry, konzolne aplikacije, koje komuniciraju preko tastature i tekstualnog izlaza i GUI aplikacije, koje imaju kompletan skup korisničkih kontrola. 15.1. Servisne aplikacije Ovo su obično sistemski procesi koji se startaju automatski po startu operativnog sistema. Ove aplikacije direktno ne komuniciraju sa korisnikom, nego primaju poruke od sistema. Tako na primjer, aplikacije koje predstavljaju Web server ne prikazuju ništa na ekranu, niti očitavaju išta sa tastature, nego obavljaju prijemom i slanjem podataka kroz socket funkcije. Servisne aplikacije u užem smislu se mogu startati i kada korisnik nije uopšte prijavljen na računar. 15.2. Konzolne aplikacije Već su prvi primjeri u FILDZAN-32 koji su se uspjeli kompajlirati predstavljali ovakve aplikacije. Konzola je interfejs koji omogućava ulaz/izlaz aplikacijama koje rade u znakovnom režimu. Konzola se sastoji od ulaznog bafera i jednog ili više ekranskih bafera. Ulazni bafer sadrži red ulaznih slogova od kojih svaki uključuje informacije u ulaznom događaju. Ekranski bafer je dvodimenzionalni niz znakova i informacija o boji za izlaz na prozoru konzole. Win32 dopušta funkcije visokog i niskog nivoa za pristup konzoli. Funkcije visokog nivoa su orijentisane prema znakovima i omogućavaju redirekciju podataka. Funkcije niskog nivoa prate ulaze sa tastature kao što su pojedinačni tasteri, događaje miša i omogućuju bolju kontrolu izlaza na ekran. Konzolne aplikacije se ne pišu ni na kakav poseban način. Treba jedino znati da jezik FILDZAN32 koji se razvija sam po sebi nema naredbe kao što su writeln ili scanf, pa treba napisati program koristeći Win32 API. Najvažnije funkcije visokog nivoa su GetStdHandle , ReadConsoleA i WriteConsoleA, koje su objašnjene u testnim primjerima šestog i sedmog poglavlja. Od funkcija niskog nivoa treba spomenuti funkciju PeekConsoleInput kojom se mogu očitavati tasteri bez čekanja. 15.3. Grafičke kontrole Grafičke aplikacije imaju drugačiji pristup ulaznim podacima od tekstualnih. Na ekranu se nalaze različite kontrole (dugmad, editna polja, kombinovane liste i slično) Sve Windows kontrole su zapravo prozori. To je bitno za znati, jer se tako mnoge funkcije namijenjene prozorima mogu koristiti i za kontrole. Tako na primjer, postavljanje naslova prozora ili upis podrazumijevane vrijednosti u editno polje obavljaju iste funkcije. Dva su pristupa pravljenju Windows kontrola. Jedan je preko resursnih dijaloga i zahtijeva upotrebu resursnog editora ili jezika za resursne skripte. Resursi se odvojeno kompajliraju i povezuju sa glavnim programom. To su binarni podaci koji opisuju izgled kontrola. Prednost pristupa je u mogućnosti ekstrakcije ekranskih formi iz izvršnog programa u cilju njihove popravke ili prevođenja na druge jezike. Druga prednost je što je osnovni program kraći. Treća prednost je što resursni editori mogu biti grafičke, vizuelne aplikacije, pa je njihova priprema razmjerno jednostavna. Nedostaci pristupa su potreba za posebnim kompajlerom resursa i veća rasparčanost koda jer se on nalazi i u datoteci sa programom i u datoteci sa resursom. Windows kontrole se mogu dobiti i direktnim pozivom CreateWindowExA funkcije za svaku kontrolu. Kako resursni kompajler za FILDZAN32 još nije napisan, koristiće se drugi metod. Dio parametara iz CreateWindowExA koji su korišteni za kreiranje osnovne Windows aplikacije se mogu primijeniti i ovdje, dok se drugi dio mijenja. Tako na primjer, za Windows kontrole nema potrebe registrovati klasu prozora, jer već postoji nekoliko standardnih: BUTTON - dugmad, checkbox-ovi i radio tasteri LISTBOX – liste podataka COMBOBOX - kombinovane liste podataka EDIT - unosna polja SCROLLBAR - klizna traka 111 STATIC - statični tekst SysAnimate32- kontrola koja prikazuje AVI datoteku msctls_hotkey32- kontrola koja predefiniše taster za brži pristup nekoj opciji msctls_progress32- mjerač realizacije nekog posla msctls_statusbar32 - statusna traka ToolbarWindow32 - alatna traka tooltips_class32 - informacioni prozorčić msctls_trackbar32 - potenciometarska kontrola msctls_updown32 - kontrola za unos podatka uz mogućnost uvećanja i umanjenja njegove vrijednosti tasterima SysHeader32 - zaglavlje pogleda na podatke u formi liste SysListView32 - Pogled na podatke u formi liste, koji omogućuje i pojedine ikone SysTabControl32 - Tab kontrola, omogućuje prikaz podataka u formi odvojenih kartica SysTreeView32 - Pogled stabla, hijerarhijski prikaz podataka RichEdit - Omogućuje unos tekstova koji mogu biti u boji i sadržati dodatne podatke Sa kontrolama se komunicira slanjem poruka kontroli funkcijom SendMessage ili odgovarajućim funkcijama za obradu prozora. Kontrole vraćaju prozoru poruku WM_COMMAND, WM_NOTIFY, WM_HSCROLL ili WM_VSCROLL, zavisno od same kontrole. U okviru wParam i lParam parametara nalaze se dodatne informacije koje govore o poruci. 15.4. Funkcije grafičkih kontrola kroz primjer Na slici Sl. 15.4.1 data je ekranska forma aplikacije za unos podataka o zainteresovanim licima za uvođenje kablovske televizije. Na ovoj formi se nalaze sve standardne Windows kontrole, koje se nalaze u USER32.DLL biblioteci. Sl. 15.4.1. Forma aplikacije Na ovoj formi se uočava da postoje kontrole tipa edit polja, listbox, combobox, checkbox, memo polja, menu, dugmad, scroll bar, statički tekst, iscrtani logo firme, ispisani tekst i menu. Sada će se pogledati cijeli listing programa, a zatim vidjeti kako se definiše pojedina vrsta kontrola i kako se očitavaju podaci koje ona šalje. 112 cijeli funkcija RegisterClassExA(cijeli * wndclass); cijeli funkcija ShowWindow ( cijeli a,cijeli b) ; cijeli funkcija UpdateWindow(cijeli hWnd) ; cijeli funkcija GetMessageA (cijeli a, cijeli b, cijeli c,cijeli * d); cijeli funkcija TranslateMessage (cijeli * d) ; cijeli funkcija DispatchMessageA (cijeli * d) ; cijeli funkcija CreateWindowExA(cijeli a,cijeli b,cijeli c, cijeli d,cijeli e,cijeli f, cijeli g,cijeli h,cijeli i, karakter * j,karakter * k,cijeli l); cijeli funkcija LoadCursorA ( cijeli a,cijeli b) ; cijeli funkcija LoadIconA ( cijeli a,cijeli b) ; cijeli funkcija DestroyWindow ( cijeli a) ; cijeli funkcija PostQuitMessage ( cijeli a) ; cijeli funkcija DefWindowProcA (cijeli a, cijeli b, cijeli c,cijeli d); cijeli funkcija MessageBoxA (cijeli a, karakter * b, karakter * c,cijeli d); cijeli funkcija WinExec (karakter * b, karakter * c); cijeli funkcija GetModuleHandleA ( cijeli a) ; cijeli funkcija SendMessageA (karakter * a,cijeli b, cijeli c, cijeli d); cijeli funkcija GetWindowTextA (cijeli a,karakter * b, cijeli c); cijeli funkcija IsDlgButtonChecked(cijeli a, cijeli b); cijeli funkcija SetScrollRange(cijeli a,cijeli b, cijeli c, cijeli d, cijeli e); cijeli funkcija SetScrollPos(cijeli a,cijeli b, cijeli c, cijeli d); cijeli funkcija GetScrollPos(cijeli a,cijeli b); cijeli funkcija BeginPaint(cijeli * a,cijeli b); cijeli funkcija EndPaint(cijeli * a,cijeli b); cijeli funkcija Ellipse(cijeli a, cijeli b, cijeli c,cijeli d, cijeli e); cijeli funkcija MoveToEx(cijeli * a, cijeli b, cijeli c,cijeli d); cijeli funkcija LineTo(cijeli a, cijeli b, cijeli c); cijeli funkcija TextOutA(cijeli a,cijeli * b,cijeli c,cijeli d,cijeli e); cijeli funkcija CreateMenu(); cijeli funkcija CreatePopupMenu(); cijeli funkcija AppendMenuA(karakter * a,cijeli b, cijeli c, cijeli d); cijeli funkcija SetMenu(cijeli a,cijeli b); cijeli hInstance; karakter * klasa; slog { cijeli cbSize; cijeli style; cijeli * lpfnWndProc; cijeli cbClsExtra; cijeli cbWndExtra; cijeli hInstance; cijeli hIcon; cijeli hCursor; cijeli hbrBackground; karakter * lpszMenuName; karakter * lpszClassName; cijeli hIconSm; } wc; ` Klasa prozora cijeli hwnd; slog { cijeli hwnd; cijeli message; cijeli wParam; cijeli lParam; cijeli time; slog { cijeli x; cijeli y; } pt; } Msg; ` Poruka slog { cijeli hdc; cijeli fErase; slog { cijeli left,top,right,bottom; } rcPaint; cijeli fRestore; cijeli fIncUpdate; cijeli [32] rgbReserved; } pstruct; cijeli hEdit1,hEdit2,hGroup1,hRadio1,hRadio2,hCheck1, hMemo1,hListBox1,hCombo1,hScroll1,hButton1,hStatic1, hStatic2,hStatic3,hStatic4,hStatic5,hStatic6,hdc,hMenu, hSubMenu; cijeli funkcija KreirajKontrole() { hEdit1:=CreateWindowExA(0,hInstance,0,hwnd,21,161,16,64, 1350565888, ` ws_child or ws_visible or ws_border "","EDIT",512); hEdit2:=CreateWindowExA(0,hInstance,0,hwnd,21,161,48,64, 1350565888, ` ws_child or ws_visible or ws_border "","EDIT",512); hGroup1:=CreateWindowExA(0,hInstance,0,hwnd,57,217,80,16, 1342177287, ` ws_child or ws_visible or bs_groupbox "Spol","BUTTON",0); hRadio1:=CreateWindowExA(0,hInstance,105,hGroup1,17,113,16,2 4, 1342177289, ` ws_child or ws_visible or bs_autoradiobutton "Muški","BUTTON",0); hRadio2:=CreateWindowExA(0,hInstance,106,hGroup1,17,113,32,2 4, 1342177289, ` ws_child or ws_visible or bs_autoradiobutton "Ženski","BUTTON",0); hCheck1:=CreateWindowExA(0,hInstance,107,hwnd,17,209,152,16, 1342177283, ` ws_child or ws_visible or bs_autocheckbox "Uplatio uvođenje","BUTTON",512); hMemo1:=CreateWindowExA(0,hInstance,0,hwnd,89,185,216,16, 1350565892, ` ws_child or ws_visible or ws_border or es_multiline "Memo","EDIT",512); hListBox1:=CreateWindowExA(0,hInstance,0,hwnd,97,200,24,272, 1352663043, ` ws_child or ws_visible or ws_border or lbs_standard "List1","LISTBOX",512); SendMessageA("1.Samo ` 384 LB_ADDSTRING SendMessageA("2.TV i ` 384 LB_ADDSTRING SendMessageA("3.Samo ` 384 LB_ADDSTRING SendMessageA("4.TV s ` 384 LB_ADDSTRING SendMessageA("5.Puni ` 384 LB_ADDSTRING TV program",0,384,hListBox1); Internet",0,384,hListBox1); Internet",0,384,hListBox1); kodiranimkanalima",0,384,hListBox1); paket",0,384,hListBox1); hCombo1:=CreateWindowExA(0,hInstance,0,hwnd,100,145,144,272, 1350566402, ` ws_child or ws_visible or ws_border or cbs_dropdown or cbs_hasstrings "COmbobox1","COMBOBOX",0); SendMessageA("Maršala Tita",0,323,hCombo1); ` 323 CB_ADDSTRING SendMessageA("Alipašina",0,323,hCombo1); ` 323 CB_ADDSTRING hScroll1:=CreateWindowExA(0,hInstance,0,hwnd,21,185,192,272, 1342177280, ` ws_child or ws_visible or sbs_horz "","SCROLLBAR",0); SetScrollRange(1,100,1,2,hScroll1); hButton1:=CreateWindowExA(0,hInstance,0,hwnd,25,75,256,288, 1342177280, ` ws_child or ws_visible or bs_pushbutton "Unesi","BUTTON",0); hStatic1:=CreateWindowExA(0,hInstance,0,hwnd,14,57,16,8, 1342177291, `ws_child or ws_visible or ss_simple "Prezime","STATIC",0); hStatic2:=CreateWindowExA(0,hInstance,0,hwnd,14,37,50,8, 1342177291, `ws_child or ws_visible or ss_simple "Ime","STATIC",0); hStatic3:=CreateWindowExA(0,hInstance,0,hwnd,14,72,200,16, 1342177291, `ws_child or ws_visible or ss_simple "Napomena","STATIC",0); hStatic4:=CreateWindowExA(0,hInstance,0,hwnd,14,103,8,272, 113 1342177291, `ws_child or ws_visible "Vrsta usluge","STATIC",0); or ss_simple ` Korak 4: Prozorska procedura cijeli funkcija WndProc(cijeli lParam, cijeli wParam, cijeli msg, cijeli hwnd) { cijeli obrada; obrada:=0; ako (msg=16){ DestroyWindow(hwnd); obrada:=1;}` WM_CLOSE ako (msg=15){ OnWMPaint(hwnd); obrada:=1;}` WM_PAINT ako (msg=2) {PostQuitMessage(0); obrada:=1;}` WM_DESTROY hStatic6:=CreateWindowExA(0,hInstance,0,hwnd,13,190,176,280, ako (msg=273) {OnWMCommand(wParam,lParam); obrada:=1;} 1342177291, `ws_child or ws_visible or ss_simple ` Poruka WM_COMMAND "Stepen realizacije","STATIC",0); ako (msg=276) {OnWMHScroll(wParam,lParam); obrada:=1;} ` Poruka WM_HSCROLL hMenu:=CreateMenu(); hSubMenu := CreatePopupMenu(); ako (obrada#1) { DefWindowProcA(lParam,wParam,msg,hwnd); AppendMenuA( "O& programu",200,0,hSubMenu); } AppendMenuA( "I&zlaz",201,0,hSubMenu); inace {0;} AppendMenuA("&Meni",hSubMenu,16,hMenu); SetMenu(hMenu,hwnd); } } hStatic5:=CreateWindowExA(0,hInstance,0,hwnd,14,78,128,280, 1342177291, `ws_child or ws_visible or ss_simple "Adresa","STATIC",0); cijeli funkcija OnWMHScroll(cijeli wParam,cijeli lParam) { cijeli nPos; ako (lParam=hScroll1)& (wParam & 65535 =5) `SB_THUMBTRACK { nPos:=wParam / 65536; SetScrollPos(1,nPos,2,hScroll1); } } cijeli funkcija OnWMCommand(cijeli wParam,cijeli lParam) { karakter [200] rezultat; cijeli nItem; ako (lParam=0) { ako (wParam & 65535 = 201) { PostQuitMessage(0); } ako (wParam & 65535 = 200) { MessageBoxA(0,"O programu", "Ovo je aplikacija koja demonstrira kontrole i GDI",0); } ` Glavni program { ` Korak 1: Registracija prozorske klase hInstance:=GetModuleHandleA(0); wc.cbSize := 48; wc.style := 0; wc.lpfnWndProc := WndProc; wc.cbClsExtra := 0; wc.cbWndExtra := 0; wc.hInstance := hInstance; wc.hIcon := LoadIconA(32512,0); `IDI_APPLICATION wc.hCursor := LoadCursorA(32512,0); ` IDC_ARROW wc.hbrBackground := 5; `SIVA wc.lpszMenuName := 0; wc.lpszClassName := "FILDZANKLASA"; wc.hIconSm := LoadIconA(32512,0); `IDI_APPLICATION ` } ako (lParam=hButton1) { GetWindowTextA(200,rezultat,hEdit1); MessageBoxA(0,"Prezime",rezultat,hwnd); GetWindowTextA(200,rezultat,hEdit2); MessageBoxA(0,"Ime",rezultat,hwnd); GetWindowTextA(200,rezultat,hCombo1); MessageBoxA(0,"Adresa",rezultat,hwnd); GetWindowTextA(200,rezultat,hMemo1); MessageBoxA(0,"Napomena",rezultat,hwnd); ako IsDlgButtonChecked(105,hGroup1)=1 { MessageBoxA(0,"Spol","Muski",hwnd); } ako IsDlgButtonChecked(106,hGroup1)=1 { MessageBoxA(0,"Spol","Zenski",hwnd); } ako IsDlgButtonChecked(107,hwnd)=1 { MessageBoxA(0,"Status","Platio",hwnd); } nItem := SendMessageA(0,0,392,hListBox1); ` LB_GETCURSEL ako nItem=2 { MessageBoxA(0,"TV","Ne koristi TV",hwnd); } ako (GetScrollPos(2,hScroll1)>50) { MessageBoxA(0,"Realizovanost","Preko 50",0); } } } cijeli funkcija OnWMPaint(cijeli hwnd) { hdc:=BeginPaint(&pstruct,hwnd); MoveToEx(0,250,400,hdc); LineTo(250,480,hdc); LineTo(310,480,hdc); LineTo(310,400,hdc); LineTo(250,400,hdc); TextOutA(5,"CBLTV",253,403,hdc); Ellipse(294,470,264,410, hdc); EndPaint(&pstruct,hwnd); } ako (!RegisterClassExA(&wc)) { MessageBoxA(0, "Greska","Neuspjela registracija!",0); } inace { Korak 2: Kreiranje prozora hwnd:=CreateWindowExA(0,hInstance,0,0,383,535, 177,108, 13565952, ` WS_OVERLAPPEDWINDOW "Forma za unos","FILDZANKLASA",512); ako (hwnd = 0) { MessageBoxA(0, "Greska","Neuspjelo kreiranje!",0); } inace { KreirajKontrole(); ShowWindow(10,hwnd); `SW_SHOW UpdateWindow(hwnd); ` Korak 3: Petlja poruka dok (GetMessageA(0,0,0,&Msg) > 0) { TranslateMessage(&Msg); DispatchMessageA(&Msg); } Msg.wParam; } } } Sl. 15.4.2. Aplikacija sa podprozorima kontrolama 114 Na listingu Sl. 15.4.2 se vidi da se registracija prozorske klase uopšte nije promijenila, izuzev boje pozadine. Dijelu koda za kreiranje prozora je dodan poziv funkcije KreirajKontrole nakon što je kreiran glavni program, dok je glavna petlja poruka identična osnovnoj verziji. Prozorska procedura obrađuje pet poruka. ` Korak 4: Prozorska procedura cijeli funkcija WndProc(cijeli lParam, cijeli wParam, cijeli msg, cijeli hwnd) { cijeli obrada; obrada:=0; ako (msg=16){ DestroyWindow(hwnd); obrada:=1;}` WM_CLOSE ako (msg=15){ OnWMPaint(hwnd); obrada:=1;}` WM_PAINT ako (msg=2) {PostQuitMessage(0); obrada:=1;}` WM_DESTROY ako (msg=273) {OnWMCommand(wParam,lParam); obrada:=1;} ` Poruka WM_COMMAND ako (msg=276) {OnWMHScroll(wParam,lParam); obrada:=1;}` Poruka WM_HSCROLL ako (obrada#1) { DefWindowProcA(lParam,wParam,msg,hwnd); } inace {0;} } Poruka WM_COMMAND (broj 273) se šalje glavnom prozoru svaki put kada se izabere neka opcija na meniju ili pritisne neki ekranski taster, radio taster ili checkbox. Ova poruka uz parametre wparam i lparam šalje dodatne vrijednosti koji određuju kontrolu. Poruka WM_PAINT (broj 15) se šalje glavnom prozoru svaki put kada se treba iscrtati dio prozora. Horizontalne klizne trake (scrollbar) šalju poruke WM_HSCROLL (broj 276). 15.5. Meniji Kreiranje menija se vrši funkcijom CreateMenu(), a podmenija funkcijom CreatePopupMenu(). Ove funkcije interno kreiraju menije, i dodijele mu identifikator, handle. To se vidi na dijelu koda koji se nalazi na kraju funkcije KreirajKontrole() hMenu:=CreateMenu(); hSubMenu := CreatePopupMenu(); AppendMenuA( "O& programu",200,0,hSubMenu); AppendMenuA( "I&zlaz",201,0,hSubMenu); AppendMenuA("&Meni",hSubMenu,16,hMenu); SetMenu(hMenu,hwnd); Za dodavanje opcija menija koristi se funkcija AppendMenuA, čiji prvi parametar predstavlja tekst opcije, drugi parametar predstavlja broj koji će meni proslijediti uz poruku WM_COMMAND ili handle podmenija. Treći parametar predstavlja status menija i ima vrijednost 0 ako je riječ o opciji, a 16 ako je riječ o podmeniju. Moguće je još mnogo različitih statusa. Posljednji parametar predstavlja handle menija ili podmenija kome se pridružuje ova opcija. Meni se dodjeljuje prozoru primjenom opcije SetMenu, čiji je prvi parametar handle menija, a drugi je handle prozora. Izbor opcije u meniju šalje glavnom prozoru poruku WM_COMMAND. Odgovor na opcije se vidi u sljedećem dijelu koda unutar funkcije OnWMCommand ako (lParam=0) { ako (wParam & 65535 = 201) { PostQuitMessage(0); } ako (wParam & 65535 = 200) { MessageBoxA(0,"O programu", "Ovo je aplikacija koja demonstrira kontrole i GDI",0); } } Poruka WM_COMMAND koja je stigla od menija u parametru lParam ima vrijednost 0, a nižih 16 bita parametra wParam predstavlja konstantu koja je data uz drugi parametar funkcije AppendMenuA. 15.6. Dugme - Button Kontrola oblika dugmeta se kreira kao i svaki prozor, CreateWindowExA funkcijom. U našem primjeru, to je naredba hButton1:=CreateWindowExA(0,hInstance,0,hwnd,25,75,256,288, 1342177280, ` ws_child or ws_visible or bs_pushbutton "Unesi","BUTTON",0); Kao što se vidi, klasa prozora je BUTTON, a stil je kombinacija ws_child , ws_visible i bs_pushbutton. Treći parametar je hwnd, što znači da je riječ o kontroli koja ima roditelja, tj. prozor kome će se slati poruke. Posljednji parametar je 0 što znači da nema specijalnog okvira. Prepoznavanje da je taster pritisnut može se vršiti u obradi poruke WM_COMMAND, što se vidi iz sljedećeg dijela koda unutar funkcije OnWMCommand: 115 ako (lParam=hButton1) { ... } Parametar lParam poruke WM_COMMAND sadrži handle tastera koji je pritisnut, hButton1. U okviru obrade ovog tastera se nalazi kod koji očitava vrijednosti svih kontrola i prikazuje ih na ekranu koristeći MessageBoxA. 15.7. Editna i memo polja Najvažnija kontrola za unos podataka su polja za unos teksta ili editna polja. Ove kontrole imaju klasu EDIT kao u sljedećem dijelu koda hEdit1:=CreateWindowExA(0,hInstance,0,hwnd,21,161,16,64, 1350565888, ` ws_child or ws_visible or ws_border "","EDIT",512); hEdit2:=CreateWindowExA(0,hInstance,0,hwnd,21,161,48,64, 1350565888, ` ws_child or ws_visible or ws_border "","EDIT",512); Memo polja se razlikuju od običnih editnih polja po tome što imaju dodatni stil es_multiline hMemo1:=CreateWindowExA(0,hInstance,0,hwnd,89,185,216,16, 1350565892, ` ws_child or ws_visible or ws_border or es_multiline "Memo","EDIT",512); Očitavanje vrijednosti kontrole se svodi na čitanje naslova prozora funkcijom GetWindowTextA unutar obrade pritiska na dugme. Prvi argument ove funkcije je broj bajtova koliki tekst treba da bude, drugi je adresa na koju se tekst smješta a treći je hendl kontrole. U sljedećem dijelu koda se primljeni podaci prikazuju u poruci (prava aplikacija bi ih upisala u bazu podataka) GetWindowTextA(200,rezultat,hEdit1); MessageBoxA(0,"Prezime",rezultat,hwnd); GetWindowTextA(200,rezultat,hEdit2); MessageBoxA(0,"Ime",rezultat,hwnd); GetWindowTextA(200,rezultat,hCombo1); MessageBoxA(0,"Adresa",rezultat,hwnd); GetWindowTextA(200,rezultat,hMemo1); MessageBoxA(0,"Napomena",rezultat,hwnd); U složenijim slučajevima editno polje treba dodatno kontrolisati, recimo zabranjujući da se nenumeričke vrijednosti uopšte mogu otkucati. To se radi obradom poruka koje editno polje direktno šalje glavnom prozoru. 15.8. Grupe kontrola i radio tasteri Radio tasteri su okruglog oblika i omogućavaju izbor jedne od više opcija. Svaki radio taster predstavlja poseban prozor klase BUTTON. Da bi se znalo između kojih radio tastera se odabira opcija, formira se grupa tastera (group box) koja je takođe prozor klase BUTTON, ali sa kombinacijom stilova ws_child, ws_visible i bs_groupbox, kao što se vidi iz dijela koda: hGroup1:=CreateWindowExA(0,hInstance,0,hwnd,57,217,80,16, 1342177287, ` ws_child or ws_visible or bs_groupbox "Spol","BUTTON",0); Radio tasteri imaju kombinaciju stilova ws_child, ws_visible i bs_autoradiobutton. Ono što je bitno primijetiti da se za roditeljski prozor ne navodi handle od glavnog prozora, nego od grupe tastera hGroup1, te da su koordinate relativne u odnosu grupu kontrola. Pored toga, svaki radio taster treba da ima svoju specijalnu numeričku oznaku koja je treći parametar i koja u narednim linijama ima vrijednosti 105, odnosno 106. hRadio1:=CreateWindowExA(0,hInstance,105,hGroup1,17,113,16,24, 1342177289, ` ws_child or ws_visible or bs_autoradiobutton "Muški","BUTTON",0); hRadio2:=CreateWindowExA(0,hInstance,106,hGroup1,17,113,32,24, 1342177289, ` ws_child or ws_visible or bs_autoradiobutton "Ženski","BUTTON",0); Očitavanje vrijednosti radio tastera se vrši funkcijom IsDlgButtonChecked, čiji prvi argument ima vrijednost ranije navedene numeričke oznake, a drugi je handle na grupu tastera. Ako je taster izabran, ova će funkcija vratiti tačnu vrijednost, što se vidi na sljedećem dijelu koda. ako IsDlgButtonChecked(105,hGroup1)=1 { MessageBoxA(0,"Spol","Muski",hwnd); } ako IsDlgButtonChecked(106,hGroup1)=1 { MessageBoxA(0,"Spol","Zenski",hwnd); } 116 15.9. Kontrolne kućice (checkbox) Kontrolnom kućicom (checkbox) se omogućuje unos podataka koji imaju vrijednosti tipa tačno/netačno. Ova komponenta se kreira kao i obični tasteri (prozor klase BUTTON) uz stil koji je kombinacija stilova ws_child, ws_visible i bs_autocheckbox. I kod ove komponente je potrebno navesti internu oznaku (koja u sljedećem dijelu koda ima vrijednost 107) hCheck1:=CreateWindowExA(0,hInstance,107,hwnd,17,209,152,16, 1342177283, ` ws_child or ws_visible or bs_autocheckbox "Uplatio uvođenje","BUTTON",512); Očitavanje vrijednosti ove komponente se takođe vrši funkcijom IsDlgButtonChecked, kao u sljedećem dijelu koda: ako IsDlgButtonChecked(107,hwnd)=1 { MessageBoxA(0,"Status","Platio",hwnd); } 15.10. Liste podataka (listbox) Liste podataka (listbox) služe za izbor podataka poredanih jedan iznad drugog. I ova kontrola se kreira kao prozor, ali koji je klase LISTBOX. Stil je kombinacija ws_child , ws_visible , ws_border i lbs_standard. Kreiranom listboxu, treba poslati vrijednosti koristeći funkciju SendMessageA. Prvi argument ove funkcije (lParam) je pointer na niz karaktera koji se dodaje u listbox, drugi je 0 (wParam), treći je 384 ( poruka LB_ADDSTRING) a četvrti je handle na listbox. hListBox1:=CreateWindowExA(0,hInstance,0,hwnd,97,200,24,272, 1352663043, ` ws_child or ws_visible or ws_border or lbs_standard "List1","LISTBOX",512); SendMessageA("1.Samo SendMessageA("2.TV i SendMessageA("3.Samo SendMessageA("4.TV s SendMessageA("5.Puni TV program",0,384,hListBox1); ` 384 LB_ADDSTRING Internet",0,384,hListBox1); ` 384 LB_ADDSTRING Internet",0,384,hListBox1); ` 384 LB_ADDSTRING kodiranimkanalima",0,384,hListBox1); ` 384 LB_ADDSTRING paket",0,384,hListBox1); ` 384 LB_ADDSTRING Da bi se saznalo koja je opcija listbox-a odabrana, pošalje se poruka LB_GETCURSEL (392) listboxu uz lparam i wparam parametre jednake 0. nItem := SendMessageA(0,0,392,hListBox1); ` LB_GETCURSEL ako nItem=2 { MessageBoxA(0,"TV","Ne koristi TV",hwnd); } 15.11. Kombinovane liste (combo box) Kombinovanjem listboxa i editnog polja dobija se combo box. On je prozor klase COMBOBOX, i kreira se i puni slično LISTBOXu, s tim što je stil prozora kombinacija ws_child, ws_visible, ws_border, cbs_dropdown i cbs_hasstrings a kod poruke za punjenje 323 (cb_addstring). Nazivi ulica su stavljeni u combobox koji je tipa dropdown, što znači da je moguće dokucavati uneseni tekst. Druga dva tipa su simple koji je fiksnog izgleda i dropdownlist koji je promjenjive veličine, ali je tekst moguće samo izabrati, ne i dokucavati. hCombo1:=CreateWindowExA(0,hInstance,0,hwnd,100,145,144,272, 1350566402, ` ws_child or ws_visible or ws_border or cbs_dropdown or cbs_hasstrings "COmbobox1","COMBOBOX",0); SendMessageA("Maršala Tita",0,323,hCombo1); ` 323 CB_ADDSTRING SendMessageA("Alipašina",0,323,hCombo1); ` 323 CB_ADDSTRING Očitavanje stringa koji je izabran u ComboBoxu se može obaviti očitavanjem naslova prozora. MessageBoxA(0,"Adresa",rezultat,hwnd); GetWindowTextA(200,rezultat,hMemo1); 15.12. Statički tekst Pored odgovora na WM_PAINT poruku, statički tekst se takođe može realizovati u formi podprozora klase static. O iscrtavanju ovakvih tekstova na formama brine kasnije sam Windows. hStatic1:=CreateWindowExA(0,hInstance,0,hwnd,14,57,16,8, 1342177291, `ws_child or ws_visible or ss_simple "Prezime","STATIC",0); hStatic2:=CreateWindowExA(0,hInstance,0,hwnd,14,37,50,8, 1342177291, `ws_child or ws_visible or ss_simple "Ime","STATIC",0); hStatic3:=CreateWindowExA(0,hInstance,0,hwnd,14,72,200,16, 1342177291, `ws_child or ws_visible or ss_simple "Napomena","STATIC",0); hStatic4:=CreateWindowExA(0,hInstance,0,hwnd,14,103,8,272, 1342177291, `ws_child or ws_visible or ss_simple 117 "Vrsta usluge","STATIC",0); hStatic5:=CreateWindowExA(0,hInstance,0,hwnd,14,78,128,280, 1342177291, `ws_child or ws_visible or ss_simple "Adresa","STATIC",0); hStatic6:=CreateWindowExA(0,hInstance,0,hwnd,13,190,176,280, 1342177291, `ws_child or ws_visible or ss_simple "Stepen realizacije","STATIC",0); 15.13. Klizna traka (scrollbar) Iako se daleko češće koristi za pregled velikih slika ili skupova korisničkih kontrola koje ne mogu stati na ekran, horizontalna klizna traka se može koristiti i za unos podataka čija vrijednost nije egzaktna nego približna. Pomicanje klizne trake izaziva poruku WM_HSCROLL (broj 276). U programu je ova poruka obrađena u funkciji OnWMHScroll cijeli funkcija OnWMHScroll(cijeli wParam,cijeli lParam) { cijeli nPos; ako (lParam=hScroll1)& (wParam & 65535 =5) `SB_THUMBTRACK { nPos:=wParam / 65536; SetScrollPos(1,nPos,2,hScroll1); } } Postoji više načina pomicanja klizne trake, povlačenjem kvadratića na njoj, klikom na strelice ili klikom u prazna polja. Ovdje je obrađeno samo povlačenje kvadratića (u nižoj riječi wParama vrijednost 5, poruka SB_THUMBTRACK). Prilikom povlačenja kvadratića na kliznoj traci(ali samo u tom slučaju), viša riječ parametra wparam će sadržati novu poziciju. Ta pozicija neće biti zadržana ako se ne pozove funkcija SetScrollPos, čiji prvi parametar znači da li će se klizna traka ponovo iscrtati, drugi parametar definiše njenu novu poziciju. Treći parametar govori da li je riječ o horizontalnoj kliznoj traci, vertikalnoj kliznoj traci samog prozora ili odvojenoj kontroli (vrijednost 2). Četvrti parametar je handle na kliznu traku. Trenutna pozicija klizne trake se dobija funkcijom GetScrollPos, čiji prvi parametar predstavlja vrstu klizne trake (u našem slučaju 2, odvojena kontrola), a drugi je hendl na kliznu traku. U ovom dijelu koda se provjerava da li klizna traka ima vrijednost preko 50. ako (GetScrollPos(2,hScroll1)>50) { MessageBoxA(0,"Realizovanost","Preko 50",0); } 15.14. Iscrtane slike i WM_PAINT poruka Za iscrtavanje grafike postoji jedan poseban podsistem koji se zove GDI, graphic device interface. On omogućava širok izbor grafičkih elemenata kao što su linije, krugovi, elipse, ispunjeni likovi, bitmape, tekstualne poruke, i slično Većina ovih funkcija koristi jedan specijalni identifikator dijela prozora po kome se crta, koji se zove hdc (handle to device context - kontekst uređaja). On se dobija pozivom odgovarajućih funkcija iz hendla na prozor, hwnd. Razlog zbog čega API funkcije za crtanje razdvajaju prozor od njegovog konteksta uređaja je u činjenici da prozor ima okvir i korisnu površinu i da crtanje po korisnoj površini ne mijenja sadržaj okvira i obrnuto. Nije, međutim dobro iscrtavati sliku bilo kada. Iscrtavanje drugih prozora u sistemu lako prekriva iscrtanu sliku, pa se ono što je iscrtano izgubi. Stoga je iscrtavanje potrebno obaviti svaki put kada je primljena poruka WM_PAINT (poruka broj 15). Ovu poruku šalje sistem kada je prozor doživio takvu promjenu da ga je potrebno ponovo crtati (recimo, otkriven nakon što je bio prekriven ili su mu promijenjene dimenzije. Unutar funkcije OnWMPaint iscrtava se predviđeni lik. Funkcijom BeginPaint, koja ima dva parametra: struktura za crtanje i handle na prozor, daje se informacija Windowsu da se počinje sa iscrtavanjem. Struktura za crtanje je slog koji sadrži informacije o pravougaoniku koji se iscrtava. Rezultat funkcije BeginPaint je handle na kontekst uređaja (device context). Crtanje se završava funkcijom EndPaint koja ima iste argumente. cijeli funkcija OnWMPaint(cijeli hwnd) { hdc:=BeginPaint(&pstruct,hwnd); MoveToEx(0,250,400,hdc); LineTo(250,480,hdc); LineTo(310,480,hdc); LineTo(310,400,hdc); LineTo(250,400,hdc); TextOutA(5,"CBLTV",253,403,hdc); Ellipse(294,470,264,410, hdc); EndPaint(&pstruct,hwnd); } Između funkcija BeginPaint i EndPaint mogu se vidjeti funkcije za crtanje. Prvi parametar funkcije MoveToEx, koja služi za postavljanje početne tačke je pointer na slog koji bi vratio prethodne koordinate ili vrijednost 0 ukoliko prethodne koordinate nije potrebno očitavati. Drugi parametar predstavlja y koordinatu tačke, treći parametar predstavlja x koordinatu, a 118 četvrti hendl na kontekst uređaja. Tačka postavljena funkcijom MoveToEx je početna tačka za iscrtavanje linija. Linije se dalje iscrtava do tačke čije su y i x koordinate navedene kao prvi i drugi parametar funkcije LineTo. Krajnja tačka tako iscrtane linije postaje početna tačka za novu liniju. Ispis teksta se obavlja funkcijom TextOutA. Prvi argument ove funkcije je broj bajtova koliko je velik string koji se ispisuje, drugi je sam string, treći i četvrti su same koordinate stringa a posljednji je handle na kontekst uređaja. Moguće je iscrtavati i elipse. Funkcija Ellipse za argumente ima redom: y koordinatu donjeg desnog ugla kvadrata koji je opisuje, x koordinatu donjeg desnog ugla kvadrata koji je opisuje, y koordinatu gornjeg lijevog ugla kvadrata koji je opisuje, x koordinatu donjeg lijevog ugla kvadrata koji je opisuje i handle na kontekst uređaja. 15.15. Rezime poglavlja Pod windowsom kontrole su takođe prozori. Svaka kontrola se kreira funkcijom CreateWindowExA i ima nekoliko predefinisanih klasa. Sve kontrole osim radio tastera trebaju da za roditelja imaju glavni prozor. Radio tasteri se smještaju u grupe. Podaci koje kontrole šalju se očitavaju na različite načine. Dodatno iscrtani grafički elementi se trebaju crtati kao odgovor na poruku WM_PAINT. Sve funkcije za crtanje dio su podsistema koji se zove GDI i kao argument imaju handle na kontekst uređaja koji se prosljeđuje kao zadnji argument funkcija za crtanje. -. 119 16. SPISAK WIN32API FUNKCIJA U prethodnim poglavljima upoznato je sa osnovama Windows API-ja. Sada slijedi spisak svih API funkcija koje savremene verzije Windowsa pružaju. 16.1. Najvažniji podsistemi Windows API-ja Windows API je kompilacija različitih skupova funkcija namijenjenih programerima. Najvažniji njegovi dijelovi su: - Windows Kernel - Korisnički interfejs - Grafički podsistem GDI - Funkcije za slanje poruka MAPI - Funkcije za rad sa interfejsom za telefon TAPI - COM, objektni model za kooperaciju odvojenih aplikacija - OLE/Active X, nadgradnja COMa za pravljenje aplikacija čije su komponente druge aplikacije - ODBC, funkcije za pristup bazama podataka - Kontrole unaprijeđenog korisničkog interfejsa - DirectX, nadgradnja COMa za direktni pristup grafičkom hardveru i zvuku - RASAPI za pristup preko modema - Winsock za pravljenje Internet aplikacija -MCI, za pristup multimedijalnim uređajima. -OPENGL za trodimenzionalnu grafiku - Standardni dijalozi Api funkcija ima mnogo i jedini način da se one nauče je analizom gotovih programa. Stoga većina Windows API aplikacija ima standardan izgled. Tako na primjer, ODBC aplikacije izgledaju kao na slici Sl. 16.1.1: Sl. 16.1.1. Osnovna ODBC aplikacija 120 16.2. DLL datoteke u kojima se nalaze funkcije Standardnim API funkcijama windowsa smatraju se one koje se nalaze u sljedećim DLL datotekama: ACLUI.DLL Korisnički interfejs za kontrolu prava pristupaACTIVEDS.DLL Active Directory Services ADVAPI32.DLL Razni sistemski pozivi uključujući sigurnost i registry bdnapi.DLL Web TV biblioteka bignums.dll Račun sa velikim brojevima CAP.DLL Dijagnostika COMCTL32.DLL Savremene kontrole korisničkog interfejsa COMDLG32.DLL Standardni dijalozi CRTDLL.DLL Standardna C biblioteka, printf, sin itd CRYPT32.DLL Kriptografske funkcije ctl3d32.dll Trodimenzionalni izgled kontrola d3dim.DLL Proširenje arhitekture Direct3D D3DRM.DLL Direct3D vektorske funkcije d3dxof.DLL Direct3D aplikacijska biblioteka dapi.DLL Za pristup direktoriju MS Exchangea ddraw.dll Direct Draw, glavna datoteka dflayout.dll Definisanje rasporeda podataka u složeniim dokumentima DINPUT.DLL DirectInput (za DirectX pristup joysticku, tastaturi, mišu) dlcapi.dll Pristupanje DLC protokolu za HP mrežne štampače DPLAY.DLL DirectPlay, za igranje preko mreže DPLAYX.DLL DirectPlay, proširenje DSETUP.DLL Za instalaciju DirectX DSOUND.DLL DirectSound, zvuk u DirectX dynloader.dll Analiza OBJ datoteka edbbcli.DLL Alatke za MS Exchange server gc.dll Garbage collector GDI32.DLL Grafičke biblioteke za prikaz linija i bitmapa glide2x.dll 3D biblioteka za 3DFX 3D grafičke akceleratore glu32.dll Pomoćne funkcije koje OpenGL aplikacije koriste za prikaz 3D grafike GLUT32.DLL Varijanta OpenGL sa izmjenjenim imenima funkcija HLINK.DLL Rad sa hiperlinkovima ICMP.DLL Za komandu PING ICMUI.DLL Korisnički interfejs za Microsoft Color Matching System imagehlp.dll Za analiziranje EXE datoteka IMM32.DLL Unošenje azijskih UNICODE znakova iphlpapi.DLL Informacije o mrežnoj konfiguraciji i statistici IPROP.DLL Implementacija OlePropertySet KERNEL32.DLL Upravljanje memorijom i I/O operacijama loadperf.dll Upravljanje perfomance monitorom LSAPI32.DLL Informacije o licenciranju lz32.dll Kompresija podataka mapi32.dll Slanje i obrada EMAIL poruka mgmtapi.DLL Biblioteka za upravljanje resursima preko SNMP MPR.DLL Punjenje Network Neighboorhooda spiskom mašina MPRAPI.DLL Pristup funkcijama za rutiranje MSACM32.DLL Upravljanje audio kompresijom mscms.DLL Color Matching biblioteka (prilikom štampe) MSI.DLL Windows Installer MSLSP32.DLL Informacije o licenciranju MSVCRT.DLL Microsoft C runtime biblioteka MSVCRTD.DLL Microsoft C runtime biblioteka, debug verzija 16.3. MSVFW32.DLL Video for Windows MSWSOCK.DLL Microsoftove nestandardne Winsock funkcije NAL.DLL Sloj abstrakcije mreže netapi32.dll Za pristup Microsoftovim mrežama NTDLL.DLL Za pristup internim funkcijama Windowsa NT NTMSAPI.DLL Removable Storage API (proširenje diskova trakama) ODBC32.DLL Pristup bazama podataka ODBCCP32.dll Podešavanje ODBC ole32.dll Osnovne OLE funkcije OLEAUT32.DLL Ole automatizacija oledlg.DLL OLE dijalozi (Insert Object) OLEPRO32.DLL Microsoftove vlastite OLE funkcije opengl.dll Silicon Graphics OpenGL biblioteka opengl32.dll Microsoft OpenGL Biblioteka pdh.dll Performance Data Helper penwin32.dll Za Windows koji se upravlja olovkom pkdp32.dll Za Windows koji se upravlja olovkom PSAPI.DLL Spisak procesa koji se izvršavaju RASAPI32.DLL RAS Pristup sistemu preko modema rasdlg.dll Dijalozi koji se koriste u RAS rassapi.dll RAS administracijske funkcije RESUTILS.DLL Pristup Windows resursima RICHED20.DLL RichEdit kontrola rpcns4.dll Name Service u pozivu udaljene procedure (RPC) RPCRT4.DLL API za poziv udaljene procedure RTM.DLL Upravljač tabelom rutiranja Secur32.DLL Windows sigurnosne funkcije SETUPAPI.DLL Instalacija Windowsa SHELL32.DLL Veza između aplikacije i FileManagera, Explorera SHFOLDER.DLL Pristup specijalnim folderima (My Documents) SHLWAPI.DLL Pomoćne funkcije za pristup stazama, urlovima, registriju i bojama snmpapi.dll Pristup SNMP funkcijama za praćenje mreže i servera svrapi.dll Kontrola dijeljenih (share) resursa na Microsoft mreži tapi32.dll Telefonski API TOOLHELP.DLL Funkcije za debagiranje i praćenje sistema URL.DLL Pokretanje Web browsera preko URL adrese URLMON.DLL Proširenje OLE32 USER32.DLL Najbitnije funkcije za rad sa prozorima i kontrolama USERENV.DLL Pristup korisničkim profajlovima version.dll Informacije o broju verzije izvršnog programa webpost.dll Slanje Web stranica na internet win32spl.dll Pristup printer spooleru WINFAX.DLL Rad sa telefaxom WININET.DLL Microsoft Internet funkcije winmm.dll Windows multimedia API wintrust.dll Autentifikacija tajnim i javnim ključem WOW32.dll Podrška 16 bitnim aplikacijama WS2_32.DLL Winsock 2.0 wsock32.dll Winsock API wst.dll Working Set Tuner (optimalan broj stranica u RAMu) Spisak API funkcija Sada su navedene sve dokumentovane funkcije koje se nalaze u pojedinim bibliotekama, a koje je moguće pozvati iz FILDZAN-32 ili drugih programskih jezika. Puna sintaksa svake od njih, namjena i način korištenja mogu se naći na Internetu ili na CD-ovima Microsoft Developers Network. Ovdje su navedeni ime funkcije, biblioteka, oznaka NM/AW, broj parametara i kratki opis funkcije. Ako je navedena oznaka AW, tada se pri deklaraciji i pozivu funkcije njenom imenu dodaje slovo A za Ascii stringove ili W za Unicode stringove (npr CreateWindowEx se u Fildzan32 piše CreateWindowExA). Pri oznaci NM ovog sufiksa nema. 121 AbortDoc,GDI32.DLL,NM,1, stops the current print job and erases everything drawn since the AddPrintProcessor,WINMM.DLL,AW,5 installs a print processor on thespecified server and adds the print-processor name to an internallist of supported print processors. last call to the StartDoc function. AddPrintProvidor,WINMM.DLL,AW,3, installs a local printer provider and links the configuration, AbortPath,GDI32.DLL,NM,1, closes and discards any paths in the specified device context. data, and provider files. AbortPrinter,WINMM.DLL,NM,1, deletes a printer?s spool file if the printer is configured for AdjustTokenGroups,ADVAPI32.DLL,NM,6, adjusts groups in the specified access token. spooling. AdjustTokenPrivileges,ADVAPI32.DLL,NM,6 enables or disables privileges in the specified AbortSystemShutdown,ADVAPI32.DLL,AW,1, stops a system shutdown started by using the access token. InitiateSystemShutdown function. accept,WS2_32.DLL,NM,3, extracts the first connection on the queue of pending connections AdjustWindowRect,USER32.DLL,NM,3 calculates the required size of the window rectangle, based on the desired client-rectangle size. on socket s. accept,WSOCK32.DLL,NM,3, extracts the first connection on the queue of pending connections AdjustWindowRectEx,USER32.DLL,NM,4 calculates the required size of thewindow rectangle, based on the desired size of the clientrectangle. on socket s. ADsBuildEnumerator,ACTIVEDS.DLL,NM,2 Builds an enumerator object for the specified AcceptEx,MSWSOCK.DLL,NM,8, combines several socket functions into a single API/kernel Active Directory container object. transition. ADsBuildVarArrayInt,ACTIVEDS.DLL,NM,3 Builds a VARIANT array from an array of AcceptEx,WSOCK32.DLL,NM,8, combines several socket functions into a single API/kernel DWORDS. transition. ADsBuildVarArrayStr,ACTIVEDS.DLL,NM,3 Builds a VARIANT array from an array of Unicode AcceptSecurityContext,SECUR32.DLL,NM,9,This function enables the server part of a strings. transport application to establish a security context between the server and a remote client. AccessCheck,ADVAPI32.DLL,NM,8 is used by a server application to check aclient?s access to ADsEnumerateNext,ACTIVEDS.DLL,NM,4 Populates a VARIANT arrray with elements fetched from the indicated enumerator object. an object against the access control associatedwith the object. ADsFreeEnumerator,ACTIVEDS.DLL,NM,1 Frees an enumerator object previously created AccessCheckAndAuditAlarm,ADVAPI32.DLL,AW,11, performs an access validation and through ADsBuildEnumerator generates corresponding audit messages. ADsGetLastError,ACTIVEDS.DLL,NM,5 Retrieves the calling thread?s last-error code value. AccessNtmsLibraryDoor,NTMSAPI.DLL,NM,3, unlocks the door of the specified library. If the ADsGetObject,ACTIVEDS.DLL,NM,3 In Active Directory, bind to an object given its path and library is busy, RSM queues the request and returns successfully. primaryinterface identifier (IID). acmDriverAdd,MSACM32.DLL,AW,5, adds a driver to the list of available ACM drivers. ADsOpenObject,ACTIVEDS.DLL,NM,6 In Active Directory, bind to an object using username acmDriverClose,MSACM32.DLL,NM,2, closes a previously opened ACM driver instance. and passwordcredentials. acmDriverDetails,MSACM32.DLL,AW,3, queries a specified ACM driver to determine its ADsSetLastError,ACTIVEDS.DLL,NM,3 Sets the calling thread?s last-error code value. capabilities. acmDriverEnum,MSACM32.DLL,NM,3 enumerates the available ACM drivers,continuing until AdvancedDocumentProperties,WINMM.DLL,AW,5 displays a printerconfiguration dialog box for the specified printer, allowing theuser to configure that printer. there are no more drivers or the callback functionreturns FALSE. AllocateAndInitializeSid,ADVAPI32.DLL,NM,11, allocates and initializes a security identifier acmDriverID,MSACM32.DLL,NM,3 returns the handle of an ACM driveridentifier associated (SID) with up to eight subauthorities. with an open ACM driver instance or streamhandle. acmDriverMessage,MSACM32.DLL,NM,4 sends a user-defined message to a given ACM driver AllocateLocallyUniqueId,ADVAPI32.DLL,NM,1, allocates a locally unique identifier (LUID). AllocateNtmsMedia,NTMSAPI.DLL,NM,6, allocates a piece of available media. instance. AllocConsole,KERNEL32.DLL,NM,0, allocates a new console for the calling process. acmDriverOpen,MSACM32.DLL,NM,3 opens the specified ACM driver andreturns a driver AngleArc,GDI32.DLL,NM,6, moves the current position to the ending point of the arc. instance handle that can be used to communicatewith the driver. AnimatePalette,GDI32.DLL,NM,4 replaces entries in the specified logical palette. acmDriverPriority,MSACM32.DLL,NM,3, modifies the priority and state of an ACM driver. AnimateWindow,USER32.DLL,NM,3, enables you to produce special effects when showing or acmDriverRemove,MSACM32.DLL,NM,2, removes an ACM driver from the list of available hiding windows. ACM drivers. AnyPopup,USER32.DLL,NM,0, indicates whether an owned, visible, top- level pop-up, or acmFilterChoose,MSACM32.DLL,AW,1, creates an ACM-defined dialog box that enables the overlapped window exists on the screen. user to select a waveform-audio filter. acmFilterDetails,MSACM32.DLL,AW,3 queries the ACM for details about a filter with a specific AppendMenu,USER32.DLL,AW,4, appends a new item to the end of the specified menu bar, drop-down menu, submenu, or shortcut menu. waveform-audio filter tag. acmFilterEnum,MSACM32.DLL,AW,5, enumerates waveform-audio filters available for a given ApplyControlToken,SECUR32.DLL,NM,2,Provides a way to apply a control token to a security context. filter tag from an ACM driver. Arc,GDI32.DLL,NM,9, draws an elliptical arc. acmFilterTagDetails,MSACM32.DLL,AW,3, queries the ACM for details about a specific ArcTo,GDI32.DLL,NM,9, draws an elliptical arc. waveform-audio filter tag. acmFilterTagEnum,MSACM32.DLL,AW,5, will return MMSYSERR_NOERROR (zero) if no filter AreAllAccessesGranted,ADVAPI32.DLL,NM,2, checks whether a set of requested access rights has been granted. tags are to be enumerated. AreAnyAccessesGranted,ADVAPI32.DLL,NM,2, tests whether any of a set of requested access acmFormatChoose,MSACM32.DLL,AW,1 function creates an ACM-defined dialog box that rights has been granted. enables the user to select a waveform-audio format. AreFileApisANSI,KERNEL32.DLL,NM,0, determines whether a set of Win32 file functions is acmFormatDetails,MSACM32.DLL,AW,3, queries the ACM for format details for a specific using the ANSI or OEM character set code page. waveform-audio format tag. ArrangeIconicWindows,USER32.DLL,NM,1, arranges all the minimized (iconic) child windows acmFormatEnum,MSACM32.DLL,AW,5, enumerates waveform-audio formats available for a of the specified parent window. given format tag from an ACM driver. AssociateColorProfileWithDevice,MSCMS.DLL,AW,3, associates a specified color profile with a acmFormatSuggest,MSACM32.DLL,NM,5 queries the ACM or a specified ACMdriver to specified device. suggest a destination format for the supplied sourceformat. AttachThreadInput,USER32.DLL,NM,3, fails if either of the specified threads does not have a acmFormatTagDetails,MSACM32.DLL,AW,3, queries the ACM for details on a specific message queue. waveform-audio format tag. acmFormatTagEnum,MSACM32.DLL,AW,5, enumerates waveform-audio format tags available auxGetDevCaps,WINMM.DLL,AW,3, retrieves the capabilities of a given auxiliary output device. from an ACM driver. auxGetNumDevs,WINMM.DLL,NM,0, retrieves the number of auxiliary output devices present acmGetVersion,MSACM32.DLL,NM,0, returns the version number of the ACM. acmMetrics,MSACM32.DLL,NM,3, returns various metrics for the ACM or related ACM objects. in the system. auxGetVolume,WINMM.DLL,NM,2, retrieves the current volume setting of the specified acmStreamClose,MSACM32.DLL,NM,2 closes an ACM conversion stream. If the function is auxiliary output device. successful, the handle is invalidated. auxOutMessage,WINMM.DLL,NM,4, sends a message to the given auxiliary output device. acmStreamConvert,MSACM32.DLL,NM,3, requests the ACM to perform a conversion on the auxSetVolume,WINMM.DLL,NM,2, sets the volume of the specified auxiliary output device. specified conversion stream. acmStreamMessage,MSACM32.DLL,NM,4, sends a driver-specific message to an ACM driver. BackupEventLog,ADVAPI32.DLL,AW,2, saves the specified event log to a backup file. BackupFree,EDBBCLI.DLL,NM,1, frees a backup memory buffer. acmStreamOpen,MSACM32.DLL,NM,8, opens an ACM conversion stream. BackupRead,KERNEL32.DLL,NM,7, reads data associated with a specified file or directory into acmStreamPrepareHeader,MSACM32.DLL,NM,3, prepares an ACMSTREAMHEADER a buffer. structure for an ACM stream conversion. acmStreamReset,MSACM32.DLL,NM,2 stops conversions for a given ACM stream. All pending BackupSeek,KERNEL32.DLL,NM,6, seeks forward in a data stream initially accessed by using the BackupRead or BackupWrite function. buffers are marked as done and returned to the application. acmStreamSize,MSACM32.DLL,NM,4, returns a recommended size for a source or destination BackupWrite,KERNEL32.DLL,NM,7, writes a stream of data from a buffer to a specified file or directory. buffer on an ACM stream. BatchExport,DAPI.DLL,AW,1, exports objects from the Microsoft Exchange Server directory. acmStreamUnprepareHeader,MSACM32.DLL,NM,3 cleans up the preparation performed by the acmStreamPrepareHeader </native/sdk/win32/vfw/src/mmfu5dwy.htm> function for an ACM BatchImport,DAPI.DLL,AW,1, imports directory service objects from a text file in a single function call. stream. AcquireCredentialsHandle,SECUR32.DLL,AW,9,Acquires a handle to preexisting credentials of Beep,KERNEL32.DLL,NM,2, generates simple tones on the speaker. BeginDeferWindowPos,USER32.DLL,NM,1 allocates memory for a multiple-window - position a security principal. AcsLan,DLCAPI.DLL,NM,2 communicates with IBM mainframes or networkperipheral devices, structure and returns the handle to thestructure. such as printers connected directly to thenetwork, by using the data link control (DLC) protocol. BeginPaint,USER32.DLL,NM,2 prepares the specified window for paintingand fills a ActivateKeyboardLayout,USER32.DLL,NM,2 The ActivateKeyboardLayout function activates a PAINTSTRUCT structure with information about thepainting. different keyboard layout and sets the active keyboard layout for the entire system rather than BeginPath,GDI32.DLL,NM,1, opens a path bracket in the specified device context. BeginUpdateResource,KERNEL32.DLL,AW,2 returns a handle that can be usedby the the calling thread. UpdateResource function to add, delete, or replace resourcesin an executable file. AddAccessAllowedAce,ADVAPI32.DLL,NM,4, adds an access-allowed ACE to an ACL. bind,WS2_32.DLL,NM,3, is used on an unconnected socket before subsequent calls to the AddAccessDeniedAce,ADVAPI32.DLL,NM,4, adds an access-denied ACE to an ACL. connect or listen functions. AddAce,ADVAPI32.DLL,NM,5, adds one or more ACEs to a specified ACL. AddAtom,KERNEL32.DLL,AW,1, adds a character string to the local atom table and returns a bind,WSOCK32.DLL,NM,3, is used on an unconnected socket before subsequent calls to the connect or listen functions. unique value (an atom) identifying the string. BindImage,IMAGEHLP.DLL,NM,3, computes the virtual address of each imported function. AddAuditAccessAce,ADVAPI32.DLL,NM,6, adds a system-audit ACE to a system ACL. BindImageEx,IMAGEHLP.DLL,NM,5, computes the virtual address of each function that is AddFontResource,GDI32.DLL,AW,1, adds the font resource from the specified file to the imported. Windows font table. AddForm,WINMM.DLL,AW,3, adds a form to the list of available forms that can be selected for BindMoniker,OLE32.DLL,NM,4,This function locates an object by means of its moniker, activates the object if it is inactive, and retrieves a pointer to the specified interface on that the specified printer. AddJob,WINMM.DLL,AW,5 obtains a path string that specifies a file that you can use to store a object. BitBlt,GDI32.DLL,NM,9 performs a bit-block transfer of the color datacorresponding to a spooled print job. AddMonitor,WINMM.DLL,AW,3 installs a local printer monitor and links the configuration, data, rectangle of pixels from the specified sourcedevice context into a destination device context. BringWindowToTop,USER32.DLL,NM,1, brings the specified window to the top of the Z order. and monitor files. AddNtmsMediaType,NTMSAPI.DLL,NM,3, adds the specified media type to the specified library BroadcastSystemMessage,USER32.DLL,AW,5, sends a message to the specified recipients. BstrFromVector,OLEAUT32.DLL,NM,2,Returns a BSTR, assigning each element of the vector if there is not currently a relation in the library object. The function then creates the system to a character in the BSTR. media pools if they do not exist. BuildCommDCB,KERNEL32.DLL,AW,2, fills a specified DCB structure with values specified in AddPort,WINMM.DLL,AW,3, adds the name of a port to the list of supported ports. a device-control string. AddPrinter,WINMM.DLL,AW,3 adds a printer to the list of supported printers for a specified BuildCommDCBAndTimeouts,KERNEL32.DLL,AW,3 translates a device-definitionstring into server. appropriate device-control block codes and then placesthese codes into a device control block. AddPrinterConnection,WINMM.DLL,AW,1, adds a connection to the specified printer for the BuildDisplayTable,MAPI32.DLL,NM,10, creates a display table from the property page data current user. contained in one or more DTPAGE structures. AddPrinterDriver,WINMM.DLL,AW,3, installs a local or remote printer driver and links the configuration, data, and driver files. 122 BuildExplicitAccessWithName,ADVAPI32.DLL,AW,5, initializes an EXPLICIT_ACCESS structure with data specified by the caller. BuildImpersonateExplicitAccessWithName,ADVAPI32.DLL,AW,6, is provided for future use. BuildImpersonateTrustee,ADVAPI32.DLL,AW,2, is provided for future use. BuildSecurityDescriptor,ADVAPI32.DLL,AW,9, allocates and initializes a new security descriptor. BuildTrusteeWithName,ADVAPI32.DLL,AW,2, initializes a TRUSTEE structure. BuildTrusteeWithSid,ADVAPI32.DLL,AW,2, initializes a TRUSTEE structure. CallMsgFilter,USER32.DLL,AW,2 passes the specified message and hookcode to the hook procedures associated with the WH_SYSMSGFILTER andWH_MSGFILTER hooks. CallNamedPipe,KERNEL32.DLL,AW,7 connects to a message-type pipe (and waits if an instance of the pipe is not available), writes to and reads from the pipe, and then closes the pipe. CallNextHookEx,USER32.DLL,NM,4, passes the hook information to the next hook procedure in the current hook chain. CallWindowProc,USER32.DLL,AW,5, passes message information to the specified window procedure. CancelDC,GDI32.DLL,NM,1, cancels any pending operation on the specified device context (DC). CancelIo,KERNEL32.DLL,NM,1 cancels all pending input and output (I/O)operations that were issued by the calling thread for the specifiedfile handle. CancelNtmsLibraryRequest,NTMSAPI.DLL,NM,2, cancels outstanding RSM requests, such as calls to the CleanNtmsDrive function. If the library is busy, RSM queues the cancellation and returns success. CancelNtmsOperatorRequest,NTMSAPI.DLL,NM,2, cancels the specified RSM operator request. CancelWaitableTimer,KERNEL32.DLL,NM,1, sets the specified ?waitable? timer to the inactive state. CascadeWindows,USER32.DLL,NM,5, cascades the specified windows or the child windows of the specified parent window. CertAddCertificateContextToStore,CRYPT32.DLL,NM,4, adds a certificate context to the certificate store. CertAddCRLContextToStore,CRYPT32.DLL,NM,4, adds a certificate revocation list (CRL) context to the certificate store. CertAddCTLContextToStore,CRYPT32.DLL,NM,4, adds a certificate trust list (CTL) context to a certificate store. CertAddEncodedCertificateToStore,CRYPT32.DLL,NM,6, creates a certificate context from an encoded certificate and adds it to the certificate store. CertAddEncodedCRLToStore,CRYPT32.DLL,NM,6, creates a certificate revocation list (CRL) context from an encoded CRL and adds it to the certificate store. The function makes a copy of the CRL context before adding it to the store. CertAddEncodedCTLToStore,CRYPT32.DLL,NM,6, creates a certificate trust list (CTL) context from an encoded CTL and adds it to the certificate store. The function makes a copy of the CTL context before adding it to the store. CertAddEnhancedKeyUsageIdentifier,CRYPT32.DLL,NM,2, adds a usage identifier object identifier (OID) to the enhanced key usage (EKU) extended property of the certificate. CertAddSerializedElementToStore,CRYPT32.DLL,NM,8,Adds a serialized certificate, certificate revocation list (CRL), or certificate trust list (CTL) element to the store. CertAlgIdToOID,CRYPT32.DLL,NM,1,Converts a CryptoAPI algorithm identifier (ALG_ID) to an Abstract Syntax Notation One (ASN.1) object identifier (OID) string. CertCloseStore,CRYPT32.DLL,NM,2, closes a certificate store handle and reduces the reference count on the store. There needs to be a corresponding call to CertCloseStore for each successful call to the CertOpenStore or CertDuplicateStore functions. CertCompareCertificate,CRYPT32.DLL,NM,3, compares two certificates to determine whether they are identical. CertCompareCertificateName,CRYPT32.DLL,NM,3, compares two certificate CERT_NAME_BLOB structures to determine whether they are identical. The CERT_NAME_BLOB structures are used for the subject and the issuer of certificates. CertCompareIntegerBlob,CRYPT32.DLL,NM,2, compares two integer BLOBs to determine whether they represent equal numeric values. CertComparePublicKeyInfo,CRYPT32.DLL,NM,3, compares two encoded public keys to determine whether they are identical. CertCreateCertificateContext,CRYPT32.DLL,NM,3, creates a certificate context from an encoded certificate. The created context is not persisted to a certificate store. The function makes a copy of the encoded certificate within the created context. CertCreateCRLContext,CRYPT32.DLL,NM,3, creates a certificate revocation list (CRL) context from an encoded CRL. The created context is not persisted to a certificate store. It makes a copy of the encoded CRL within the created context. CertCreateCTLContext,CRYPT32.DLL,NM,3, creates a certificate trust list (CTL) context from an encoded CTL. The created context is not persisted to a certificate store. The function makes a copy of the encoded CTL within the created context. CertDeleteCertificateFromStore,CRYPT32.DLL,NM,1, deletes the specified certificate context from the certificate store. CertDeleteCRLFromStore,CRYPT32.DLL,NM,1, deletes the specified certificate revocation list (CRL) context from the certificate store. CertDeleteCTLFromStore,CRYPT32.DLL,NM,1, deletes the specified certificate trust list (CTL) context from a certificate store. CertDuplicateCertificateContext,CRYPT32.DLL,NM,1,Duplicates a certificate context by incrementing its reference count. CertDuplicateCRLContext,CRYPT32.DLL,NM,1, duplicates a certificate revocation list (CRL) context by incrementing its reference count. CertDuplicateCTLContext,CRYPT32.DLL,NM,1, duplicates a certificate trust list (CTL) context by incrementing its reference count. CertDuplicateStore,CRYPT32.DLL,NM,1,Duplicates a store handle by incrementing the store's reference count. CertEnumCertificateContextProperties,CRYPT32.DLL,NM,2, retrieves the first or next extended property associated with a certificate context. CertEnumCertificatesInStore,CRYPT32.DLL,NM,2,Retrieves the first or next certificate in a certificate store. Used in a loop, this function can retrieve in sequence all certificates in a certificate store. CertEnumCRLContextProperties,CRYPT32.DLL,NM,2, retrieves the first or next extended property associated with a certificate revocation list (CRL) context. CertEnumCTLContextProperties,CRYPT32.DLL,NM,2, retrieves the first or next extended property associated with a certificate trust list (CTL) context. Used in a loop, this function can retrieve in sequence all extended properties associated with a CTL context. CertEnumCTLsInStore,CRYPT32.DLL,NM,2, retrieves the first or next certificate trust list (CTL) context in a certificate store. Used in a loop, this function can retrieve in sequence all CTL contexts in a certificate store. CertFindAttribute,CRYPT32.DLL,NM,3, finds the first attribute in the CRYPT_ATTRIBUTE array, as identified by its object identifier (OID). CertFindCertificateInStore,CRYPT32.DLL,NM,6,Finds the first or next certificate context in a certificate store that matches a search criteria established by the dwFindType and its associated pvFindPara. CertFindCTLInStore,CRYPT32.DLL,NM,6, finds the first or next certificate trust list (CTL) context that matches search criteria established by the dwFindType and its associated pvFindPara. CertFindExtension,CRYPT32.DLL,NM,3, finds the first extension in the CERT_EXTENSION array, as identified by its object identifier (OID). CertFindRDNAttr,CRYPT32.DLL,NM,2, finds the first RDN attribute identified by its object identifier (OID) in a list of the Relative Distinguished Names (RDN). CertFindSubjectInCTL,CRYPT32.DLL,NM,5, attempts to find the specified subject in a certificate trust list (CTL). CertFreeCertificateContext,CRYPT32.DLL,NM,1,Frees a certificate context by decrementing its reference count. When the reference count goes to zero, CertFreeCertificateContext frees the memory occupied by a certificate context. CertFreeCRLContext,CRYPT32.DLL,NM,1, frees a certificate revocation list (CRL) context by decrementing its reference count. When the reference count goes to zero, CertFreeCRLContext frees the memory occupied by a CRL context. CertFreeCTLContext,CRYPT32.DLL,NM,1, frees a certificate trust list (CTL) context by decrementing its reference count. When the reference count goes to zero, CertFreeCTLContext frees the memory occupied by a CTL context. CertGetCertificateContextProperty,CRYPT32.DLL,NM,4, retrieves the information contained in an extended property of a certificate context. CertGetCRLContextProperty,CRYPT32.DLL,NM,4, gets an extended property for the specified certificate revocation list (CRL) context. CertGetCRLFromStore,CRYPT32.DLL,NM,4,Gets the first or next certificate revocation list (CRL) context from the certificate store for the specified issuer. CertGetCTLContextProperty,CRYPT32.DLL,NM,4, retrieves an extended property of a certificate trust list (CTL) context. CertGetEnhancedKeyUsage,CRYPT32.DLL,NM,4, returns information from the enhanced key usage (EKU) extension or the EKU extended property of a certificate. EKUs indicate valid uses of the certificate. CertGetIntendedKeyUsage,CRYPT32.DLL,NM,4, acquires the intended key usage bytes from a certificate. The intended key usage can be in either the szOID_KEY_USAGE ( CertGetIssuerCertificateFromStore,CRYPT32.DLL,NM,4,Retrieves the certificate context from the certificate store for the first or next issuer of the specified subject certificate. The new Certificate Chain Verification Functions are recommended instead of the use of this function. CertGetSubjectCertificateFromStore,CRYPT32.DLL,NM,3,Returns from a certificate store a subject certificate context uniquely identified by its issuer and serial number. CertIsRDNAttrsInCertificateName,CRYPT32.DLL,NM,4, compares the attributes in the certificate name with the specified CERT_RDN to determine whether all attributes are included there. CertNameToStr,CRYPT32.DLL,AW,5,Converts an encoded name in a CERT_NAME_BLOB structure to a null-terminated character string. CertOIDToAlgId,CRYPT32.DLL,NM,1, converts the Abstract Syntax Notation One (ASN.1) object identifier (OID) string to the CryptoAPI algorithm identifier (ALG_ID). CertOpenStore,CRYPT32.DLL,NM,5,Opens a certificate store using a specified store provider type. CertOpenSystemStore,CRYPT32.DLL,AW,2, is a simplified function used to open the most common system certificate store. To open certificate stores with more complex requirements, such as file-based or memory-based stores, use CertOpenStore. CertRDNValueToStr,CRYPT32.DLL,AW,4, converts a name in a CERT_RDN_VALUE_BLOB to a null-terminated character string. CertRemoveEnhancedKeyUsageIdentifier,CRYPT32.DLL,NM,2, removes a usage identifier object identifier (OID) from the enhanced key usage (EKU) extended property of the certificate. CertSaveStore,CRYPT32.DLL,NM,6,Saves the certificate store to a file or to a memory BLOB. CertSerializeCertificateStoreElement,CRYPT32.DLL,NM,4, serializes a certificate context's encoded certificate and its encoded properties. The result can be persisted to storage so that the certificate and properties can be retrieved at a later time. CertSerializeCRLStoreElement,CRYPT32.DLL,NM,4, serializes an encoded certificate revocation list (CRL) context and the encoded representation of its properties. CertSerializeCTLStoreElement,CRYPT32.DLL,NM,4, serializes an encoded certificate trust list (CTL) context and the encoded representation of its properties. The result can be persisted to storage so that the CTL and properties can be retrieved later. CertSetCertificateContextProperty,CRYPT32.DLL,NM,4, sets an extended property for a specified certificate context. CertSetCRLContextProperty,CRYPT32.DLL,NM,4, sets an extended property for the specified certificate revocation list (CRL) context. CertSetCTLContextProperty,CRYPT32.DLL,NM,4, sets an extended property for the specified certificate trust list (CTL) context. CertSetEnhancedKeyUsage,CRYPT32.DLL,NM,2, sets the enhanced key usage (EKU) property for the certificate. CertStrToName,CRYPT32.DLL,AW,7,Converts a null-terminated X.500 string to an encoded certificate name. CertVerifyCRLRevocation,CRYPT32.DLL,NM,4, check a CRL to determine whether a subject's certificate has or has not been revoked. The new Certificate Chain Verification Functions are recommended instead of the use of this function. CertVerifyCRLTimeValidity,CRYPT32.DLL,NM,2, verifies the time validity of a CRL. CertVerifyCTLUsage,CRYPT32.DLL,NM,7, verifies that a subject is trusted for a specified usage by finding a signed and time-valid CTL with the usage identifiers that contain the subject. CertVerifyRevocation,CRYPT32.DLL,NM,7,Checks the revocation status of the certificates contained in the rgpvContext array. If a certificate in the list is found to be revoked, no further checking is done. CertVerifySubjectCertificateContext,CRYPT32.DLL,NM,3, performs the enabled verification checks on a certificate by checking the validity of the certificate's issuer. The new Certificate Chain Verification Functions are recommended instead this function. CertVerifyTimeValidity,CRYPT32.DLL,NM,2, verifies the time validity of a certificate. CertVerifyValidityNesting,CRYPT32.DLL,NM,2, verifies that a subject certificate's time validity nests correctly within its issuer's time validity. ChangeClipboardChain,USER32.DLL,NM,2, removes a specified window from the chain of clipboard viewers. ChangeDisplaySettings,USER32.DLL,AW,2, changes the display settings to the specified graphics mode. ChangeIdleRoutine,MAPI32.DLL,NM,7, changes some or all of the characteristics of a FNIDLE - based idle routine. ChangeNtmsMediaType,NTMSAPI.DLL,NM,3, moves the specified PMID to the specified target media pool and sets the PMID's media type identifier to the media type of the target media pool. ChangeServiceConfig,ADVAPI32.DLL,AW,11, changes the configuration parameters of a service. CharLower,USER32.DLL,AW,1, converts a character string or a single character to lowercase. CharLowerBuff,USER32.DLL,AW,2, converts uppercase characters in a buffer to lowercase characters. CharNext,USER32.DLL,AW,1 returns a pointer to the next character in a string. CharNextEx,USER32.DLL,AW,3 The CharNextExA function retrieves the pointer to the next character in a string. CharPrev,USER32.DLL,AW,2, returns a pointer to the preceding character in a string. CharPrevEx,USER32.DLL,AW,4 retrieves the pointer to the preceding character in a string. CharToOem,USER32.DLL,AW,2, translates a string into the OEM-defined character set. CharToOemBuff,USER32.DLL,AW,3, translates a specified number of characters in a string into the OEM-defined character set. CharUpper,USER32.DLL,AW,1, converts a character string or a single character to uppercase. CharUpperBuff,USER32.DLL,AW,2, converts lowercase characters in a buffer to uppercase characters. CheckBitmapBits,MSCMS.DLL,NM,9, checks whether the pixels in a specified bitmap lie within the output gamut of a specified transform. CheckColors,MSCMS.DLL,NM,5, determines whether the colors in an array lie within the output gamut of a specified transform. 123 CoGetMarshalSizeMax,OLE32.DLL,NM,6,4.2 CoGetMarshalSizeMax This function returns CheckDlgButton,USER32.DLL,NM,3, changes the check state of a button control. an upper bound on the number of bytes needed to marshal the specified interface pointer to the CheckMenuItem,USER32.DLL,NM,3, sets the state of the specified menu item's check mark CoGetObject,OLE32.DLL,NM,4, Converts a display name into a moniker that identifies the attribute to either checked or unchecked. CheckMenuRadioItem,USER32.DLL,NM,5, checks a specified menu item and makes it a radio object named, and then binds to the object identified by the moniker. CoGetPSClsid,OLE32.DLL,NM,2,This function returns the CLSID of the DLL that implements item. CheckRadioButton,USER32.DLL,NM,4 adds a check mark to (checks) aspecified radio button the proxy and stub for the specified interface. CoGetStandardMarshal,OLE32.DLL,NM,6,4.2 CoGetStandardMarshal This function creates in a group and removes a check mark from(clears) all other radio buttons in the group. CheckSumMappedFile,IMAGEHLP.DLL,NM,5, computes the checksum of the specified image a default, or standard, marshaling object in either the client process or the server process, CoGetState,OLE32.DLL,NM,1, This function is not yet supported. file. CoGetTIDFromIPID,OLE32.DLL,NM,1, This function is not yet supported. ChildWindowFromPoint,USER32.DLL,NM,3, determines which, if any, of the child windows CoGetTreatAsClass,OLE32.DLL,NM,2,4.2 CoGetTreatAsClass This function returns the belonging to a parent window contains the specified point. CLSID of an object that can emulate the specified object. HRESULT CoGetTreatAsClass( ChildWindowFromPointEx,USER32.DLL,NM,4 determines which, if any, of the child windows REFCLSID belonging to the specified parent window contains the specified point. ChooseColor,COMDLG32.DLL,AW,1, creates a Color common dialog box that enables the user CoImpersonateClient,OLE32.DLL,NM,0,Allows the server to impersonate the client of the current call for the duration of the call. to select a color. ChooseFont,COMDLG32.DLL,AW,1, creates a Font common dialog box that enables the user CoInitialize,OLE32.DLL,NM,1 Initializes the COM library on the current thread and identifies the concurrency model as single-thread apartment to choose attributes for a logical font. CoInitializeEx,OLE32.DLL,NM,2,Initializes the COM library for use by the calling thread, sets ChoosePixelFormat,GDI32.DLL,NM,2 compares the generic pixel formats supported by Windows NT and any device pixel formats supported by special hardware accelerators with the the thread's concurrency model, and creates a new apartment for the thread if one is required. CoInitializeSecurity,OLE32.DLL,NM,9,Registers security and sets the default security values for pixel format you described, and returns the best match. Chord,GDI32.DLL,NM,9, draws a chord (a region bounded by the intersection of an ellipse and the process. This function is called exactly once per process, either explicitly or implicitly. It can be called by the client, server, or both. a line segment, called a ?secant?). CoIsHandlerConnected,OLE32.DLL,NM,1, This function determines whether a remote object is CleanNtmsDrive,NTMSAPI.DLL,NM,2, queues a cleaning request for the specified drive for connected to the corresponding in-process object. cleaning. CoIsOle1Class,OLE32.DLL,NM,1,This function determines if a given CLSID represents an OLE ClearCommBreak,KERNEL32.DLL,NM,1 restores character transmission for aspecified 1 object. communications device and places the transmission line ina nonbreak state. ClearCommError,KERNEL32.DLL,NM,3 retrieves information about acommunications error and CoLoadLibrary,OLE32.DLL,NM,2,Loads a specific DLL into the caller's process. CoLoadLibrary is equivalent to LoadLibraryEx. CoLoadLibrary does not do anything about the lifetime of the reports the current status of acommunications device. ClearEventLog,ADVAPI32.DLL,AW,2, clears the specified event log, and optionally saves the library. CoLockObjectExternal,OLE32.DLL,NM,3,4.2 CoLockObjectExternal This function is called current copy of the logfile to a backup file. ClientToScreen,USER32.DLL,NM,2, replaces the client coordinates in the POINT structure with either to lock an object to ensure that it stays in memory, or to release such a lock. Call CoMarshalHresult,OLE32.DLL,NM,2,This function marshals an HRESULT to the specified the screen coordinates. stream, from which it can be unmarshaled using the CoUnmarshalHresult function. ClipCursor,USER32.DLL,NM,1, confines the cursor to a rectangular area on the screen. CoMarshalInterface,OLE32.DLL,NM,6, This function writes into a stream the data required to CloseClipboard,USER32.DLL,NM,0, closes the clipboard. initialize a proxy object in some client process. The COM library in the client process calls the CloseColorProfile,MSCMS.DLL,NM,1,This CloseColorProfile closes an open profile handle. CoUnmarshalInterface function to extract the data and initialize the proxy. CloseDesktop,USER32.DLL,NM,1, closes an open handle to a desktop object. CloseEnhMetaFile,GDI32.DLL,NM,1 closes an enhanced-metafile devicecontext and returns a CoMarshalInterThreadInterfaceInStream,OLE32.DLL,NM,3,Marshals an interface pointer from one thread to another thread in the same process. handle that identifies an enhanced-formatmetafile. CombineRgn,GDI32.DLL,NM,4 combines two regions and stores the result in a third region. CloseEventLog,ADVAPI32.DLL,NM,1, closes the specified event log. CombineTransform,GDI32.DLL,NM,3, concatenates two world-space to page- space CloseFigure,GDI32.DLL,NM,1, closes an open figure in a path. transformations. CloseHandle,KERNEL32.DLL,NM,1, closes an open object handle. CommConfigDialog,KERNEL32.DLL,AW,3, displays a driver-supplied configuration dialog box. CloseIMsgSession,MAPI32.DLL,NM,1, closes a message session and all the messages CommDlgExtendedError,COMDLG32.DLL,NM,0, can return general error codes for any of the created within that session. common dialog box functions. CloseMetaFile,GDI32.DLL,NM,1, closes a metafile device context and returns a handle that CommitUrlCacheEntry,WININET.DLL,AW,11,Stores data in the specified file in the Internet identifies a Windows-format metafile. cache and associates it with the specified URL. CloseNtmsNotification,NTMSAPI.DLL,NM,1, closes the specified open notification channel. CompareFileTime,KERNEL32.DLL,NM,2, compares two 64-bit file times. CloseNtmsSession,NTMSAPI.DLL,NM,1, closes the specified RSM session. CompareString,KERNEL32.DLL,AW,6 compares two character strings, usingthe locale ClosePrinter,WINMM.DLL,NM,1, closes the specified printer object. CloseServiceHandle,ADVAPI32.DLL,NM,1 closes the handles created with OpenSCManager, specified by the given identifier as the basis for thecomparison. CompleteAuthToken,SECUR32.DLL,NM,2, completes an authentication token. OpenService or CreateService ConfigurePort,WINMM.DLL,AW,3, displays the port-configuration dialog box for a port on the closesocket,WS2_32.DLL,NM,1, closes a socket. specified server. closesocket,WSOCK32.DLL,NM,1, closes a socket. connect,WS2_32.DLL,NM,3, establishes a connection to a specifed socket. CloseWindow,USER32.DLL,NM,1, minimizes (but does not destroy) the specified window. connect,WSOCK32.DLL,NM,3, is used to create a connection to the to the specified CloseWindowStation,USER32.DLL,NM,1, closes an open window station handle. destination. CLSIDFromProgID,OLE32.DLL,NM,2,Looks up a CLSID in the registry, given a ProgID. ConnectNamedPipe,KERNEL32.DLL,NM,2 enables a named pipe server process to wait for a CLSIDFromString,OLE32.DLL,NM,2,Converts a string generated by the StringFromCLSID client process to connect to an instance of a named pipe. function back into the original CLSID. ConnectToPrinterDlg,WINMM.DLL,NM,2, displays a dialog box that lets users browse and ClusWorkerCheckTerminate,RESUTILS.DLL,NM,1,The ClusWorkerCheckTerminate utility connect to printers on a network. function determines whether a worker thread should exit as soon as possible. ContinueDebugEvent,KERNEL32.DLL,NM,3 enables a debugger to continue a thread that ClusWorkerCreate,RESUTILS.DLL,NM,3,The ClusWorkerCreate utility function creates a previously reported a debugging event. worker thread. ControlService,ADVAPI32.DLL,NM,3, sends a control code to a Win32-based service. ClusWorkerTerminate,RESUTILS.DLL,NM,1,The ClusWorkerTerminate utility function ConvertDefaultLocale,KERNEL32.DLL,NM,1, converts a special default locale value to an terminates a worker thread. CoAddRefServerProcess,OLE32.DLL,NM,0,Increments a global per-process reference count. actual locale identifier. ConvertThreadToFiber,KERNEL32.DLL,NM,1 converts the current thread into a fiber. CoBuildVersion,OLE32.DLL,NM,0,4.2 CoBuildVersion This function is obsolete. Requirements OS Versions: Windows CE 3.0 and later. Header: Objbase.h. Link Library: CopyAcceleratorTable,USER32.DLL,AW,3, copies the specified accelerator table. CopyEnhMetaFile,GDI32.DLL,AW,2, copies the contents of an enhanced- format metafile to a Ole32.lib. specified file. CoCopyProxy,OLE32.DLL,NM,2,This function makes a private copy of the specified proxy. CoCreateFreeThreadedMarshaler,OLE32.DLL,NM,2,Creates an aggregatable object capable of CopyFile,KERNEL32.DLL,AW,3 copies an existing file to a new file. CopyFileEx,KERNEL32.DLL,AW,6, copies an existing file to a new file. context-dependent marshaling. CopyIcon,USER32.DLL,NM,1, copies the specified icon from another module to the current CoCreateGuid,OLE32.DLL,NM,1,Creates a GUID, a unique 128-bit integer used for CLSIDs module. and interface identifiers. CopyImage,USER32.DLL,NM,5 creates a new image (icon, cursor, orbitmap) and copies the CoCreateInstance,OLE32.DLL,NM,5,ExCreates an instance of a specific class on a specific attributes of the specified image to the newone. machine. CopyLZFile,LZ32.DLL,NM,2, is obsolete. CoCreateInstanceEx,OLE32.DLL,NM,6,Creates an instance of a specific class on a specific CopyMetaFile,GDI32.DLL,AW,2, copies the content of a Windows-format metafile to the machine. specified file. CoDisconnectObject,OLE32.DLL,NM,2,This function disconnects all remote process CopyRect,USER32.DLL,NM,2, copies the coordinates of one rectangle to another. connections being maintained on behalf of all the interface pointers that point to a specified CopySid,ADVAPI32.DLL,NM,3, copies a security identifier (SID) to a buffer. object. Only the process that actually manages the object should call CoDisconnectObject. CoQueryAuthenticationServices,OLE32.DLL,NM,2,4.2 CoQueryAuthenticationServices This CoDosDateTimeToFileTime,OLE32.DLL,NM,3,Converts the MS-DOS representation of the function retrieves a list of the authentication services registered when the process called . time and date to a FILETIME structure, which Win32 uses to determine the date and time. HRESULT CoFileTimeNow,OLE32.DLL,NM,1, Pointer to return the FILETIME structure. CoQueryClientBlanket,OLE32.DLL,NM,7, This function is called by the server to find out about CoFileTimeToDosDateTime,OLE32.DLL,NM,3,Converts a FILETIME into MS-DOS date and the client that invoked the method executing on the current thread. time values. CoQueryProxyBlanket,OLE32.DLL,NM,8,4.2 CoQueryProxyBlanket This function retrieves CoFreeAllLibraries,OLE32.DLL,NM,0, This function frees all the DLLs that have been loaded with the CoLoadLibrary function (called internally by CoGetClassObject), regardless of whether the authentication information the client uses to make calls on the specified proxy. HRESULT CoQueryReleaseObject,OLE32.DLL,NM,1, This function is not yet supported. they are currently in use. CoFreeLibrary,OLE32.DLL,NM,1,This function frees a library that, when loaded, was specified CoRegisterChannelHook,OLE32.DLL,NM,2, This function is not yet supported. CoRegisterClassObject,OLE32.DLL,NM,5,Registers an EXE class object with OLE so other to be freed explicitly. applications can connect to it. EXE object applications should call CoRegisterClassObject on CoFreeUnusedLibraries,OLE32.DLL,NM,0,Unloads any DLLs that are no longer in use and startup. that, when loaded, were specified to be freed automatically. CoRegisterMallocSpy,OLE32.DLL,NM,1, This function registers an implementation of the CoGetCallContext,OLE32.DLL,NM,2, Interface identifier (IID) of the call context that is being IMallocSpy interface in OLE, thereafter requiring OLE to call its wrapper methods around every requested. call to the corresponding IMalloc method. CoGetCallerTID,OLE32.DLL,NM,1,Returns a GUID identifying the callers thread. CoRegisterMessageFilter,OLE32.DLL,NM,2,Registers with OLE the instance of an CoGetClassObject,OLE32.DLL,NM,5,FromURL Returns a factory object for a given CLSID. CoGetClassObjectFromURL,URLMON.DLL,NM,10, Returns a factory object for a given CLSID. IMessageFilter interface, which is to be used for handling concurrency issues on the current thread. Only one message filter can be registered for each thread. CoGetCurrentLogicalThreadId,OLE32.DLL,NM,1, This function is not yet supported. CoRegisterPSClsid,OLE32.DLL,NM,2,This function enables a downloaded DLL to register its CoGetCurrentProcess,OLE32.DLL,NM,0, This function returns a value that is unique to the custom interfaces within its running process so that the marshaling code will be able to marshal current thread. CoGetCurrentProcess can be used to avoid thread ID reuse problems. DWORD CoGetCurrentProcess(void); Return Value Unique DWORD value identifying the those interfaces. CoReleaseMarshalData,OLE32.DLL,NM,1,This function destroys a previously marshaled data current thread. CoGetInstanceFromFile,OLE32.DLL,NM,8,This function creates a new object and initializes it packet. CoReleaseServerProcess,OLE32.DLL,NM,0,Decrements the global per-process reference from a file using IPersistFile::Load. count. CoGetInterfaceAndReleaseStream,OLE32.DLL,NM,3,This function unmarshals a buffer CoResumeClassObjects,OLE32.DLL,NM,0,4.2 CoResumeClassObjects This function is containing an interface pointer and releases the stream when an interface pointer has been called by a server that can register multiple class objects to inform the OLE SCM about all marshaled from another thread to the calling thread. registered CoGetMalloc,OLE32.DLL,NM,2,4.2 CoGetMalloc This function retrieves a pointer to the CoRevertToSelf,OLE32.DLL,NM,0,This function restores the authentication information on a default OLE task memory allocator (which supports the system implementation of the IMalloc thread of execution. 124 CreateHatchBrush,GDI32.DLL,NM,2, creates a logical brush that has the specified hatch CoRevokeClassObject,OLE32.DLL,NM,1, This function informs OLE that a class object, pattern and color. previously registered with the CoRegisterClassObject function, is no longer available for use. CreateIC,GDI32.DLL,AW,4 creates an information context for the specified device. CoRevokeMallocSpy,OLE32.DLL,NM,0,This function revokes a registered IMallocSpy object. CreateIcon,USER32.DLL,NM,7, creates an icon that has the specified size, colors, and bit CoSetProxyBlanket,OLE32.DLL,NM,8,Sets the authentication information that will be used to patterns. make calls on the specified proxy. This is a helper function for IClientSecurity::SetBlanket. CreateIconFromResource,USER32.DLL,NM,4, creates an icon or cursor from resource bits CoSetState,OLE32.DLL,NM,1, This function is not yet supported. describing the icon. CoSuspendClassObjects,OLE32.DLL,NM,0,4.2 CoSuspendClassObjects This function CreateIconFromResourceEx,USER32.DLL,NM,7, creates an icon or cursor from resource bits prevents any new activation requests from the SCM on all class objects registered within the describing the icon. process. CoSwitchCallContext,OLE32.DLL,NM,2, This function switches the call context object used by CreateIconIndirect,USER32.DLL,NM,1, creates an icon or cursor from an ICONINFO structure. CreateILockBytesOnHGlobal,OLE32.DLL,NM,3,Creates a byte array object, using global CoGetCallContext. memory as the physical device, which is intended to be the compound file foundation. CoTaskMemAlloc,OLE32.DLL,NM,1,Allocates a block of task memory in the same way that CreateIoCompletionPort,KERNEL32.DLL,NM,4 can associate an instance of an opened file IMalloc::Alloc does. CoTaskMemFree,OLE32.DLL,NM,1,Frees a block of task memory previously allocated through with a newly created or an existing input/output completion port; or it can create an input/output completion port without associating it with a file. a call to the CoTaskMemAlloc or CoTaskMemRealloc function. CoTaskMemRealloc,OLE32.DLL,NM,2,Changes the size of a previously allocated block of task CreateIProp,MAPI32.DLL,NM,6, creates a property data object, that is, an IPropData object. CreateItemMoniker,OLE32.DLL,NM,3,This function creates an item moniker that identifies an memory. object within a containing object (typically a compound document). CoTreatAsClass,OLE32.DLL,NM,2, This function establishes or removes an emulation, in CreateMailslot,KERNEL32.DLL,AW,4 creates a mailslot with the specifiedname and returns a which objects of one class are treated as objects of a different class. handle that a mailslot server can use to performoperations on the mailslot. CoUninitialize,OLE32.DLL,NM,0,Closes the COM library on the current thread, unloads all DLLs loaded by the thread, frees any other resources that the thread maintains, and forces all CreateMappedBitmap,COMCTL32.DLL,NM,5, creates a bitmap for use in a toolbar. CreateMDIWindow,USER32.DLL,AW,10, creates a multiple document interface (MDI) child RPC connections on the thread to close. window. CoUnmarshalHresult,OLE32.DLL,NM,2, Pointer to the stream from which the HRESULT is to CreateMenu,USER32.DLL,NM,0, creates a menu. be unmarshaled. CoUnmarshalInterface,OLE32.DLL,NM,3,4.2 CoUnmarshalInterface This function initializes a CreateMetaFile,GDI32.DLL,AW,1, creates a device context for a Windows-meta file. CreateMultiProfileTransform,MSCMS.DLL,NM,6, accepts an array of profiles or a single device newly created proxy using data written into the stream by a previous call to the function, and link profile and creates a color transform that CountClipboardFormats,USER32.DLL,NM,0 retrieves the number of different data formats CreateMutex,KERNEL32.DLL,AW,3, creates a named or unnamed mutex object. currently on the clipboard. CPlApplet,ODBCCP32.DLL,NM,4, is a library-defined callback function that serves as the entry CreateNamedPipe,KERNEL32.DLL,AW,8 creates an instance of a named pipe and returns a handle for subsequent pipe operations. point for a Control Panel application. CreateNtmsMedia,NTMSAPI.DLL,AW,4,The CreateNtmsMediaPool function creates a new CreateAcceleratorTable,USER32.DLL,AW,2, creates an accelerator table. application media pool. CreateAntiMoniker,OLE32.DLL,NM,1, Address of IMoniker* pointer variable that receives the CreateNtmsMediaPool,NTMSAPI.DLL,AW,6, creates a new application media pool. interface pointer to the new anti-moniker. CreateAsyncBindCtx,URLMON.DLL,NM,4, Creates an asynchronous bind context for use with CreateOleAdviseHolder,OLE32.DLL,NM,1, instantiates an advise holder object for managing compound document notifications. It passes out a pointer to asynchronous monikers. CreatePalette,GDI32.DLL,NM,1, creates a logical color palette. CreateBindCtx,OLE32.DLL,NM,2,This function supplies a pointer to an implementation of CreatePatternBrush,GDI32.DLL,NM,1, creates a logical brush with the specified bitmap pattern. IBindCtx, an object that stores information about a particular moniker-binding operation. CreatePen,GDI32.DLL,NM,3, creates a logical pen that has the specified style, width, and color. CreateBitmap,GDI32.DLL,NM,5, creates a bitmap with the specified width, height, and color CreatePenIndirect,GDI32.DLL,NM,1, creates a logical cosmetic pen that has the style, width, format (color planes and bits per pixel). and color specified in a structure. CreateBitmapIndirect,GDI32.DLL,NM,1 creates a bitmap with thespecified width, height, and CreatePipe,KERNEL32.DLL,NM,4, creates an anonymous pipe, and returns handles to the color format (color planes and bitsper pixel). read and write ends of the pipe. CreateBrushIndirect,GDI32.DLL,NM,1, creates a logical brush that has the specified style, CreatePointerMoniker,OLE32.DLL,NM,2, This function creates a pointer moniker based on a color, and pattern. pointer to an object. CreateCaret,USER32.DLL,NM,4, creates a new shape for the system caret and assigns CreatePolygonRgn,GDI32.DLL,NM,3, creates a polygonal region. ownership of the caret to the specified window. CreateClassMoniker,OLE32.DLL,NM,2,Creates a class moniker that refers to the given class. CreatePolyPolygonRgn,GDI32.DLL,NM,4, creates a region consisting of a series of polygons. CreateColorTransform,MSCMS.DLL,AW,4, creates a color transform that applications can use CreatePopupMenu,USER32.DLL,NM,0, creates a drop-down menu, submenu, or shortcut menu. to perform color management. CreateCompatibleBitmap,GDI32.DLL,NM,3 creates a bitmap compatiblewith the device that is CreatePrivateObjectSecurity,ADVAPI32.DLL,NM,6 allocates and initializesa self-relative security descriptor for a new protected server?sis being created. associated with the specified devicecontext. CreateProcess,KERNEL32.DLL,AW,10, creates a new process and its primary thread. CreateCompatibleDC,GDI32.DLL,NM,1, can only be used with devices that support raster CreateProcessAsUser,ADVAPI32.DLL,AW,11, creates a new process and its primary thread. operations. CreateProfileFromLogColorSpace,MSCMS.DLL,AW,2, converts a logical color space to a CreateConsoleScreenBuffer,KERNEL32.DLL,NM,5, creates a console screen buffer and CreatePropertySheetPage,COMCTL32.DLL,AW,1, creates a new page for a property sheet. returns a handle of it. CreateCursor,USER32.DLL,NM,7 creates a cursor having the specified size, bit patterns, and CreateRectRgn,GDI32.DLL,NM,4 creates a rectangular region. CreateRectRgnIndirect,GDI32.DLL,NM,1, creates a rectangular region. hot spot. CreateRemoteThread,KERNEL32.DLL,NM,7, creates a thread that runs in the address space CreateDataAdviseHolder,OLE32.DLL,NM,1,Supplies a pointer to the OLE implementation of of another process. IDataAdviseHolder on the data advise holder object. CreateDataCache,OLE32.DLL,NM,4,Supplies a pointer to a new instance of an OLE-provided CreateRoundRectRgn,GDI32.DLL,NM,6, creates a rectangular region with rounded corners. CreateScalableFontResource,GDI32.DLL,AW,4, creates a font resource file for a scalable font. implementation of a data cache. CreateDC,GDI32.DLL,AW,4, creates a device context (DC) for a device by using the specified CreateSemaphore,KERNEL32.DLL,AW,4, creates a named or unnamed semaphore object. CreateService,ADVAPI32.DLL,AW,13, creates a service object and adds it to the specified name. CreateDesktop,USER32.DLL,AW,6, returns a handle that can be used to access the desktop. service control manager database. CreateSolidBrush,GDI32.DLL,NM,1, creates a logical brush that has the specified solid color. CreateDeviceLinkProfile,MSCMS.DLL,NM,4, creates a device link profile from a set of color CreateStatusWindow,COMCTL32.DLL,AW,4, creates a status window, which is typically used profiles, using the specified intents. CreateDialogIndirectParam,USER32.DLL,AW,5, creates a modeless dialog box from a dialog to display the status of an application. CreateStdDispatch,OLEAUT32.DLL,NM,4,Creates a standard implementation of the IDispatch box template in memory. interface through a single function call. This simplifies exposing objects through Automation. CreateDialogParam,USER32.DLL,AW,5, creates a modeless dialog box from a dialog box CreateStreamOnHGlobal,OLE32.DLL,NM,3,Creates a stream object stored in global memory. template resource. CreateTable,MAPI32.DLL,NM,9 creates structures and an object handle for a table data object CreateDIBitmap,GDI32.DLL,NM,6 creates a device-dependent bitmap (DDB)from a devicean ITableData object which can be used to create table contents. independent bitmap (DIB) and, optionally, sets thebitmap bits. CreateDIBPatternBrush,GDI32.DLL,NM,2 creates a logical brush that has the pattern specified CreateTapePartition,KERNEL32.DLL,NM,4 reformats a tape. CreateTextServices,RICHED20.DLL,NM,3,creates an instance of a text services object. by the specified device-independent bitmap (DIB). CreateThread,KERNEL32.DLL,NM,6, creates a thread to execute within the address space of CreateDIBPatternBrushPt,GDI32.DLL,NM,2 creates a logical brush that has the pattern the calling process. specified by the device-independent bitmap (DIB). CreateToolbarEx,COMCTL32.DLL,NM,13, creates a toolbar window and adds the specified CreateDIBSection,GDI32.DLL,NM,6, creates a device-independent bitmap (DIB) that buttons to the toolbar. applications can write to directly. CreateToolhelp32Snapshot,TOOLHELP.DLL,NM,2, takes a snapshot of the specified CreateDirectory,KERNEL32.DLL,AW,2, creates a new directory. processes in the system, as well as the heaps, modules, and threads used by these processes. CreateDirectoryEx,KERNEL32.DLL,AW,3 creates a new directory with a specified path that CreateTypeLib,OLEAUT32.DLL,NM,3, creates a type library in the current file format. retains the attributes of a specified template directory. CreateTypeLib2,OLEAUT32.DLL,NM,3, creates a type library in the current file format. CreateDiscardableBitmap,GDI32.DLL,NM,3, creates a discardable bitmap that is compatible CreateUpDownControl,COMCTL32.DLL,NM,12, creates an up-down control. with the specified device. CreateUrlCacheEntry,WININET.DLL,AW,5,Creates a local file name for saving the cache entry CreateDispTypeInfo,OLEAUT32.DLL,NM,3,Creates simplified type information for use in an based on the specified URL and the file extension. implementation of IDispatch. CreateUrlCacheGroup,WININET.DLL,NM,2,Generates cache group identifications. CreateEllipticRgn,GDI32.DLL,NM,4, creates an elliptical region. CreateURLMoniker,URLMON.DLL,NM,3, Creates a URL moniker from either a full URL string CreateEllipticRgnIndirect,GDI32.DLL,NM,1, creates an elliptical region. or from a base context URL moniker and a partial URL string. CreateEnhMetaFile,GDI32.DLL,AW,4, creates a device context for an enhanced-format CreateUserProfile,USERENV.DLL,AW,5 creates a user profile with the specified account name metafile. and preferred name. CreateEnvironmentBlock,USERENV.DLL,NM,3, retrieves the environment variables for the CreateWaitableTimer,KERNEL32.DLL,AW,3, creates a ?waitable? timer object. specified user. This block can then be passed to the CreateProcessAsUser function. CreateWindow,USER32.DLL,AW,1 creates an overlapped, pop-up, or childwindow CreateErrorInfo,OLEAUT32.DLL,NM,1, This function creates an instance of a generic error CreateWindowEx,USER32.DLL,AW,12 creates an overlapped, pop-up, or childwindow with an object. extended style; otherwise, this function isidentical to the CreateWindow function. CreateEvent,KERNEL32.DLL,AW,4, creates a named or unnamed event object. CreateWindowStation,USER32.DLL,AW,4, creates a window station object. CreateFiber,KERNEL32.DLL,NM,3 allocates a fiber object, assigns it astack, and sets up CryptAcquireContext,ADVAPI32.DLL,AW,5,used to acquire a handle to a particular key execution to begin at the specified startaddress, typically the fiber function. container within a particular CSP. CreateFile,KERNEL32.DLL,AW,7, creates or opens file CreateFileMapping,KERNEL32.DLL,AW,6, creates a named or unnamed file- mapping object CryptCreateHash,ADVAPI32.DLL,NM,5,used to initiate the hashing of a stream of data. It returns to the caller a handle to a CSP hash object. for the specified file. CryptDecodeMessage,CRYPT32.DLL,NM,13,Decodes, decrypts, and verifies a cryptographic CreateFileMoniker,OLE32.DLL,NM,2,creates a file moniker based on the specified path. message. CreateFont,GDI32.DLL,AW,14, creates a logical font that has specific characteristics. CryptDecodeObject,CRYPT32.DLL,NM,7, decodes a structure of the type indicated by the CreateFontIndirect,GDI32.DLL,AW,1, creates a logical font that has the characteristics lpszStructType parameter. The use of CryptDecodeObjectEx is recommended as an API that specified in the specified structure. performs the same function with significant performance improvements. CreateFormatEnumerator,URLMON.DLL,NM,3, Creates an object that implements CryptDecrypt,ADVAPI32.DLL,NM,6,The CryptDecryptAndVerifyMessageSignature function IEnumFORMATETC over a static array of FORMATETC structures. decrypts a message and verifies its signature. CreateGenericComposite,OLE32.DLL,NM,3,4.2 CreateGenericComposite This function CryptDecryptAndVerifyMessageSignature,CRYPT32.DLL,NM,9, decrypts a message and performs a generic composition of two monikers and supplies a pointer to the resulting verifies its signature. composite moniker. CryptDecryptMessage,CRYPT32.DLL,NM,6, decodes and decrypts a message. CreateHalftonePalette,GDI32.DLL,NM,1 creates a halftone palette for the specified device CryptDeriveKey,ADVAPI32.DLL,NM,5,generates cryptographic keys derived from base data. context. 125 CryptSetOIDFunctionValue,CRYPT32.DLL,NM,7, sets a value for the specified encoding type, CryptDestroyHash,ADVAPI32.DLL,NM,1,destroys the hash object referenced by the hHash function name, OID, and value name. parameter. CryptDestroyKey,ADVAPI32.DLL,NM,1,releases the handle referenced by the hKey parameter. CryptSetProvider,ADVAPI32.DLL,AW,2,is used to specify the current user default CSP. CryptSetProvParam,ADVAPI32.DLL,NM,4,customizes the operations of a CSP. CryptEncodeObject,CRYPT32.DLL,NM,5, encodes a structure of the type indicated by the value of the lpszStructType parameter. The use of CryptEncodeObjectEx is recommended as CryptSignAndEncodeCertificate,CRYPT32.DLL,NM,9,Security SDK content provides details about using authentication, authorization, cryptography, and related technologies in the an API that performs the same function with significant performance improvements. Microsoft Windows Server, Windows, and Windows NT platforms. CryptEncrypt,ADVAPI32.DLL,NM,7,is used to encrypt data. CryptSignAndEncryptMessage,CRYPT32.DLL,NM,8, creates a hash of the specified content, CryptEncryptMessage,CRYPT32.DLL,NM,7, encrypts and encodes a message. CryptEnumOIDFunction,CRYPT32.DLL,NM,6, enumerates the registered object identifier (OID) signs the hash, encrypts the content, hashes the encrypted contents and the signed hash, and then encodes both the encrypted content and the signed hash. functions. CryptExportKey,ADVAPI32.DLL,NM,6,used to export cryptographic keys out of a cryptographic CryptSignCertificate,CRYPT32.DLL,NM,9, signs the CryptSignHash,ADVAPI32.DLL,AW,6,is used to sign a piece of data. service provider in a secure manner. CryptExportPublicKeyInfo,CRYPT32.DLL,NM,5, exports the public key information associated CryptSignMessage,CRYPT32.DLL,NM,7, creates a hash of the specified content, signs the with the corresponding private key of the provider. For an updated version of this function, see hash, and then encodes both the original message content and the signed hash. CryptUnregisterDefaultOIDFunction,CRYPT32.DLL,NM,3, removes the registration of a DLL CryptExportPublicKeyInfoEx. containing the default function to be called for the specified encoding type and function name. CryptExportPublicKeyInfoEx,CRYPT32.DLL,NM,8, exports the public key information CryptUnregisterOIDFunction,CRYPT32.DLL,NM,3, removes the registration of a DLL containing associated with the provider's corresponding private key. the function to be called for the specified encoding type, function name, and OID. CryptFormatObject,CRYPT32.DLL,NM,9, formats the encoded data and returns a Unicode CryptVerifyCertificateSignature,CRYPT32.DLL,NM,5,Verifies the signature of a certificate, string in the allocated buffer according to the certificate encoding type. certificate revocation list (CRL), or certificate request by using the public key in a CryptFreeOIDFunctionAddress,CRYPT32.DLL,NM,2, releases a handle returned by CERT_PUBLIC_KEY_INFO structure. CryptGetOIDFunctionAddress or CryptGetDefaultOIDFunctionAddress by decrementing the CryptVerifyDetachedMessageHash,CRYPT32.DLL,NM,8, verifies a detached hash. reference count on the function handle. CryptGenKey,ADVAPI32.DLL,NM,4,generates random cryptographic keys for use with the CSP CryptVerifyDetachedMessageSignature,CRYPT32.DLL,NM,8, verifies a signed message containing a detached signature or signatures. module. CryptVerifyMessageHash,CRYPT32.DLL,NM,7, verifies the hash of specified content. CryptGenRandom,ADVAPI32.DLL,NM,3,fills a buffer with random bytes. CryptGetDefaultOIDDllList,CRYPT32.DLL,NM,4, acquires the list of the names of DLL files that CryptVerifyMessageSignature,CRYPT32.DLL,NM,7,Verifies a signed message's signature. CryptVerifySignature,ADVAPI32.DLL,AW,6,is used to verify a signature against a hash object. contain registered default object identifier (OID) functions for a specified function set and DAPIAllocBuffer,DAPI.DLL,NM,2, allocates or reallocates a block of memory. encoding type. DAPIEnd,DAPI.DLL,NM,1, closes a directory operation session. CryptGetDefaultOIDFunctionAddress,CRYPT32.DLL,NM,6, loads the DLL that contains a DAPIFreeMemory,DAPI.DLL,NM,1, releases or frees a block of memory. default function address. CryptGetHashParam,ADVAPI32.DLL,NM,5,retrieves data that governs the operations of a hash DAPIGetSiteInfo,DAPI.DLL,AW,3, retrieves the site information for a directory service agent. DAPIRead,DAPI.DLL,AW,6, reads (exports) attributes from a directory object. object. DAPIStart,DAPI.DLL,AW,2, initializes a directory operation session. CryptGetKeyParam,ADVAPI32.DLL,NM,5,retrieves data that govern the operations of a key. DAPIUninitialize,DAPI.DLL,NM,1, terminates background processes. CryptGetMessageCertificates,CRYPT32.DLL,NM,5, returns the handle of an open certificate store containing the message's certificates and CRLs. This function calls CertOpenStore using DAPIWrite,DAPI.DLL,AW,7, writes (imports) information to a directory object. DceErrorInqText,RPCRT4.DLL,AW,2, returns the message text for a status code. provider type CERT_STORE_PROV_PKCS7 as its lpszStoreProvider parameter. CryptGetMessageSignerCount,CRYPT32.DLL,NM,3, returns the number of signers of a signed DdeAbandonTransaction,USER32.DLL,NM,3 abandons the specifiedasynchronous transaction and releases all resources associated withthe transaction. message. CryptGetOIDFunctionAddress,CRYPT32.DLL,NM,6, searches the list of registered and installed DdeAccessData,USER32.DLL,NM,2, provides access to the data in the specified dynamic data exchange (DDE) object. functions for an encoding type and object identifier (OID) match. DdeAddData,USER32.DLL,NM,4, adds data to the specified dynamic data exchange (DDE) CryptGetOIDFunctionValue,CRYPT32.DLL,NM,7, queries a value associated with an OID. CryptGetProvParam,ADVAPI32.DLL,NM,5,retrieves parameters that govern the operations of a object. DdeClientTransaction,USER32.DLL,NM,8, begins a data transaction between a client and a CSP. CryptGetUserKey,ADVAPI32.DLL,NM,3,retrieves a handle to a permanent user key pair, such server. DdeCmpStringHandles,USER32.DLL,NM,2, compares the values of two string handles. as the user?s signature key pair. CryptHashCertificate,CRYPT32.DLL,NM,7, hashes the entire encoded content of a certificate DdeConnect,USER32.DLL,NM,4 establishes a conversation with a server application that supports the specified service name and topic name pair. including its signature. CryptHashData,ADVAPI32.DLL,NM,4,used to compute the cryptographic hash on a stream of DdeCreateStringHandle,USER32.DLL,AW,3 creates a handle that identifies the string pointed to by the psz parameter. data. DdeConnectList,USER32.DLL,NM,5 establishes a conversation with allserver applications that CryptHashMessage,CRYPT32.DLL,NM,9, creates a hash of the message. support the specified service name andtopic name pair. CryptHashPublicKeyInfo,CRYPT32.DLL,NM,7, encodes the public key information in a CERT_PUBLIC_KEY_INFO structure and computes the hash of the encoded bytes. The hash DdeCreateDataHandle,USER32.DLL,NM,7 creates a dynamic data exchange(DDE) object and fills the object with data from the specifiedbuffer. created is used with key identifier functions. CryptHashSessionKey,ADVAPI32.DLL,NM,3,used to compute the cryptographic hash on a key DdeDisconnect,USER32.DLL,NM,1 terminates a conversation started byeither the DdeConnect or DdeConnectList function and invalidatesthe specified conversation handle. object. CryptHashToBeSigned,CRYPT32.DLL,NM,6, computes the hash of the encoded content from a DdeDisconnectList,USER32.DLL,NM,1, destroys the specified conversation list and terminates all conversations associated with the list. signed and encoded certificate. The hash is performed on only the CryptImportKey,ADVAPI32.DLL,NM,6,is used to transfer a cryptographic key from a key blob to DdeEnableCallback,USER32.DLL,NM,3 enables or disables transactions fora specific conversation or for all conversations currentlyestablished by the calling application. the CSP. CryptImportPublicKeyInfo,CRYPT32.DLL,NM,4, converts and imports the public key information DdeFreeDataHandle,USER32.DLL,NM,1, frees a dynamic data exchange (DDE) object and into the provider and returns a handle of the public key. CryptImportPublicKeyInfoEx provides a deletes the data handle associated with the object. DdeFreeStringHandle,USER32.DLL,NM,2, frees a string handle in the calling application. revised version of this function. DdeGetData,USER32.DLL,NM,4, copies data from the specified dynamic data exchange (DDE) CryptImportPublicKeyInfoEx,CRYPT32.DLL,NM,7, imports public key information into the object to the specified local buffer. cryptographic service provider (CSP) and returns a handle of the public key. DdeGetLastError,USER32.DLL,NM,1 returns the most recent error code set by the failure of a CryptInitOIDFunctionSet,CRYPT32.DLL,NM,2,The CryptInitOIDFunctionSet initializes and Dynamic Data Exchange Management Library (DDEML) function and resets the error code to returns the handle of the OID function set identified by a supplied function set name. CryptInstallOIDFunctionAddress,CRYPT32.DLL,NM,6, installs a set of callable object identifier DMLERR_NO_ERROR. DdeImpersonateClient,USER32.DLL,NM,1, impersonates a dynamic data exchange (DDE) (OID) function addresses. client application in a DDE client conversation. CryptMsgCalculateEncodedLength,CRYPT32.DLL,NM,6, calculates the maximum number of DdeInitialize,USER32.DLL,AW,4, registers an application with the Dynamic Data Exchange bytes need for an encoded cryptographic message given the message type, encoding Management Library (DDEML). parameters, and total length of the data to be encoded. CryptMsgClose,CRYPT32.DLL,NM,1, closes a cryptographic message handle. At each call to DdeKeepStringHandle,USER32.DLL,NM,2, increments the usage count associated with the this function, the reference count on the message is reduced by one. When the reference count specified handle. DdeNameService,USER32.DLL,NM,4 registers or unregisters the service names a dynamic reaches zero, the message is fully released. CryptMsgControl,CRYPT32.DLL,NM,4, performs a control operation after a message has been data exchange (DDE) server supports. DdePostAdvise,USER32.DLL,NM,3 causes the system to send an XTYP_ADVREQ transaction decoded by a final call to the CryptMsgUpdate function. CryptMsgCountersign,CRYPT32.DLL,NM,4, countersigns an existing signature in a message. to the calling (server) application?s dynamic data exchange (DDE) callback function for each client with an active advise loop on the specified topic and item. CryptMsgCountersignEncoded,CRYPT32.DLL,NM,7, countersigns an existing PKCS #7 DdeQueryConvInfo,USER32.DLL,NM,3 obtains information about a dynamic data exchange message signature. (DDE) transaction and about the conversation in which the transaction takes place. CryptMsgEncodeAndSignCTL,CRYPT32.DLL,NM,6, encodes a CTL and creates a signed message containing the encoded CTL.This function first encodes the CTL pointed to by pCtlInfo DdeQueryNextServer,USER32.DLL,NM,2 obtains the next conversation handle in the specified conversation list. and then calls CryptMsgSignCTL to sign the encoded message. DdeQueryString,USER32.DLL,AW,5 copies text associated with a string handle into a buffer. + CryptMsgGetAndVerifySigner,CRYPT32.DLL,NM,6, verifies a cryptographic message's DdeReconnect,USER32.DLL,NM,1 allows a client Dynamic Data Exchange Management signature. CryptMsgGetParam,CRYPT32.DLL,NM,5, acquires a message parameter after a cryptographic Library (DDEML) application to attempt to reestablish a conversation with a service that has message has been encoded or decoded. This function is called after the final CryptMsgUpdate terminated a conversation with the client. DdeSetQualityOfService,USER32.DLL,NM,3 specifies the quality of service a raw DDE call. CryptMsgOpenToDecode,CRYPT32.DLL,NM,6,Opens a cryptographic message for decoding application desires for future DDE conversations it initiates. DdeSetUserHandle,USER32.DLL,NM,3, associates an application-defined 32- bit value with a and returns a handle of the opened message. CryptMsgOpenToEncode,CRYPT32.DLL,NM,6, opens a cryptographic message for encoding conversation handle or a transaction identifier. and returns a handle of the opened message. The message remains open until CryptMsgClose DdeUnaccessData,USER32.DLL,NM,1, unaccesses a dynamic data exchange (DDE) object. DdeUninitialize,USER32.DLL,NM,1 frees all Dynamic Data ExchangeManagement Library is called. (DDEML) resources associated with the callingapplication. CryptMsgSignCTL,CRYPT32.DLL,NM,7, creates a signed message containing an encoded DeallocateNtmsMedia,NTMSAPI.DLL,NM,3, deallocates the side associated with the specified CTL. logical media. CryptMsgUpdate,CRYPT32.DLL,NM,4, adds contents to a cryptographic message. CryptMsgVerifyCountersignatureEncoded,CRYPT32.DLL,NM,7, verifies the countersignature of DebugActiveProcess,KERNEL32.DLL,NM,1, allows a debugger to attach to an active process and then debug it. a message. CryptRegisterDefaultOIDFunction,CRYPT32.DLL,NM,4,The CryptRegisterDefaultOIDFunction DebugBreak,KERNEL32.DLL,NM,0 causes a breakpoint exception to occur inthe current registers a DLL containing the default function to be called for the specified encoding type and process so that the calling thread can signal thedebugger and force it to take some action. function name. Unlike CryptRegisterOIDFunction, the function name to be exported by the DLL DecommissionNtmsMedia,NTMSAPI.DLL,NM,2, moves a side from the Available state to the Decommissioned state. cannot be overridden. CryptRegisterOIDFunction,CRYPT32.DLL,NM,5,Registers a DLL that contains the function to DecryptMessage,SECUR32.DLL,NM,4,Decrypts a message by using Negotiate. DefDlgProc,USER32.DLL,AW,4 carries out default message processing fora window procedure be called for the specified encoding type, function name, and object identifier (OID). belonging to an application-defined dialog boxclass. CryptReleaseContext,ADVAPI32.DLL,NM,2,is used to release a handle to a CSP and a key DefFrameProc,USER32.DLL,AW,5 provides default processing for anywindow messages that container. the window procedure of a multiple documentinterface (MDI) frame window does not process. CryptSetHashParam,ADVAPI32.DLL,NM,4,in theory, customizes the operations of a hash DefineDosDevice,KERNEL32.DLL,AW,3 lets an application define, redefine, or delete MS-DOS object. device names. CryptSetKeyParam,ADVAPI32.DLL,NM,4,customizes various aspects of a key?s operations. 126 DefMDIChildProc,USER32.DLL,AW,4 provides default processing for anywindow message that DispatchMessage,USER32.DLL,AW,1, dispatches a message to a window procedure. DispGetIDsOfNames,OLEAUT32.DLL,NM,4,Uses type information to convert a set of names to the window procedure of a multiple documentinterface (MDI) child window does not process. DISPIDs. This is the recommended implementation of IDispatch::GetIDsOfNames. DefWindowProc,USER32.DLL,AW,4 calls the default window procedure toprovide default DispGetParam,OLEAUT32.DLL,NM,5, This function retrieves a parameter from the processing for any window messages that anapplication does not process. DeinitMapiUtil,MAPI32.DLL,NM,0 releases utility functions calledexplicitly by the ScInitMapiUtil DISPPARAMS structure, checks both named parameters and positional parameters, and coerces the parameter to the specified type. function or implicitly by theMAPIInitialize function. DispInvoke,OLEAUT32.DLL,NM,8,Automatically calls member functions on an interface, given DeleteAce,ADVAPI32.DLL,NM,2, deletes an ACE from an ACL. the type information for the interface. You can describe an interface with type information and DeleteColorTransform,MSCMS.DLL,NM,1, deletes a given color transform. DeleteCriticalSection,KERNEL32.DLL,NM,1, releases all resources used by an unowned critical implement IDispatch::Invoke for the interface using this single call. DlgDirList,USER32.DLL,AW,5, fills the specified list box with the names of all files matching the section object. specified path or filename. DeleteDC,GDI32.DLL,NM,1, deletes the specified device context (DC). DlgDirListComboBox,USER32.DLL,AW,5, fills the specified combo box with a directory listing. DeleteEnhMetaFile,GDI32.DLL,NM,1, deletes an enhanced-format metafile or an enhancedDlgDirSelectComboBoxEx,USER32.DLL,AW,4, retrieves the current selection from a combo format metafile handle. box filled by using the DlgDirListComboBox function. DeleteFiber,KERNEL32.DLL,NM,1, deletes an existing fiber. DlgDirSelectEx,USER32.DLL,AW,4, retrieves the current selection from a single-selection list DeleteFile,KERNEL32.DLL,AW,1, deletes an existing file. box. DeleteForm,WINMM.DLL,AW,2, removes a form name from the list of supported forms. DllDebugObjectRPCHook,OLE32.DLL,NM,2, This function is not yet supported. DeleteMenu,USER32.DLL,NM,3, deletes an item from the specified menu. DllEntryPoint,EDBBCLI.DLL,NM,3, is an optional method of entry into a dynamic-link library DeleteMetaFile,GDI32.DLL,NM,1, deletes a Windows-format metafile or Windows-format (DLL). metafile handle. DllEntryPoint,MSCMS.DLL,NM,3, is an optional method of entry into a dynamic-link library DeleteMonitor,WINMM.DLL,AW,3, removes a printer monitor added by the AddMonitor (DLL). function. DeleteNtmsDrive,NTMSAPI.DLL,NM,2, deletes a drive from the RSM database. The drive must DocumentProperties,WINMM.DLL,AW,6 retrieves or modifies printerinitialization information or displays a printer-configurationdialog box for the specified printer. have a dwOperationalState of NTMS_NOT_PRESENT. DeleteNtmsLibrary,NTMSAPI.DLL,NM,2, deletes a library, and all the devices contained in the DoDragDrop,OLE32.DLL,NM,4,Carries out an OLE drag and drop operation. DosDateTimeToFileTime,KERNEL32.DLL,NM,3, converts MS-DOS date and time values to a library, from the RSM database. All media in the library is moved to the offline library. DeleteNtmsMedia,NTMSAPI.DLL,NM,2, deletes a physical piece of offline media from RSM by 64-bit file time. DosDateTimeToVariantTime,OLEAUT32.DLL,NM,3,Converts the MS-DOS representation of removing all references to the specified media from the database. time to the date and time representation stored in a variant. DeleteNtmsMediaPool,NTMSAPI.DLL,NM,2, deletes the specified application media pool. DeleteNtmsMediaType,NTMSAPI.DLL,NM,3, deletes the specified media type relation from the DPtoLP,GDI32.DLL,NM,3, converts device coordinates into logical coordinates. DragAcceptFiles,SHELL32.DLL,NM,2, registers whether a window accepts dropped files. specified library, provided that the library does not contain any physical media objects of the DragDetect,USER32.DLL,NM,3 captures the mouse and tracks its movement until the user specified media type. releases the left button, presses the ESC key, or moves the mouse outside the ?drag DeleteObject,GDI32.DLL,NM,1 deletes a logical pen, brush, font, bitmap, region, or palette, rectangle? around the specified point. freeing all system resources associated with the object. DeletePort,WINMM.DLL,AW,3, displays a dialog box that allows the user to delete a port name. DragFinish,SHELL32.DLL,NM,1, releases memory that Windows allocated for use in transferring filenames to the application. DeletePrinter,WINMM.DLL,NM,1, deletes the specified printer object. DragQueryFile,SHELL32.DLL,AW,4, retrieves the filenames of dropped files. DeletePrinterConnection,WINMM.DLL,AW,1 deletes a connection to aprinter that was DragQueryPoint,SHELL32.DLL,NM,2, retrieves the position of the mouse pointer at the time a established by a call to AddPrinterConnection orConnectToPrinterDlg. DeletePrinterDriver,WINMM.DLL,AW,3 removes the specified printer-driver name from the list file was dropped. DrawAnimatedRects,USER32.DLL,NM,4 draws a wire-frame rectangle andanimates it to of names of supported drivers for aserver. indicate the opening of an icon or the minimizing ormaximizing of a window. DeletePrintProcessor,WINMM.DLL,AW,3, removes a printer processor added by the DrawCaption,USER32.DLL,NM,4, draws a window caption. AddPrintProcessor function. DrawDibBegin,MSVFW32.DLL,NM,8 changes parameters of a DrawDib DC or initializes a new DeletePrintProvidor,WINMM.DLL,AW,3, removes a printer provider added by the DrawDib DC. AddPrintProvidor function. DeleteSecurityContext,SECUR32.DLL,NM,1, deletes the local data structures associated with DrawDibChangePalette,MSVFW32.DLL,NM,4, sets the palette entries used for drawing DIBs. DrawDibClose,MSVFW32.DLL,NM,1, closes a DrawDib DC and frees the resources DrawDib the specified security context. allocated for it. DeleteService,ADVAPI32.DLL,NM,1 marks the specified service for deletion from the service DrawDibDraw,MSVFW32.DLL,NM,13, draws a DIB to the screen. control manager database. DeleteUrlCacheEntry,WININET.DLL,AW,1,Removes the file associated with the source name DrawDibEnd,MSVFW32.DLL,NM,1 clears the flags and other settings of aDrawDib DC that are set by the DrawDibBegin or DrawDibDrawfunctions. from the cache, if the file exists. DrawDibGetBuffer,MSVFW32.DLL,NM,4, retrieves the location of the buffer used by DrawDib DeleteUrlCacheGroup,WININET.DLL,NM,4,Releases the specified GROUPID and any for decompression. associated state in the cache index file. DrawDibGetPalette,MSVFW32.DLL,NM,1, retrieves the palette used by a DrawDib DC. DeregisterEventSource,ADVAPI32.DLL,NM,1, closes a handle to the specified event log. DrawDibOpen,MSVFW32.DLL,NM,0, opens the DrawDib library for use and creates a DrawDib DeregisterIdleRoutine,MAPI32.DLL,NM,1, removes a FNIDLE - based idle routine from the DC for drawing. MAPI system. DescribePixelFormat,GDI32.DLL,NM,4 obtains information about thepixel format identified by DrawDibProfileDisplay,MSVFW32.DLL,NM,1, determines settings for the display system when using DrawDib functions. iPixelFormat of the device associatedwith hdc. DrawDibRealize,MSVFW32.DLL,NM,3, realizes the palette of the DrawDib DC for use with the DestroyAcceleratorTable,USER32.DLL,NM,1, destroys an accelerator table. DestroyCaret,USER32.DLL,NM,0, destroys the caret?s current shape, frees the caret from the specified DC. DrawDibSetPalette,MSVFW32.DLL,NM,2 sets the palette used for drawing DIBs. window, and removes the caret from the screen. DrawDibStart,MSVFW32.DLL,NM,2, prepares a DrawDib DC for streaming playback. DestroyCursor,USER32.DLL,NM,1, destroys a cursor and frees any memory the cursor DrawDibStop,MSVFW32.DLL,NM,1, frees the resources used by a DrawDib DC for streaming occupied. playback. DestroyEnvironmentBlock,USERENV.DLL,NM,1, frees environment variables created by the DrawDibTime,MSVFW32.DLL,NM,2, retrieves timing information about the drawing operation CreateEnvironmentBlock function. and is used during debug operations. DestroyIcon,USER32.DLL,NM,1, destroys an icon and frees any memory the icon occupied. DestroyMenu,USER32.DLL,NM,1 destroys the specified menu and frees any memory that the DrawEdge,USER32.DLL,NM,4, draws one or more edges of rectangle. DrawEscape,GDI32.DLL,NM,4 accesses drawing capabilities of a video display that are not menu occupies. directly available through the graphics device interface (GDI). DestroyPrivateObjectSecurity,ADVAPI32.DLL,NM,1 deletes a protected server object?s DrawFocusRect,USER32.DLL,NM,2, draws a rectangle in the style used to indicate that the security descriptor. DestroyPropertySheetPage,COMCTL32.DLL,NM,1, destroys a property sheet not been passed rectangle has the focus. DrawFrameControl,USER32.DLL,NM,4, draws a frame control of the specified type and style. to the PropertySheet function. DrawIcon,USER32.DLL,NM,4, draws an icon in the client area of the window of the specified DestroyWindow,USER32.DLL,NM,1, destroys the specified window. device context. DeviceCapabilities,WINMM.DLL,AW,5, retrieves the capabilities of a printer device driver. DrawIconEx,USER32.DLL,NM,9 draws an icon or cursor in the client area of the window of the DeviceIoControl,KERNEL32.DLL,NM,8 sends a control code directly to a specified device specified device context, performing the specified raster operations, and stretching or driver, causing the corresponding device to perform the specified operation. compressing the icon or cursor as specified. DialogBoxIndirectParam,USER32.DLL,AW,5, creates a modal dialog box from a dialog box DrawInsert,COMCTL32.DLL,NM,3, draws the insert icon in the parent window of the specified template in memory. drag list box. DialogBoxParam,USER32.DLL,AW,5, creates a modal dialog box from a dialog box template DrawMenuBar,USER32.DLL,NM,1, redraws the menu bar of the specified window. resource. DrawState,USER32.DLL,AW,10, displays an image and applies a visual effect to indicate a DirectDrawCreate,DDRAW.DLL,NM,3,creates an instance of a DirectDraw object. DirectDrawCreateClipper,DDRAW.DLL,NM,3,creates an instance of a DirectDrawClipper object state, such as a disabled or default state. DrawStatusText,COMCTL32.DLL,AW,4, draws the specified text in the style of a status window not associated with a DirectDraw object. DirectDrawEnumerate,DDRAW.DLL,AW,2,enumerates the primary DirectDraw display device with borders. DrawText,USER32.DLL,AW,5, draws formatted text in the specified rectangle. and a nondisplay device (such as a 3-D accelerator that has no 2-D capabilities), if one is DrawTextEx,USER32.DLL,AW,6 draws formatted text in the specified rectangle. installed. DirectInputCreate,DINPUT.DLL,AW,4,This function creates a DirectInput object that supports DriveType,SHELL32.DLL,NM,1 Determines the drive type based on the drive number. DumpCAP,CAP.DLL,NM,0,Write data for the current instance of CAP.DLL. The name of the the IDirectInput COM interface. text file is APPNAME.CAP. DirectPlayCreate,DPLAY.DLL,NM,3,Creates an instance of a DirectPlay object. DuplicateHandle,KERNEL32.DLL,NM,7, duplicates an object handle. DirectPlayCreate,DPLAYX.DLL,NM,3,Creates an instance of a DirectPlay object. DirectPlayEnumerate,DPLAY.DLL,NM,2,Enumerates the DirectPlay service providers installed DuplicateToken,ADVAPI32.DLL,NM,3, creates a new access token that duplicates one already in existence. on the system. DuplicateTokenEx,ADVAPI32.DLL,NM,6, creates a new access token that duplicates an DirectPlayEnumerate,DPLAYX.DLL,AW,2,Enumerates the DirectPlay service providers existing token. installed on the system. DirectPlayLobbyCreate,DPLAYX.DLL,AW,5,Creates an instance of a DirectPlayLobby object. EjectNtmsCleaner,NTMSAPI.DLL,NM,4, ejects the cleaning cartridge from the currently reserved cleaner slot. DirectXFileCreate,D3DXOF.DLL,NM,1,Creates an instance of a DirectXFile object. EjectNtmsMedia,NTMSAPI.DLL,NM,4, ejects the specified medium from the port of the current DirectXRegisterApplication,DSETUP.DLL,AW,2,Registers an ISV's game as an application library. If the library is busy, RSM queues EjectNtmsMedia and returns success. designed to work with DirectPlayLobby. Ellipse,GDI32.DLL,NM,5 draws an ellipse. The center of the ellipse is the center of the specified DirectXSetup,DSETUP.DLL,AW,3,Installs one or more DirectX components. bounding rectangle. DisableNtmsObject,NTMSAPI.DLL,NM,3, disables the specified RSM object. EmptyClipboard,USER32.DLL,NM,0, empties the clipboard and frees handles to data in the DisableThreadLibraryCalls,KERNEL32.DLL,NM,1, lets a DLL disable the clipboard. DLL_THREAD_ATTACH and DLL_THREAD_DETACH notification calls. DisassociateColorProfileFromDevice,MSCMS.DLL,AW,3, disassociates a specified color profile EmptyWorkingSet,PSAPI.DLL,NM,1, removes as many pages as possible from the working set of the specified process. with a specified device on a specified computer. EnableIdleRoutine,MAPI32.DLL,NM,2 enables or disables a FNIDLE based idle routine. DisconnectNamedPipe,KERNEL32.DLL,NM,1, disconnects the server end of a named pipe EnableMenuItem,USER32.DLL,NM,3, enables, disables, or grays the specified menu item. instance from a client process. EnableNtmsObject,NTMSAPI.DLL,NM,3, enables the specified object. DismountNtmsDrive,NTMSAPI.DLL,NM,2, queues a command to move the media in the EnableScrollBar,USER32.DLL,NM,3, enables or disables one or both scroll bar arrows. specified drive to its storage slot. This function should be paired with the MountNtmsMedia EnableWindow,USER32.DLL,NM,2, enables or disables mouse and keyboard input to the function. DismountNtmsMedia,NTMSAPI.DLL,NM,4, queues a command to move the specified media in specified window or control. a drive to its storage. This function should be paired with the MountNtmsMedia function. 127 EqualRect,USER32.DLL,NM,2 determines whether the two specifiedrectangles are equal by EncryptMessage,SECUR32.DLL,NM,4,Encrypts a message to provide privacy by using comparing the coordinates of their upper-left and lower-right corners. Negotiate. EqualRgn,GDI32.DLL,NM,2, checks the two specified regions to determine whether they are EndDialog,USER32.DLL,NM,2, destroys a modal dialog box, causing the system to end any identical. processing for the dialog box. EndDoc,GDI32.DLL,NM,1 ends a print job. This function replaces the ENDDOC printer escape. EqualSid,ADVAPI32.DLL,NM,2, tests two security identifier (SID) values. EndDocPrinter,WINMM.DLL,NM,1, returns an error if the print job was not started by calling the EraseTape,KERNEL32.DLL,NM,3 erases all or part of a tape. Escape,GDI32.DLL,NM,5, allows applications to access capabilities of a particular device not StartDocPrinter function. directly available through GDI. EndPage,GDI32.DLL,NM,1 informs the device that the application has finished writing to a EscapeCommFunction,KERNEL32.DLL,NM,2, directs a specified communications device to page. perform an extended function. EndPagePrinter,WINMM.DLL,NM,1, indicates the end of one page and the beginning of the ExcludeClipRect,GDI32.DLL,NM,5 creates a new clipping region thatconsists of the existing next page for the specified printer. clipping region minus the specifiedrectangle. EndPaint,USER32.DLL,NM,2, marks the end of painting in the specified window. EndPath,GDI32.DLL,NM,1, closes a path bracket and selects the path defined by the bracket ExcludeUpdateRgn,USER32.DLL,NM,2 prevents drawing within invalid areasof a window by excluding an updated region in the window from aclipping region. into the specified device context. ExitProcess,KERNEL32.DLL,NM,1,l does not return until no threads are in their DLL EndUpdateResource,KERNEL32.DLL,AW,2, ends a resource update in an executable file. initialization or detach routines. EnterCriticalPolicySection,USERENV.DLL,NM,1, pauses the application of policy to allow ExitThread,KERNEL32.DLL,NM,1, ends a thread. applications to safely read policy settings. EnterCriticalSection,KERNEL32.DLL,NM,1, waits for ownership of the specified critical section ExitWindowsEx,USER32.DLL,NM,2, returns as soon as it has initiated the shutdown. ExpandEnvironmentStrings,KERNEL32.DLL,AW,3, expands environment-variable strings and object. replaces them with their defined values. EnumCalendarInfo,KERNEL32.DLL,AW,4, enumerates calendar information for a specified ExpandEnvironmentStringsForUser,USERENV.DLL,AW,4, expands the source string by using locale. the environment block established for the specified user. EnumChildWindows,USER32.DLL,NM,3, enumerates the child windows that belong to the specified parent window by passing the handle of each child window, in turn, to an application- ExportNtmsDatabase,NTMSAPI.DLL,NM,1, creates a consistent set of database files in the RSM database directory. defined callback function. ExportSecurityContext,SECUR32.DLL,NM,4, creates a serialized representation of a security EnumClipboardFormats,USER32.DLL,NM,1, lets you enumerate the data formats that are context that can later be imported into a different process by calling ImportSecurityContext. currently available on the clipboard. ExtCreatePen,GDI32.DLL,NM,5, creates a logical cosmetic or geometric pen that has the EnumColorProfiles,MSCMS.DLL,AW,5, enumerates all the profiles satisfying the given specified style, width, and brush attributes. enumeration criteria. ExtCreateRegion,GDI32.DLL,NM,3, creates a region from the specified region and EnumDateFormats,KERNEL32.DLL,AW,3 enumerates the long or short dateformats that are transformation data. available for a specified locale, including dateformats for any alternate calendars. EnumDependentServices,ADVAPI32.DLL,AW,6 provides the name and status of each service ExtensionPropSheetPageProc,SETUPAPI.DLL,NM,3 specifies an application-defined callback that depends on the specified service; that is, the specified service must be running before the function that receives the address of the AddPropSheetPageProc function, which resides in the module that creates a property sheet. dependent services can run. EnumDesktopWindows,USER32.DLL,NM,3 enumerates all windows in a desktopby passing the ExtEscape,GDI32.DLL,NM,6, allows applications to access capabilities of a particular device that are not available through GDI. handle of each window, in turn, to an application-defined callback function. EnumDeviceDrivers,PSAPI.DLL,NM,3, retrieves the load address for each device driver in the ExtFloodFill,GDI32.DLL,NM,5, fills an area of the display surface with the current brush. ExtractAssociatedIcon,SHELL32.DLL,AW,3 returns the handle of an indexedicon found in a file system. or an icon found in an associated executablefile. EnumDisplayMonitors,USER32.DLL,NM,4 enumerates display monitors (including invisible ExtractIcon,SHELL32.DLL,AW,3 retrieves the handle of an icon from thespecified executable pseudo-monitors associated with the mirroring drivers) that intersect a region formed by the file, dynamic-link library (DLL), or iconfile. intersection of a specified clipping rectangle and the visible region of a device context. EnumDisplaySettings,USER32.DLL,AW,3 obtains information about one of a display device?s ExtractIconEx,SHELL32.DLL,AW,5 retrieves the handle of an icon from thespecified executable file, dynamic-link library (DLL), or iconfile. graphics modes. ExtSelectClipRgn,GDI32.DLL,NM,3 combines the specified region with the current clipping EnumEnhMetaFile,GDI32.DLL,NM,5 enumerates the records within anenhanced-format region by using the specified mode. metafile by retrieving each record and passing itto the specified callback function. ExtTextOut,GDI32.DLL,AW,8, draws a character string by using the currently selected font. EnumerateNtmsObject,NTMSAPI.DLL,NM,6, enumerates the RSM objects contained in the FatalAppExit,KERNEL32.DLL,AW,2 displays a message box and terminates the application lpContainerId parameter. EnumerateSecurityPackages,SECUR32.DLL,AW,2,Returns an array of SecPkgInfo structures when the message box is closed. FatalExit,KERNEL32.DLL,NM,1, transfers execution control to the debugger. that describe the security packages available to the client. FaxAbort,WINFAX.DLL,NM,2, A fax client application calls the FaxAbort function to terminate a EnumFontFamilies,GDI32.DLL,AW,4, enumerates the fonts in a specified font family that are fax job. available on a specified device. EnumFontFamiliesEx,GDI32.DLL,AW,5 enumerates all fonts in the systemthat match the font FaxAccessCheck,WINFAX.DLL,NM,2, A fax client application calls the FaxAccessCheck function to query the fax access privileges of a user. characteristics specified by the LOGFONTstructure. FaxClose,WINFAX.DLL,NM,1, closes the following types of fax handles: A fax server handle EnumFonts,GDI32.DLL,AW,4, enumerates the fonts available on a specified device. returned by a call the FaxConnectFaxServer function A fax port handle returned by a call EnumForms,WINMM.DLL,AW,6 enumerates the forms supported by the specified printer. FaxCompleteJobParams,WINFAX.DLL,AW,2, creates both a FAX_COVERPAGE_INFO EnumJobs,WINMM.DLL,AW,8 initializes an array of either JOB_INFO_1 orJOB_INFO_2 structure and a FAX_JOB_PARAM structure for a fax client application. structures with data describing the specified print jobsfor the specified printer. EnumMetaFile,GDI32.DLL,NM,4 enumerates the records within a Windows-format metafile by FaxConnectFaxServer,WINFAX.DLL,AW,2, connects a fax client application to the local fax server. retrieving each record and passing it to the specified callback function. FaxEnableRoutingMethod,WINFAX.DLL,AW,3, enables or disables a fax routing method for a EnumMonitors,WINMM.DLL,AW,6 initializes an array of structures with data describing the specific fax device. A fax administration application typically calls this function for device monitors for the specified server. management. EnumObjects,GDI32.DLL,NM,4, enumerates the pens or brushes available for the specified FaxEnumGlobalRoutingInfo,WINFAX.DLL,AW,3, enumerates all fax routing methods device context. associated with a specific fax server. EnumPorts,WINMM.DLL,AW,5, can succeed even if the server specified by pName does not FaxEnumJobs,WINFAX.DLL,AW,3, enumerates all queued and active fax jobs on the fax have a printer defined. server to which the client has connected. The function returns detailed information for each fax EnumPrinterDrivers,WINMM.DLL,AW,7, enumerates all of the printer drivers installed on the job to the fax client application. specified printer server. FaxEnumPorts,WINFAX.DLL,AW,3, enumerates all fax devices currently attached to the fax EnumPrinters,WINMM.DLL,AW,7, enumerates available printers, print servers, domains, or server to which the client has connected. The function returns detailed information for each fax print providers. EnumPrintProcessorDatatypes,WINMM.DLL,AW,7, enumerates the data types that a specifed port to the fax client application. FaxEnumRoutingMethods,WINFAX.DLL,AW,3, enumerates all fax routing methods for a print processor supports. specific fax device. The function returns information about each routing method to a fax client EnumPrintProcessors,WINMM.DLL,AW,7, enumerates the print processors installed on the application. specified server. FaxFreeBuffer,WINFAX.DLL,NM,1, releases resources associated with a buffer allocated EnumProcesses,PSAPI.DLL,NM,3, retrieves the process identifier for each process object in previously as the result of a function call by a fax client application. the system. FaxGetConfiguration,WINFAX.DLL,AW,2, returns to a fax client application the global EnumProcessModules,PSAPI.DLL,NM,4, retrieves a handle for each module in the specified configuration settings for the fax server to which the client has connected. process. FaxGetDeviceStatus,WINFAX.DLL,AW,2, returns to a fax client application current status EnumProps,USER32.DLL,AW,2 enumerates all entries in the property listof a window by information for the fax device of interest. passing them, one by one, to the specified callbackfunction. FaxGetJob,WINFAX.DLL,AW,3, A fax client application calls the FaxGetJob function to retrieve EnumPropsEx,USER32.DLL,AW,3 enumerates all entries in the propertylist of a window by detailed information for the specified queued or active fax job. The function returns the passing them, one by one, to the specifiedcallback function. information in a FAX_JOB_ENTRY structure. EnumProtocols,MSWSOCK.DLL,AW,3,Important is a Microsoft-specific extension to the FaxGetLoggingCategories,WINFAX.DLL,AW,3, returns to a fax client application the current Windows Sockets 1. logging categories for the fax server to which the client has connected. EnumProtocols,WSOCK32.DLL,AW,3,Important is a Microsoft-specific extension to the FaxGetPageData,WINFAX.DLL,NM,6, returns to a fax client application the first page of data Windows Sockets 1. EnumResourceLanguages,KERNEL32.DLL,AW,5 searches a module for eachresource of the for a fax job. The fax job must be an outbound job, but it can be queued or active. FaxGetPort,WINFAX.DLL,AW,2, returns information for a specified fax port to a fax client specified type and name and passes the language ofeach resource it locates to a defined application. callback function. FaxGetRoutingInfo,WINFAX.DLL,AW,4, returns to a fax client application routing information for EnumResourceNames,KERNEL32.DLL,AW,4 searches a module for each resourceof the a fax routing method that is associated with a specific fax device. specified type and passes the name of each resource itlocates to an application-defined FaxInitializeEventQueue,WINFAX.DLL,NM,5, creates a fax event queue for the calling fax client callback function. EnumResourceTypes,KERNEL32.DLL,AW,3 searches a module for resources andpasses each application. The queue enables the application to receive notifications of asynchronous events from the fax server. resource type it finds to an application-definedcallback function. EnumServicesStatus,ADVAPI32.DLL,AW,8 enumerates services in the specified service control FaxOpenPort,WINFAX.DLL,NM,4, returns a fax port handle to a fax client application. The port handle is required when the application calls other fax client functions that facilitate device manager database. management and fax document routing. EnumSystemCodePages,KERNEL32.DLL,AW,2 enumerates the code pages that are either FaxPrintCoverPage,WINFAX.DLL,AW,2, prints a fax transmission cover page to the specified installed on or supported by a system. EnumSystemLocales,KERNEL32.DLL,AW,2, enumerates the locales that are either installed on device context for a fax client application. A device context handle is obtained by using the FaxStartPrintJob function. or supported by a system. EnumThreadWindows,USER32.DLL,NM,3 enumerates all nonchild windows associated with a FaxSendDocument,WINFAX.DLL,AW,5,ForBroadcast A fax client application calls the FaxSendDocumentForBroadcast function to queue several fax jobs that will transmit the same thread by passing the handle of each window, in turn, to an application-defined callback outgoing fax transmission to several recipients. function. EnumTimeFormats,KERNEL32.DLL,AW,3, enumerates the time formats that are available for a FaxSendDocumentForBroadcast,WINFAX.DLL,AW,5, A fax client application calls the FaxSendDocumentForBroadcast function to queue several fax jobs that will transmit the same specified locale. EnumWindows,USER32.DLL,NM,2 enumerates all top-level windows on thescreen by passing outgoing fax transmission to several recipients. FaxSetConfiguration,WINFAX.DLL,AW,2, A fax client application calls the FaxSetConfiguration the handle of each window, in turn, to anapplication-defined callback function. function to change the global configuration settings for the fax server to which the client has EnumWindowStations,USER32.DLL,AW,2, enumerates only those window stations for which connected. the calling process has WINSTA_ENUMERATE access. EqualPrefixSid,ADVAPI32.DLL,NM,2, tests two security-identifier (SID) prefix values for equality. 128 FaxSetGlobalRoutingInfo,WINFAX.DLL,AW,2, A fax management application calls the FaxSetGlobalRoutingInfo function to modify fax routing method data, such as routing priority, that applies globally to the fax server. FaxSetJob,WINFAX.DLL,AW,4, A fax client application calls the FaxSetJob function to pause, resume, cancel, or restart a specified fax job. FaxSetLoggingCategories,WINFAX.DLL,AW,3, A fax client application calls the FaxSetLoggingCategories function to modify the current logging categories for the fax server to which the client has connected. FaxSetPort,WINFAX.DLL,AW,2, A fax client application calls the FaxSetPort function to change the configuration of the fax port of interest. FaxSetRoutingInfo,WINFAX.DLL,AW,4, A fax management application calls the FaxSetRoutingInfo function to modify the routing information for a fax routing method that is associated with a specific fax device. FaxStartPrintJob,WINFAX.DLL,AW,4, A fax client application calls the FaxStartPrintJob function to start printing an outbound fax transmission on the specified fax printer. The function returns a handle to a device context. FBadColumnSet,MAPI32.DLL,NM,1 tests the validity of a table column setfor use by a service provider in a subsequent call to theIMAPITable::SetColumns method. FBadEntryList,MAPI32.DLL,NM,1, validates a list of MAPI entry identifiers. FBadProp,MAPI32.DLL,NM,1, validates a specified property. FBadPropTag,MAPI32.DLL,NM,1, validates a specified property tag. FBadRestriction,MAPI32.DLL,NM,1, validates a restriction used to limit a table view. FBadRglpNameID,MAPI32.DLL,NM,2, validates an array of structures that describe named properties and verifies their allocation. FBadRglpsz,MAPI32.DLL,AW,2 validates all strings in an array of Unicode strings. FBadRow,MAPI32.DLL,NM,1, validates a row in a table. FBadRowSet,MAPI32.DLL,NM,1, validates all table rows included in a set of table rows. FBadSortOrderSet,MAPI32.DLL,NM,1, validates a sort order set by verifying its memory allocation. FBinFromHex,MAPI32.DLL,NM,2 converts a string representation of a hexadecimal number to binary data. FEqualNames,MAPI32.DLL,NM,2, determines whether two MAPI named properties are the same. FileTimeToDosDateTime,KERNEL32.DLL,NM,3, converts a 64-bit file time to MS-DOS date and time values. FileTimeToLocalFileTime,KERNEL32.DLL,NM,2, converts a file time based on the Coordinated Universal Time (UTC) to a local file time. FileTimeToSystemTime,KERNEL32.DLL,NM,2, converts a 64-bit file time to system time format. FillConsoleOutputAttribute,KERNEL32.DLL,NM,5 sets the text and background color attributes for a specified number of charactercells, beginning at the specified coordinates in a screen buffer. FillConsoleOutputCharacter,KERNEL32.DLL,AW,5 writes a character to the screen buffer a specified number of times, beginning at the specified coordinates. FillPath,GDI32.DLL,NM,1 closes any open figures in the current pathand fills the path?s interior by using the current brush andpolygon-filling mode. FillRect,USER32.DLL,NM,3, fills a rectangle by using the specified brush. FillRgn,GDI32.DLL,NM,3, fills a region by using the specified brush. FindAtom,KERNEL32.DLL,AW,1 searches the local atom table for thespecified character string and retrieves the atom associated withthat string. FindClose,KERNEL32.DLL,NM,1, closes the specified search handle. FindCloseChangeNotification,KERNEL32.DLL,NM,1, stops change notification handle monitoring. FindClosePrinterChangeNotification,WINMM.DLL,NM,1 closes a change notification object created by calling the FindFirstPrinterChangeNotification function. FindCloseUrlCache,WININET.DLL,NM,1,Closes the specified cache enumeration handle. FindDebugInfoFile,IMAGEHLP.DLL,NM,3, locates a debug (.dbg) file. FindExecutable,SHELL32.DLL,AW,3, retrieves the name and handle to the executable (. FindExecutableImage,IMAGEHLP.DLL,NM,3, locates an executable file. FindFirstChangeNotification,KERNEL32.DLL,AW,3 creates a change notification handle and sets up initial change notification filter conditions. FindFirstFile,KERNEL32.DLL,AW,2, searches a directory for a file whose name matches the specified filename. FindFirstFileEx,KERNEL32.DLL,AW,6, searches a directory for a file whose name and attributes match those specified in the function call. FindFirstFreeAce,ADVAPI32.DLL,NM,2, retrieves a pointer to the first free byte in an accesscontrol list (ACL). FindFirstPrinterChangeNotification,WINMM.DLL,NM,3, creates a change notification object and returns a handle to the object. FindFirstUrlCacheEntry,WININET.DLL,AW,3,Begins the enumeration of the Internet cache. FindFirstUrlCacheEntryEx,WININET.DLL,AW,10,Starts a filtered enumeration of the Internet cache. FindFirstUrlCacheGroup,WININET.DLL,NM,6,Initiates the enumeration of the cache groups in the Internet cache. FindMediaType,URLMON.DLL,NM,2,Class Retrieves the CLSID for the specified media type. FindMediaTypeClass,URLMON.DLL,NM,4, Retrieves the CLSID for the specified media type. FindNextChangeNotification,KERNEL32.DLL,NM,1 requests that the operating system signal a change notification handle the next time it detects an appropriate change. FindNextFile,KERNEL32.DLL,AW,2, continues a file search from a previous call to the FindFirstFile function. FindNextPrinterChangeNotification,WINMM.DLL,NM,3 retrieves information about the most recent change notification for a change notification object associated with a printer or print server. FindNextUrlCacheEntry,WININET.DLL,AW,3,Retrieves the next entry in the Internet cache. FindNextUrlCacheEntryEx,WININET.DLL,AW,6,Finds the next cache entry in a cache enumeration started by the FindFirstUrlCacheEntryEx function. FindNextUrlCacheGroup,WININET.DLL,NM,3,Retrieves the next cache group in a cache group enumeration started by FindFirstUrlCacheGroup. FindResource,KERNEL32.DLL,AW,3 determines the location of a resource with the specified type and name in the specified module. FindResourceEx,KERNEL32.DLL,AW,4 determines the location of the resourcewith the specified type, name, and language in the specifiedmodule. FindText,COMDLG32.DLL,AW,1 creates a system-defined modeless dialog boxthat lets the user specify a string to search for and options touse when searching for text in a document. FindWindow,USER32.DLL,AW,2 retrieves the handle to the top-levelwindow whose class name and window name match the specifiedstrings. FindWindowEx,USER32.DLL,AW,4 retrieves the handle to a window whose class name and window name match the specified strings. FixBrushOrgEx,GDI32.DLL,NM,4, is not implemented in the Win32 API. FlashWindow,USER32.DLL,NM,2, flashes the window only once; for repeated flashing, the application should create a system timer. FlatSB_EnableScrollBar,COMCTL32.DLL,NM,3,Enables or disables one or both flat scroll bar direction buttons. FlatSB_GetScrollInfo,COMCTL32.DLL,NM,3,Retrieves the information for a flat scroll bar. FlatSB_GetScrollPos,COMCTL32.DLL,NM,2,Retrieves the thumb position in a flat scroll bar. FlatSB_GetScrollProp,COMCTL32.DLL,NM,3,Retrieves the properties for a flat scroll bar. FlatSB_GetScrollRange,COMCTL32.DLL,NM,4,Retrieves the scroll range for a flat scroll bar. FlatSB_SetScrollInfo,COMCTL32.DLL,NM,4,Sets the information for a flat scroll bar. FlatSB_SetScrollPos,COMCTL32.DLL,NM,4,Sets the current position of the thumb in a flat scroll bar. FlatSB_SetScrollProp,COMCTL32.DLL,NM,4,Sets the properties for a flat scroll bar. FlatSB_SetScrollRange,COMCTL32.DLL,NM,5,Sets the scroll range of a flat scroll bar. FlatSB_ShowScrollBar,COMCTL32.DLL,NM,3,Shows or hides a flat scroll bar. FlattenPath,GDI32.DLL,NM,1 transforms any curves in the path that isselected into the current device context (DC), turning each curveinto a sequence of lines. FloodFill,GDI32.DLL,NM,4, fills an area of the display surface with the current brush. FlushConsoleInputBuffer,KERNEL32.DLL,NM,1 flushes the console input buffer. All input records currently in the input buffer are discarded. FlushFileBuffers,KERNEL32.DLL,NM,1, clears the buffers for the specified file and causes all buffered data to be written to the file. FlushInstructionCache,KERNEL32.DLL,NM,3, flushes the instruction cache for the specified process. FlushViewOfFile,KERNEL32.DLL,NM,2, writes to the disk a byte range within a mapped view of a file. FmtIdToPropStgName,IPROP.DLL,NM,2,Converts a property set format identifier (FMTID) to its storage or stream name. FoldString,KERNEL32.DLL,AW,5, maps one string to another, performing a specified transformation option. FormatMessage,KERNEL32.DLL,AW,7, formats a message string. FPropCompareProp,MAPI32.DLL,NM,3, compares two property values using a binary relational operator. FPropContainsProp,MAPI32.DLL,NM,3 compares two property values,generally strings or binary arrays, to see if one contains theother. FPropExists,MAPI32.DLL,NM,2 searches for a given property tag in anIMAPIProp interface or an interface derived from IMAPIProp, such asIMessage or IMAPIFolder. FrameRect,USER32.DLL,NM,3, draws a border around the specified rectangle by using the specified brush. FrameRgn,GDI32.DLL,NM,5, draws a border around the specified region by using the specified brush. FreeConsole,KERNEL32.DLL,NM,0, detaches the calling process from its console. FreeContextBuffer,SECUR32.DLL,NM,1,Enables callers of security package functions to free a memory buffer that was allocated by the security package as a result of calls to InitializeSecurityContext (General) and AcceptSecurityContext (General). FreeCredentialsHandle,SECUR32.DLL,NM,1,Notifies the security system that the credentials are no longer needed. An application calls this function to free the credential handle acquired in the call to the AcquireCredentialsHandle (General) function. FreeDDElParam,USER32.DLL,NM,2, frees the memory specified by the lParam parameter of a posted DDE message. FreeEnvironmentStrings,KERNEL32.DLL,AW,1 frees a block of environment strings. FreeGPOList,USERENV.DLL,AW,1, frees the specified linked list of GPOs. FreeLibrary,KERNEL32.DLL,NM,1, decrements the reference count of the loaded dynamic-link library (DLL) module. FreeLibraryAndExitThread,KERNEL32.DLL,NM,2 decrements the reference count of a loaded dynamic-link library (DLL) by one, and then calls ExitThread to terminate the calling thread. FreePadrlist,MAPI32.DLL,NM,1 destroys an ADRLIST structure and freesassociated memory, including memory allocated for all member arraysand structures. FreePrinterNotifyInfo,WINMM.DLL,NM,1 frees a system-allocated bufferthat was returned by the FindNextPrinterChangeNotificationfunction. FreePropVariantArray,IPROP.DLL,NM,2, calls PropVariantClear on each of the PROPVARIANT structures in the rgvars array to make the value zero for each of the members of the array. FreePropVariantArray,OLE32.DLL,NM,2, calls PropVariantClear on each of the PROPVARIANT structures in the rgvars array to make the value zero for each of the members of the array. FreeProws,MAPI32.DLL,NM,1 destroys an SRowSet structure and freesassociated memory, including memory allocated for all member arraysand structures. FreeResource,KERNEL32.DLL,NM,1, is obsolete. FreeSid,ADVAPI32.DLL,NM,1, frees a security identifier (SID) previously allocated by using the AllocateAndInitializeSid function. FtAddFt,MAPI32.DLL,NM,4, adds one unsigned 64-bit integer to another. FtgRegisterIdleRoutine,MAPI32.DLL,NM,5, adds a FNIDLE - based idle routine to the MAPI system. FtMulDw,MAPI32.DLL,NM,3, multiplies an unsigned 64-bit integer by an unsigned 32-bit integer. FtMulDwDw,MAPI32.DLL,NM,2, multiplies one unsigned 32-bit integer by another. FtNegFt,MAPI32.DLL,NM,2, computes the two?s complement of an unsigned 64-bit integer. FtpCommand,WININET.DLL,AW,6,Sends commands directly to an FTP server. FtpCreateDirectory,WININET.DLL,AW,2,Creates a new directory on the FTP server. FtpDeleteFile,WININET.DLL,AW,2,Deletes a file stored on the FTP server. FtpFindFirstFile,WININET.DLL,AW,5,Searches the specified directory of the given FTP session. File and directory entries are returned to the application in the WIN32_FIND_DATA structure. FtpGetCurrentDirectory,WININET.DLL,AW,3,Retrieves the current directory for the specified FTP session. FtpGetFile,WININET.DLL,AW,7,Retrieves a file from the FTP server and stores it under the specified file name, creating a new local file in the process. FtpGetFileEx,WININET.DLL,NM,7,retrieves a file from the FTP server and stores it under the specified file name, creating a new local file in the process. FtpGetFileSize,WININET.DLL,NM,2,Retrieves the file size of the requested FTP resource. FtpOpenFile,WININET.DLL,AW,5,Initiates access to a remote file on an FTP server for reading or writing. FtpPutFile,WININET.DLL,AW,5,Stores a file on the FTP server. FtpPutFileEx,WININET.DLL,NM,5,This function stores a file on the FTP server. FtpRemoveDirectory,WININET.DLL,AW,2,Removes the specified directory on the FTP server. FtpRenameFile,WININET.DLL,AW,3,Renames a file stored on the FTP server. FtpSetCurrentDirectory,WININET.DLL,AW,2,Changes to a different working directory on the FTP server. FtSubFt,MAPI32.DLL,NM,4, subtracts one unsigned 64-bit integer from another. GdiComment,GDI32.DLL,NM,3, copies a comment from a buffer into a specified enhanced format metafile. GdiFlush,GDI32.DLL,NM,0, flushes the calling thread?s current batch. GdiGetBatchLimit,GDI32.DLL,NM,0, returns the batch limit. GdiSetBatchLimit,GDI32.DLL,NM,1, sets the maximum number of functions that can be accumulated in the calling thread?s current batch. GenerateConsoleCtrlEvent,KERNEL32.DLL,NM,2 sends a specified signal to aconsole process group that shares the console associated with thecalling process. GenerateCopyFilePaths,MSCMS.DLL,NM,9,graphics, GraphicsDrivers, Reference, GenerateCopyFilePaths GetAcceptExSockaddrs,MSWSOCK.DLL,NM,8, parses the data obtained from a call to the AcceptEx function and passes the local and remote addresses to a SOCKADDR structure. GetAcceptExSockaddrs,WSOCK32.DLL,NM,8, parses the data obtained from a call to the AcceptEx function and passes the local and remote addresses to a SOCKADDR structure. GetAclInformation,ADVAPI32.DLL,NM,4, retrieves information about an access-control list (ACL). GetACP,KERNEL32.DLL,NM,0, retrieves the current ANSI code-page identifier for the system. GetActiveObject,OLEAUT32.DLL,NM,3,Retrieves a pointer to a running object that has been registered with OLE. 129 GetActiveWindow,USER32.DLL,NM,0, retrieves the window handle to the active window associated with the thread that calls the function. GetAddressByName,MSWSOCK.DLL,AW,10,Important is a Microsoft-specific extension to the Windows Sockets 1. GetAddressByName,WSOCK32.DLL,AW,10,Important is a Microsoft-specific extension to the Windows Sockets 1. GetAllUsersProfileDirectory,USERENV.DLL,AW,2, retrieves the path to the root of the All Users profile. GetAltMonthNames,OLEAUT32.DLL,NM,2,Retrieves the secondary (altername) month names. GetAppliedGPOList,USERENV.DLL,AW,5, retrieves the list of GPOs applied for the specified user or computer and the specified extension. GetArcDirection,GDI32.DLL,NM,1, returns the current arc direction for the specified device context.. GetAspectRatioFilterEx,GDI32.DLL,NM,2, retrieves the setting for the current aspect-ratio filter. GetAsyncKeyState,USER32.DLL,NM,1 determines whether a key is up ordown at the time the function is called, and whether the key waspressed after a previous call to GetAsyncKeyState. GetAtomName,KERNEL32.DLL,AW,3, retrieves a copy of the character string associated with the specified local atom. GetAttribIMsgOnIStg,MAPI32.DLL,NM,3, retrieves attributes of properties on an IMessage object supplied by the OpenIMsgOnIStg function. GetAuditedPermissionsFromAcl,ADVAPI32.DLL,AW,4, returns the audited access rights for a specified trustee. GetBinaryType,KERNEL32.DLL,AW,2, determines whether a file is executable, and if so, what type of executable file it is. GetBitmapBits,GDI32.DLL,NM,3, is obsolete. GetBitmapDimensionEx,GDI32.DLL,NM,2, retrieves the dimensions of a SetBitmapDimensionEx function. GetBkColor,GDI32.DLL,NM,1, returns the current background color for the specified device context. GetBkMode,GDI32.DLL,NM,1, returns the current background mix mode for a specified device context. GetBoundsRect,GDI32.DLL,NM,3 obtains the current accumulated bounding rectangle for a specified device context. GetBrushOrgEx,GDI32.DLL,NM,2, retrieves the current brush origin for the specified device context. GetCapture,USER32.DLL,NM,0, retrieves the handle of the window (if any) that has captured the mouse. GetCaretBlinkTime,USER32.DLL,NM,0, returns the elapsed time, in milliseconds, required to invert the caret?s pixels. GetCaretPos,USER32.DLL,NM,1, copies the caret?s position, in client coordinates, to the specified POINT structure. GetCharABCWidths,GDI32.DLL,AW,4 retrieves the widths, in logicalunits, of consecutive characters in a given range from the currentTrueType font. GetCharABCWidthsFloat,GDI32.DLL,AW,4 retrieves the widths, in logicalunits, of consecutive characters in a specified range from thecurrent font. GetCharacterPlacement,GDI32.DLL,AW,6 retrieves information about a character string, such as character widths, caret positioning, ordering within the string, and glyph rendering. GetCharWidth,GDI32.DLL,AW,4 retrieves the widths, in logicalcoordinates, of consecutive characters in a specified range fromthe current font. GetCharWidth32,GDI32.DLL,AW,4 retrieves the widths, in logicalcoordinates, of consecutive characters in a specified range fromthe current font. GetCharWidthFloat,GDI32.DLL,AW,4, retrieves the fractional widths of consecutive characters in a specified range from the current font. GetClassFile,OLE32.DLL,NM,2,OrMime Retrieves the CLSID of the object to instantiate for the specified file. GetClassFileOrMime,URLMON.DLL,NM,7, Retrieves the CLSID of the object to instantiate for the specified file. GetClassInfo,USER32.DLL,AW,3, retrieves information about a window class. GetClassInfoEx,USER32.DLL,AW,3 retrieves information about a windowclass, including the handle of the small icon associated with thewindow class. GetClassLong,USER32.DLL,AW,2 retrieves the specified 32-bit (long)value from the WNDCLASSEX structure associated with the specifiedwindow. GetClassName,USER32.DLL,AW,3, retrieves the name of the class to which the specified window belongs. GetClassURL,URLMON.DLL,NM,2, GetClassURL Function Not currently implemented. GetClassWord,USER32.DLL,NM,2 retrieves the 16-bit (word) value at thespecified offset into the extra class memory for the window classto which the specified window belongs. GetClientRect,USER32.DLL,NM,2 retrieves the coordinates of a window?s client area. GetClipboardData,USER32.DLL,NM,1, retrieves data from the clipboard in a specified format. GetClipboardFormatName,USER32.DLL,AW,3, retrieves from the clipboard the name of the specified registered format. GetClipboardOwner,USER32.DLL,NM,0, retrieves the window handle of the current owner of the clipboard. GetClipboardSequenceNumber,USER32.DLL,NM,0, returns the clipboard sequence number for the current window station. GetClipboardViewer,USER32.DLL,NM,0, retrieves the handle of the first window in the clipboard viewer chain. GetClipBox,GDI32.DLL,NM,2 retrieves the dimensions of the tightestbounding rectangle that can be drawn around the current visiblearea on the device. GetClipCursor,USER32.DLL,NM,1, retrieves the screen coordinates of the rectangular area to which the cursor is confined. GetClipRgn,GDI32.DLL,NM,2 retrieves a handle identifying the currentapplication-defined clipping region for the specified devicecontext. GetCMMInfo,MSCMS.DLL,NM,2, retrieves various information about the color management module (CMM) that created the specified color transform. GetColorAdjustment,GDI32.DLL,NM,2 retrieves the color adjustmentvalues for the specified device context. GetColorDirectory,MSCMS.DLL,AW,3, retrieves the path of the Windows COLOR directory on a specified machine. GetColorProfileElement,MSCMS.DLL,NM,6, copies data from a specified tagged profile element of a specified color profile into a buffer. GetColorProfileElementTag,MSCMS.DLL,NM,3, retrieves the tag name specified by dwIndex in the tag table of a given color profile, where dwIndex is a one-based index into that table. GetColorProfileFromHandle,MSCMS.DLL,NM,3,Given a handle to an open color profile, the GetColorProfileFromHandle function will copy the contents of the profile into a buffer supplied by the application. GetColorProfileHeader,MSCMS.DLL,NM,2, retrieves the header of a color profile. GetCommandLine,KERNEL32.DLL,AW,0 returns a pointer to the command-line string for the current process. GetCommConfig,KERNEL32.DLL,NM,3 gets the current configuration of a communications device. GetCommMask,KERNEL32.DLL,NM,2, retrieves the value of the event mask for a specified communications device. GetCommModemStatus,KERNEL32.DLL,NM,2, retrieves modem control-register values. GetCommProperties,KERNEL32.DLL,NM,2 fills a buffer with informationabout the communications properties for a specified communicationsdevice. GetCommState,KERNEL32.DLL,NM,2 fills in a device-control block (a DCBstructure) with the current control settings for a specifiedcommunications device. GetCommTimeouts,KERNEL32.DLL,NM,2, retrieves the time-out parameters for all read and write operations on a specified communications device. GetCompressedFileSize,KERNEL32.DLL,AW,2, obtains the compressed size of a file. GetComputerName,KERNEL32.DLL,AW,2, retrieves the computer name of the current system. GetComputerObjectName,SECUR32.DLL,AW,3, retrieves the local computer's name in a specified format. GetConsoleCP,KERNEL32.DLL,NM,0 Windows NT: returns the identity of theinput code page used by the console associated with the callingprocess. GetConsoleCursorInfo,KERNEL32.DLL,NM,2 retrieves information about thesize and visibility of the cursor for the specified console screenbuffer. GetConsoleMode,KERNEL32.DLL,NM,2 reports the current input mode of aconsole?s input buffer or the current output mode of a consolescreen buffer. GetConsoleOutputCP,KERNEL32.DLL,NM,0 Windows NT: returns the identity ofthe output code page used by the console associated with thecalling process. GetConsoleScreenBufferInfo,KERNEL32.DLL,NM,2, retrieves information about the specified console screen buffer. GetConsoleTitle,KERNEL32.DLL,AW,2, retrieves the title bar string for the current console window. GetConvertStg,OLE32.DLL,NM,1, returns the current value of the convert bit for the specified storage object. GetCountColorProfileElements,MSCMS.DLL,NM,2, retrieves the number of tagged elements in a given color profile. GetCPInfo,KERNEL32.DLL,NM,2, retrieves information about any valid installed or available code page. GetCurrencyFormat,KERNEL32.DLL,AW,6, formats a number string as a currency string for a specified locale. GetCurrentDirectory,KERNEL32.DLL,AW,2 retrieves the current directory for the current process. GetCurrentHwProfile,ADVAPI32.DLL,AW,1, retrieves the display name and globally unique identifier (GUID) string for the hardware profile. GetCurrentObject,GDI32.DLL,NM,2, obtains a handle to a device context? s currently selected object of a specified type. GetCurrentPositionEx,GDI32.DLL,NM,2, retrieves the current position in logical coordinates. GetCurrentProcess,KERNEL32.DLL,NM,0, returns a pseudohandle for the current process. GetCurrentProcessId,KERNEL32.DLL,NM,0, returns the process identifier of the calling process. GetCurrentThread,KERNEL32.DLL,NM,0, returns a pseudohandle for the current thread. GetCurrentThreadId,KERNEL32.DLL,NM,0, returns the thread identifier of the calling thread. GetCursor,USER32.DLL,NM,0, retrieves the handle of the current cursor. GetCursorPos,USER32.DLL,NM,1, retrieves the cursor?s position, in screen coordinates. GetDateFormat,KERNEL32.DLL,AW,6 formats a date as a date string for a specified locale. GetDC,USER32.DLL,NM,1, retrieves a handle of a display device context (DC) for the client area of the specified window. GetDCEx,USER32.DLL,NM,3, retrieves the handle of a display device (DC) context for the specified window. GetDCOrgEx,GDI32.DLL,NM,2, obtains the final translation origin for a specified device context (DC). GetDefaultCommConfig,KERNEL32.DLL,AW,3, gets the default configuration for a communications device. GetDefaultUserProfileDirectory,USERENV.DLL,AW,2, retrieves the path to the root of the Default User profile. GetDesktopWindow,USER32.DLL,NM,0, returns the handle of the Windows desktop window. GetDeviceCaps,GDI32.DLL,NM,2, retrieves device-specific information about a specified device. GetDeviceDriverBaseName,PSAPI.DLL,AW,3, retrieves the base name of the specified device driver. GetDeviceDriverFileName,PSAPI.DLL,AW,3, retrieves the fully qualified path for the specified device driver. GetDialogBaseUnits,USER32.DLL,NM,0 returns the system's dialog baseunits, which are the average width and height of characters in thesystem font. GetDIBColorTable,GDI32.DLL,NM,4 retrieves RGB (red, green, blue) color values from a range of entries in the color table of the DIB section bitmap that is currently selected into a specified device context. GetDIBits,GDI32.DLL,NM,7, retrieves the bits of the specified bitmap and copies them into a buffer using the specified format. GetDiskFreeSpace,KERNEL32.DLL,AW,5, retrieves information about the specified disk, including the amount of free space on the disk. GetDiskFreeSpaceEx,KERNEL32.DLL,AW,4, lets you avoid the arithmetic required by the GetDiskFreeSpace function. GetDlgCtrlID,USER32.DLL,NM,1, returns the identifier of the specified control. GetDlgItem,USER32.DLL,NM,2, retrieves the handle of a control in the specified dialog box. GetDlgItemInt,USER32.DLL,NM,4, translates the text of a specified control in a dialog box into an integer value. GetDlgItemText,USER32.DLL,AW,4, retrieves the title or text associated with a control in a dialog box. GetDoubleClickTime,USER32.DLL,NM,0, retrieves the current double-click time for the mouse. GetDriveType,KERNEL32.DLL,AW,1, determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive. GetEffectiveClientRect,COMCTL32.DLL,NM,3, calculates the dimensions of a rectangle in the client area. GetEffectiveRightsFromAcl,ADVAPI32.DLL,AW,3, retrieves the effective access rights that an ACL allows for a specified trustee. GetEnhMetaFile,GDI32.DLL,AW,1, creates a handle that identifies the enhanced-format metafile stored in the specified file. GetEnhMetaFileBits,GDI32.DLL,NM,3, retrieves the contents of the specified enhanced-format metafile and copies them into a buffer. GetEnhMetaFileDescription,GDI32.DLL,AW,3 retrieves an optional textdescription from an enhanced-format metafile and copies the stringto the specified buffer. GetEnhMetaFileHeader,GDI32.DLL,NM,3 retrieves the record containing the header for the specified enhanced-format metafile. GetEnhMetaFilePaletteEntries,GDI32.DLL,NM,3, retrieves optional palette entries from the specified enhanced metafile. GetEnvironmentStrings,KERNEL32.DLL,AW,0, returns the address of the environment block for the current process. GetEnvironmentVariable,KERNEL32.DLL,AW,3 retrieves the value of thespecified variable from the environment block of the callingprocess. GetErrorInfo,OLEAUT32.DLL,NM,2,Obtains the error information pointer set by the previous call to SetErrorInfo in the current logical thread. GetExitCodeProcess,KERNEL32.DLL,NM,2 retrieves the termination status ofthe specified process. GetExitCodeThread,KERNEL32.DLL,NM,2, retrieves the termination status of the specified thread. GetExpandedName,LZ32.DLL,AW,2 retrieves the original name of acompressed file, if the file was compressed by using the MicrosoftFile Compression Utility (COMPRESS. GetExplicitEntriesFromAcl,ADVAPI32.DLL,AW,3 retrieves an array ofEXPLICIT_ACCESS structures that describe the access-control entries(ACEs) in an access-control list (ACL). GetFileAttributes,KERNEL32.DLL,AW,1, returns attributes for a specified file or directory. GetFileAttributesEx,KERNEL32.DLL,AW,3, obtains attribute information about a specified file or directory. 130 GetFileInformationByHandle,KERNEL32.DLL,NM,2, retrieves information about a specified file. GetFileSecurity,ADVAPI32.DLL,AW,5, obtains specified information about the security of a file or directory. GetFileSize,KERNEL32.DLL,NM,2, retrieves the size, in bytes, of the specified file. GetFileTime,KERNEL32.DLL,NM,4, retrieves the date and time that a file was created, last accessed, and last modified. GetFileTitle,COMDLG32.DLL,AW,3, returns the name of the file identified by the lpszFile parameter. GetFileType,KERNEL32.DLL,NM,1 returns the type of the specified file. GetFileVersionInfo,VERSION.DLL,AW,4, returns version information about a specified file. GetFileVersionInfoSize,VERSION.DLL,AW,2 determines whether operating system can obtain version information about a specifiedfile. GetFocus,USER32.DLL,NM,0 retrieves the handle of the window that hasthe keyboard focus, if the window is associated with the callingthread?s message queue. GetFontData,GDI32.DLL,NM,5, retrieves font metric data for a TrueType font. GetFontLanguageInfo,GDI32.DLL,NM,1, returns information about the currently selected font for the specified display context. GetForegroundWindow,USER32.DLL,NM,0 returns the handle of theforeground window (the window with which the user is currentlyworking). GetForm,WINMM.DLL,AW,6, initializes a FORM_INFO_1 structure with data describing the specified form for a printer. GetFullPathName,KERNEL32.DLL,AW,4, retrieves the full path and filename of a specified file. GetGlyphOutline,GDI32.DLL,AW,7 retrieves the outline or bitmap for acharacter in the TrueType font that is selected into the specifieddevice context. GetGPOList,USERENV.DLL,AW,6, retrieves the list of GPOs for the specified user or computer. GetGraphicsMode,GDI32.DLL,NM,1, retrieves the current graphics mode for the specified device context. GetGuiResources,USER32.DLL,NM,2 returns the count of handles to graphical user interface (GUI) objects in use by the specified process. GetHandleInformation,KERNEL32.DLL,NM,2, obtains information about certain properties of an object handle. GetHGlobalFromILockBytes,OLE32.DLL,NM,2, retrieves a global memory handle to a byte array object created using the CreateILockBytesOnHGlobal function. GetHGlobalFromStream,OLE32.DLL,NM,2, This function retrieves the global memory handle to a stream that was created through a call to the CreateStreamOnHGlobal function. gethostbyaddr,WS2_32.DLL,NM,3 retrieves the host information corresponding to a network address. gethostbyaddr,WSOCK32.DLL,NM,3 retrieves the hostinformation corresponding to a network address. gethostbyname,WS2_32.DLL,NM,1, retrieves host information corresponding to a host name from a host database.Note The gethostbyname function has been deprecated by the introduction of the getaddrinfo function. gethostbyname,WSOCK32.DLL,NM,1, retrieves host information corresponding to a host name from a host database.Note The gethostbyname function has been deprecated by the introduction of the getaddrinfo function. gethostname,WS2_32.DLL,NM,2, retrieves the standard host name for the local computer. gethostname,WSOCK32.DLL,NM,2, retrieves the standard host name for the local computer. GetIconInfo,USER32.DLL,NM,2, retrieves information about the specified icon or cursor. GetImageConfigInformation,IMAGEHLP.DLL,NM,2, locates and returns the load configuration data of an image. GetImageUnusedHeaderBytes,IMAGEHLP.DLL,NM,2, returns the offset and size of the part of the PE header that is currently unused. GetInputState,USER32.DLL,NM,0, determines whether there are mouse- button or keyboard messages in the calling thread?s message queue. GetJob,WINMM.DLL,AW,6, retrieves print-job data for the specified printer. GetKBCodePage,USER32.DLL,NM,0 returns the current Windows code page. GetKernelObjectSecurity,ADVAPI32.DLL,NM,5, retrieves a copy of the security descriptor protecting a kernel object. GetKerningPairs,GDI32.DLL,AW,3, retrieves the character-kerning pairs for the currently selected font for the specified device context. GetKeyboardLayout,USER32.DLL,NM,1, retrieves the active keyboard layout for a specified thread. GetKeyboardLayoutList,USER32.DLL,NM,2 retrieves the keyboard layouthandles corresponding to the current set of input locales in thesystem. GetKeyboardLayoutName,USER32.DLL,AW,1, retrieves the name of the active keyboard layout. GetKeyboardState,USER32.DLL,NM,1 copies the status of the 256 virtual keys to the specified buffer. GetKeyboardType,USER32.DLL,NM,1, retrieves information about the current keyboard. GetKeyNameText,USER32.DLL,AW,3, retrieves a string that represents the name of a key. GetKeyState,USER32.DLL,NM,1, retrieves the status of the specified virtual key. GetLargestConsoleWindowSize,KERNEL32.DLL,NM,1 returns the size of thelargest possible console window, based on the current font and thesize of the display. GetLastActivePopup,USER32.DLL,NM,1, determines which pop-up window owned by the specified window was most recently active. GetLastError,KERNEL32.DLL,NM,0, returns the calling thread?s last-error code value. GetLengthSid,ADVAPI32.DLL,NM,1, returns the length, in bytes, of a valid SID structure. GetLocaleInfo,KERNEL32.DLL,AW,4, always retrieves information in text format. GetLocalTime,KERNEL32.DLL,NM,1 retrieves the current local date and time. GetLogicalDrives,KERNEL32.DLL,NM,0, returns a bitmask representing the currently available disk drives. GetLogicalDriveStrings,KERNEL32.DLL,AW,2, fills a buffer with strings that specify valid drives in the system. GetMailslotInfo,KERNEL32.DLL,NM,5, retrieves information about the specified mailslot. GetMapMode,GDI32.DLL,NM,1 retrieves the current mapping mode. GetMappedFileName,PSAPI.DLL,AW,4, checks if the specified address is within a memorymapped file in the address space of the specified process. If so, the function returns the name of the memory-mapped file. GetMenu,USER32.DLL,NM,1, retrieves the handle of the menu assigned to the given window. GetMenuCheckMarkDimensions,USER32.DLL,NM,0, returns the dimensions of the default check mark bitmap. GetMenuContextHelpId,USER32.DLL,NM,1, retrieves the help context identifier associated with the specified menu. GetMenuDefaultItem,USER32.DLL,NM,3 determines the default menu item on the specified menu. GetMenuItemCount,USER32.DLL,NM,1, determines the number of items in the specified menu. GetMenuItemID,USER32.DLL,NM,2, retrieves the menu item identifier of a menu item located at the specified position in a menu. GetMenuItemInfo,USER32.DLL,AW,4, retrieves information about a menu item. GetMenuItemRect,USER32.DLL,NM,4, retrieves the bounding rectangle for the specified menu item. GetMenuState,USER32.DLL,NM,3 retrieves the menu flags associated with the specified menu item. GetMenuString,USER32.DLL,AW,5, copies the text string of the specified menu item into the specified buffer. GetMessage,USER32.DLL,AW,4, retrieves a message from the calling thread?s message queue and places it in the specified structure. GetMessageExtraInfo,USER32.DLL,NM,0, gets the extra message information for the current thread. GetMessagePos,USER32.DLL,NM,0, returns a long value that gives the cursor position in screen coordinates. GetMessageTime,USER32.DLL,NM,0 returns the message time for the lastmessage retrieved by the GetMessage function from the currentthread?s message queue. GetMetaFile,GDI32.DLL,AW,1, creates a handle that identifies the given Windows-format metafile. GetMetaFileBitsEx,GDI32.DLL,NM,3, retrieves the contents of a Windows- format metafile and copies them into the specified buffer. GetMetaRgn,GDI32.DLL,NM,2, retrieves the current metaregion for the specified device context. GetMiterLimit,GDI32.DLL,NM,2, returns the miter limit for the specified device context. GetModuleBaseName,PSAPI.DLL,AW,4, retrieves the base name of the specified module. GetModuleFileName,KERNEL32.DLL,AW,3, retrieves the full path and filename for the executable file containing the specified module. GetModuleFileNameEx,PSAPI.DLL,AW,4, retrieves the fully-qualified path for the file containing the specified module. GetModuleHandle,KERNEL32.DLL,AW,1 returns a module handle for thespecified module if the file has been mapped into the address spaceof the calling process. GetModuleInformation,PSAPI.DLL,NM,4, retrieves information about the specified module in the MODULEINFO structure. GetMonitorInfo,USER32.DLL,AW,2, lets you obtain information about a display monitor. GetMultipleTrustee,ADVAPI32.DLL,AW,1, is provided for future use. GetMultipleTrusteeOperation,ADVAPI32.DLL,AW,1, is provided for future use. GetNameByType,MSWSOCK.DLL,AW,3, obtains the name of a network service. GetNameByType,WSOCK32.DLL,AW,3, obtains the name of a network service. GetNamedPipeHandleState,KERNEL32.DLL,AW,7 GetNamedPipeHandleStatespecified named pipe. GetNamedPipeInfo,KERNEL32.DLL,NM,5, retrieves information about the specified named pipe. GetNamedSecurityInfo,ADVAPI32.DLL,AW,8, retrieves a copy of the security descriptor for an object specified by name. GetNearestColor,GDI32.DLL,NM,2 returns a color value identifying acolor from the system palette that will be displayed when thespecified color value is used. GetNearestPaletteIndex,GDI32.DLL,NM,2 retrieves the index for theentry in the specified logical palette most closely matching aspecified color value. GetNextDlgGroupItem,USER32.DLL,NM,3 retrieves the handle of the firstcontrol in a group of controls that precedes (or follows) thespecified control in a dialog box. GetNextDlgTabItem,USER32.DLL,NM,3 retrieves the handle of the firstcontrol that has the WS_TABSTOP style that precedes (or follows)the specified control. GetNtmsMediaPoolName,NTMSAPI.DLL,AW,4, retrieves the specified media pool's full name hierarchy. GetNtmsObjectAttribute,NTMSAPI.DLL,AW,6, retrieves the extended attribute (named private data) from the specified RSM object. GetNtmsObjectInformation,NTMSAPI.DLL,AW,3, returns an object's information structure for the specified object. GetNtmsObjectSecurity,NTMSAPI.DLL,NM,7, reads the security descriptor for the specified RSM object. GetNtmsRequestOrder,NTMSAPI.DLL,NM,3, gets the order that the specified request will be processed in the library queue. GetNumberFormat,KERNEL32.DLL,AW,6, formats a number string as a number string customized for a specified locale. GetNumberOfConsoleInputEvents,KERNEL32.DLL,NM,2, retrieves the number of unread input records in the console?s input buffer. GetNumberOfConsoleMouseButtons,KERNEL32.DLL,NM,1, retrieves the number of buttons on the mouse used by the current console. GetNumberOfEventLogRecords,ADVAPI32.DLL,NM,2 retrieves the number of records in the specified event log. GetObject,GDI32.DLL,AW,3 obtains information about a specified graphics object. GetObjectType,GDI32.DLL,NM,1 identifies the type of the specified object. GetOEMCP,KERNEL32.DLL,NM,0, retrieves the current OEM code-page identifier for the system. GetOldestEventLogRecord,ADVAPI32.DLL,NM,2, retrieves the absolute record number of the oldest record in the specified event log. GetOpenClipboardWindow,USER32.DLL,NM,0, retrieves the handle of the window that currently has the clipboard open. GetOpenFileName,COMDLG32.DLL,AW,1 creates an Open common dialog box thatlets the user specify the drive, directory, and the name of a fileor set of files to open. GetOpenFileNamePreview,MSVFW32.DLL,AW,1, selects a file by using the Open dialog box. GetOutlineTextMetrics,GDI32.DLL,AW,3, retrieves text metrics for TrueType fonts. GetOverlappedResult,KERNEL32.DLL,NM,4 returns the results of anoverlapped operation on the specified file, named pipe, orcommunications device. GetPaletteEntries,GDI32.DLL,NM,4, retrieves a specified range of palette entries from the given logical palette. GetParent,USER32.DLL,NM,1, retrieves the handle of the specified child window?s parent window. GetPath,GDI32.DLL,NM,4 retrieves the coordinates defining theendpoints of lines and the control points of curves found in thepath that is selected into the specified device context. getpeername,WS2_32.DLL,NM,3 retrieves the name of thepeer to which a socket is connected. getpeername,WSOCK32.DLL,NM,3 retrieves the name of thepeer to which a socket is connected. GetPixel,GDI32.DLL,NM,3, retrieves the red, green, blue (RGB) color value of the pixel at the specified coordinates. GetPixelFormat,GDI32.DLL,NM,1, obtains the index of the currently selected pixel format of the specified device context. GetPolyFillMode,GDI32.DLL,NM,1, retrieves the current polygon fill mode. GetPrinter,WINMM.DLL,AW,5, retrieves information about a specified printer. GetPrinterData,WINMM.DLL,AW,6, retrieves printer-configuration data for the specified printer. GetPrinterDriver,WINMM.DLL,AW,6, retrieves driver data for the specified printer. GetPrinterDriverDirectory,WINMM.DLL,AW,6, retrieves the path of the printer-driver directory. GetPrintProcessorDirectory,WINMM.DLL,AW,6, retrieves the path for the print processor on the specified server. GetPriorityClass,KERNEL32.DLL,NM,1, returns the priority class for the specified process. GetPriorityClipboardFormat,USER32.DLL,NM,2, returns the first available clipboard format in the specified list. GetPrivateObjectSecurity,ADVAPI32.DLL,NM,5 retrieves information from a protectedserver object?s security descriptor. GetPrivateProfileInt,KERNEL32.DLL,AW,4 retrieves an integer associatedwith a key in the specified section of the given initializationfile. GetPrivateProfileSection,KERNEL32.DLL,AW,4, retrieves all of the keys and values for the specified section from an initialization file. GetPrivateProfileSectionNames,KERNEL32.DLL,AW,3, retrieves the names of all sections in an initialization file. GetPrivateProfileString,KERNEL32.DLL,AW,6, retrieves a string from the specified section in an initialization file. GetPrivateProfileStruct,KERNEL32.DLL,AW,5 retrieves the data associated with the specified key in the given section of an initialization file. 131 GetProcAddress,KERNEL32.DLL,NM,2, returns the address of the specified exported dynamic- GetStdHandle,KERNEL32.DLL,NM,1, returns a handle for the standard input, standard output, or standard error device. link library (DLL) function. GetProcessAffinityMask,KERNEL32.DLL,NM,3 obtains a process affinity mask for the specified GetStockObject,GDI32.DLL,NM,1, retrieves a handle to one of the predefined stock pens, brushes, fonts, or palettes. process and the system affinity mask for the system. GetStretchBltMode,GDI32.DLL,NM,1, retrieves the current stretching mode. GetProcessHeap,KERNEL32.DLL,NM,0, obtains a handle to the heap of the calling process. GetProcessMemoryInfo,PSAPI.DLL,NM,3, retrieves information about the memory usage of the GetStringType,KERNEL32.DLL,AW,5 returns character-type information for the characters in the specified source string. specified process in the PROCESS_MEMORY_COUNTERS structure. GetStringTypeEx,KERNEL32.DLL,AW,5, returns character-type information for the characters GetProcessPriorityBoost,KERNEL32.DLL,NM,2, returns the priority boost control state of the in the specified source string. specified process. GetSubMenu,USER32.DLL,NM,2, retrieves the handle of the drop-down menu or submenu GetProcessShutdownParameters,KERNEL32.DLL,NM,2, retrieves shutdown parameters for activated by the specified menu item. the currently calling process. GetProcessTimes,KERNEL32.DLL,NM,5, obtains timing information about a specified process. GetSysColor,USER32.DLL,NM,1, retrieves the current color of the specified display element. GetProcessVersion,KERNEL32.DLL,NM,1 obtains the major and minor versionnumbers of the GetSysColorBrush,USER32.DLL,NM,1, retrieves a handle identifying a logical brush that corresponds to the specified color index. Windows version on which a specified process expectsto run. GetSystemDefaultLangID,KERNEL32.DLL,NM,0, retrieves the system default language GetProcessWindowStation,USER32.DLL,NM,0, returns a handle of the window station identifier. associated with the calling process. GetSystemDefaultLCID,KERNEL32.DLL,NM,0, retrieves the system default locale identifier. GetProcessWorkingSetSize,KERNEL32.DLL,NM,3, obtains the minimum and maximum GetSystemDirectory,KERNEL32.DLL,AW,2, retrieves the path of the Windows system working set sizes of a specified process. directory. GetProfileInt,KERNEL32.DLL,AW,3, retrieves an integer from the specified key name in the GetSystemInfo,KERNEL32.DLL,NM,1, returns information about the current system. given section of the WIN. GetSystemMenu,USER32.DLL,NM,2 allows the application to access thewindow menu (also GetProfilesDirectory,USERENV.DLL,AW,2, retrieves the path to the root directory where all known as the System menu or the Control menu) forcopying and modifying. user profiles are stored. GetProfileSection,KERNEL32.DLL,AW,3, retrieves all of the keys and values for the specified GetSystemMetrics,USER32.DLL,NM,1, retrieves various system metrics and system configuration settings. section of the WIN. GetProfileString,KERNEL32.DLL,AW,5, retrieves the string associated with the specified key in GetSystemPaletteEntries,GDI32.DLL,NM,4 retrieves a range of palette entries from the system palette that is associated with the specified device context. the given section of the WIN. GetProfileType,USERENV.DLL,NM,1, retrieves the type of profile loaded for the current user. GetSystemPaletteUse,GDI32.DLL,NM,1, retrieves the current state of the system (physical) GetProp,USER32.DLL,AW,2, retrieves a data handle from the property list of the given window. palette for the specified device context. GetSystemPowerStatus,KERNEL32.DLL,NM,1 retrieves the power status of the system. getprotobyname,WS2_32.DLL,NM,1 information corresponding to a protocol name. GetSystemTime,KERNEL32.DLL,NM,1, retrieves the current system date and time. getprotobyname,WSOCK32.DLL,NM,1 information corresponding to a protocol name. GetSystemTimeAdjustment,KERNEL32.DLL,NM,3 determines whether the system is applying getprotobynumber,WS2_32.DLL,NM,1 getprotobynumberretrieves protocolinformation periodic time adjustments to its time-of-day clock at each clock interrupt, along with the value corresponding to a protocol number. and period of any such adjustments. getprotobynumber,WSOCK32.DLL,NM,1 retrieves protocolinformation corresponding to a GetSystemTimeAsFileTime,KERNEL32.DLL,NM,1, obtains the current system date and time. protocol number. GetTapeParameters,KERNEL32.DLL,NM,4, retrieves information that describes the tape or the GetPS2ColorRenderingDictionary,MSCMS.DLL,NM,5, retrieves the PostScript Level 2 color tape drive. rendering dictionary from the specified profile. GetTapePosition,KERNEL32.DLL,NM,5, retrieves the current address of the tape, in logical or GetPS2ColorRenderingIntent,MSCMS.DLL,NM,4, retrieves the PostScript Level 2 color absolute blocks. rendering intent from a profile. GetPS2ColorSpaceArray,MSCMS.DLL,NM,6, retrieves the PostScript Level 2 color space array GetTapeStatus,KERNEL32.DLL,NM,1, indicates whether the tape device is ready to process tape commands. from a profile. GetTempFileName,KERNEL32.DLL,AW,4, creates a name for a temporary file. GetQueuedCompletionStatus,KERNEL32.DLL,NM,5, attempts to dequeue an I/O completion GetTempPath,KERNEL32.DLL,AW,2, retrieves the path of the directory designated for packet from a specified input/output completion port. GetQueueStatus,USER32.DLL,NM,1, returns flags that indicate the type of messages found in temporary files. GetTextAlign,GDI32.DLL,NM,1, retrieves the text the specified device context. the calling thread?s message queue. GetTextCharacterExtra,GDI32.DLL,NM,1, retrieves the current intercharacter spacing for the GetRasterizerCaps,GDI32.DLL,NM,2, returns flags indicating whether TrueType fonts are specified device context. installed in the system. GetTextCharset,GDI32.DLL,NM,1 obtains a character-set identifier forthe font that is currently GetRegionData,GDI32.DLL,NM,3, fills the specified buffer with data describing a region. selected into a specified devicecontext. GetRgnBox,GDI32.DLL,NM,2, retrieves the bounding rectangle of the specified region. GetROP2,GDI32.DLL,NM,1, retrieves the foreground mix mode of the specified device context. GetTextColor,GDI32.DLL,NM,1, retrieves the current text color for the specified device context. GetSaveFileName,COMDLG32.DLL,AW,1 creates a Save common dialog box that lets the user GetTextExtentExPoint,GDI32.DLL,AW,7 retrieves the number of characters in a specified string that will fit within a specified space and fills an array with the text extent for each of those specify the drive, directory, and name of a file to save. GetSaveFileNamePreview,MSVFW32.DLL,AW,1 selects a file by using the SaveAs dialog box. characters. GetScrollInfo,USER32.DLL,NM,3 retrieves the parameters of a scrollbar, including the minimum GetTextExtentPoint,GDI32.DLL,AW,4, computes the width and height of the specified string of text. and maximum scrolling positions, thepage size, and the position of the scroll box (thumb). GetScrollPos,USER32.DLL,NM,2, retrieves the current position of the scroll box (thumb) in the GetTextExtentPoint32,GDI32.DLL,AW,4, computes the width and height of the specified string of text. specified scroll bar. GetTextFace,GDI32.DLL,AW,3, retrieves the typeface name of the font that is selected into the GetScrollRange,USER32.DLL,NM,4 retrieves the current minimum and maximum scroll box specified device context. (thumb) positions for the specified scroll bar GetTextMetrics,GDI32.DLL,AW,2 fills the specified buffer with the,metrics for the currently GetSecurityDescriptorControl,ADVAPI32.DLL,NM,3 retrieves a securitydescriptor?s control selected font. and revision information. GetSecurityDescriptorDacl,ADVAPI32.DLL,NM,4 retrieves a pointer to thediscretionary access- GetThreadContext,KERNEL32.DLL,NM,2, retrieves the context of the specified thread. GetThreadDesktop,USER32.DLL,NM,1, returns a handle to the desktop associated with a control list (ACL) in a specified securitydescriptor. specified thread. GetSecurityDescriptorGroup,ADVAPI32.DLL,NM,3, retrieves the primary group information GetThreadLocale,KERNEL32.DLL,NM,0, returns the calling thread?s current locale. from a security descriptor. GetSecurityDescriptorLength,ADVAPI32.DLL,NM,1, returns the length, in bytes, of a structurally GetThreadPriority,KERNEL32.DLL,NM,1, returns the priority value for the specified thread. GetThreadPriorityBoost,KERNEL32.DLL,NM,2, returns the priority boost control state of the valid SECURITY_DESCRIPTOR structure. specified thread. GetSecurityDescriptorOwner,ADVAPI32.DLL,NM,3, retrieves the owner information from a GetThreadSelectorEntry,KERNEL32.DLL,NM,3, retrieves a descriptor table entry for the security descriptor. specified selector and thread. GetSecurityDescriptorSacl,ADVAPI32.DLL,NM,4 retrieves a pointer to thesystem accessGetThreadTimes,KERNEL32.DLL,NM,5, obtains timing information about a specified thread. control list (ACL) in a specified securitydescriptor. GetTickCount,KERNEL32.DLL,NM,0 retrieves the number of milliseconds that have elapsed GetSecurityInfo,ADVAPI32.DLL,NM,8 retrieves a copy of the security descriptor for an object since Windows was started. specified by a handle. GetTimeFormat,KERNEL32.DLL,AW,6, formats a time as a time string for a specified locale. getservbyname,WS2_32.DLL,NM,2 getservbynameinformation corresponding to a service GetTimestampForLoadedLibrary,IMAGEHLP.DLL,NM,1, returns the timestamp of a loaded name and protocol. image. getservbyname,WSOCK32.DLL,NM,2 information corresponding to a service name and GetTimeZoneInformation,KERNEL32.DLL,NM,1, retrieves the current time-zone parameters. protocol. GetTokenInformation,ADVAPI32.DLL,NM,5, retrieves a specified type of information about an getservbyport,WS2_32.DLL,NM,2, retrieves service information corresponding to a port and access token. protocol. getservbyport,WSOCK32.DLL,NM,2, retrieves service information corresponding to a port and GetTopWindow,USER32.DLL,NM,1 examines the Z order of the child windows associated with the specified parent window and retrieves the handle of the child window at the top of the Z protocol. GetService,MSWSOCK.DLL,AW,7,Important is a Microsoft-specific extension to the Windows order. GetTrusteeName,ADVAPI32.DLL,AW,1, retrieves the trustee name from a TRUSTEE structure. Sockets 1. GetService,WSOCK32.DLL,AW,7,Important is a Microsoft-specific extension to the Windows GetTrusteeType,ADVAPI32.DLL,AW,1, retrieves the value assigned to the TrusteeType member of a specified TRUSTEE structure. Sockets 1. GetServiceDisplayName,ADVAPI32.DLL,AW,4 obtains the display name that is associated with GetTypeByName,MSWSOCK.DLL,AW,2,Important is a Microsoft-specific extension to the Windows Sockets 1. a particular service. . GetServiceKeyName,ADVAPI32.DLL,AW,4, obtains the service name that is associated with a GetTypeByName,WSOCK32.DLL,AW,2,Important is a Microsoft-specific extension to the Windows Sockets 1. particular service?s display name. GetUpdateRect,USER32.DLL,NM,3 retrieves the coordinates of thesmallest rectangle that GetShortPathName,KERNEL32.DLL,AW,3, obtains the short path form of a specified input completely encloses the update region ofthe specified window. path. GetUpdateRgn,USER32.DLL,NM,3, retrieves the update region of a window by copying it into GetSidIdentifierAuthority,ADVAPI32.DLL,NM,1 returns the address of the specified region. theSID_IDENTIFIER_AUTHORITY structure in a specified securityidentifier (SID). GetSidLengthRequired,ADVAPI32.DLL,NM,1 returns the length, in bytes, ofthe buffer required GetUrlCacheEntryInfo,WININET.DLL,AW,3,Retrieves information about a cache entry. GetUrlCacheEntryInfoEx,WININET.DLL,AW,7,Retrieves information on the cache entry to store a SID structure with a specifiednumber of subauthorities. GetSidSubAuthority,ADVAPI32.DLL,NM,2, returns the address of a specified subauthority in a associated with the specified URL, taking into account any redirections that are applied in offline mode by the HttpSendRequest function. SID structure. GetUrlCacheGroupAttribute,WININET.DLL,AW,7,Retrieves the attribute information of the GetSidSubAuthorityCount,ADVAPI32.DLL,NM,1, returns the address of the field in a SID specified cache group. structure containing the subauthority count. getsockname,WS2_32.DLL,NM,3, retrieves the current name for the specified socket descriptor GetUserDefaultLangID,KERNEL32.DLL,NM,0 retrieves the user-default language identifier. GetUserDefaultLCID,KERNEL32.DLL,NM,0, retrieves the user-default locale identifier. in name. GetUserName,ADVAPI32.DLL,AW,2, retrieves the user name of the current thread. getsockname,WSOCK32.DLL,NM,3, retrieves the current name for the specified socket GetUserNameEx,SECUR32.DLL,AW,3, retrieves the name of the user or other security descriptor in name. principal associated with the calling thread. You can specify the format of the returned name. getsockopt,WS2_32.DLL,NM,5 retrieves a socket option. GetUserObjectInformation,USER32.DLL,AW,5 returns information about awindow station or getsockopt,WSOCK32.DLL,NM,5 retrieves a socket option. GetStandardColorSpaceProfile,MSCMS.DLL,AW,4, retrieves the color profile registered for the desktop object. GetUserObjectSecurity,USER32.DLL,NM,5 retrieves security information for the specified user specified standard color space. object. GetStartupInfo,KERNEL32.DLL,AW,1 retrieves the contents of the STARTUPINFO structure GetUserProfileDirectory,USERENV.DLL,AW,3, retrieves the path to the root directory of the that was specified when the calling process was created. specified user's profile. 132 GetVersion,KERNEL32.DLL,NM,0 returns the current version number of Windows and information about the operating system platform. GetViewportExtEx,GDI32.DLL,NM,2, retrieves the x-extents and y-extents of the current viewport for the specified device context. GetViewportOrgEx,GDI32.DLL,NM,2 retrieves the x-coordinates and y-coordinates of the viewport origin for the specified devicecontext. GetVolumeInformation,KERNEL32.DLL,AW,8, returns information about a file system and volume whose root directory is specified. GetWindow,USER32.DLL,NM,2, retrieves the handle of a window that has the specified relationship (Z order or owner) to the specified window. GetWindowContextHelpId,USER32.DLL,NM,1, retrieves the help context identifier, if any, associated with the specified window. GetWindowDC,USER32.DLL,NM,1 retrieves the handle of a display device (DC)context for the specified window. GetWindowExtEx,GDI32.DLL,NM,2 retrieves the x-extents and y-extents of the windowfor the specified device context. GetWindowLong,USER32.DLL,AW,2, retrieves information about the specified window. GetWindowOrgEx,GDI32.DLL,NM,2, retrieves the x-coordinates and y- coordinates of the window origin for the specified device context. GetWindowPlacement,USER32.DLL,NM,2 retrieves the show state and therestored, minimized, and maximized positions of the specifiedwindow. GetWindowRect,USER32.DLL,NM,2, retrieves the dimensions of the bounding rectangle of the specified window. GetWindowRgn,USER32.DLL,NM,2, obtains a copy of the window region of a window. GetWindowsDirectory,KERNEL32.DLL,AW,2, retrieves the path of the Windows directory. GetWindowText,USER32.DLL,AW,3, copies the text of the specified window? s title bar (if it has one) into a buffer. GetWindowTextLength,USER32.DLL,AW,1 retrieves the length, incharacters, of the specified window?s title bar text (if the windowhas a title bar). GetWindowThreadProcessId,USER32.DLL,NM,2, retrieves the identifier of the thread that created the specified window and, optionally, the identifier of the process that created the window. GetWindowWord,USER32.DLL,NM,2, is obsolete. GetWinMetaFileBits,GDI32.DLL,NM,5 converts the enhanced-formatrecords from a metafile into Windows-format records and stores theconverted records in the specified buffer. GetWorldTransform,GDI32.DLL,NM,2, retrieves the current world-space to page-space transformation. GetWsChanges,PSAPI.DLL,NM,3, retrieves information about the pages that have been added to the working set of the specified process since the InitializeProcessForWsWatch function initiated monitoring. glAccum,OPENGL.DLL,NM,2, operates on the accumulation buffer. glAccum,OPENGL32.DLL,NM,2, operates on the accumulation buffer. glAlphaFunc,OPENGL.DLL,NM,2, specifies the alpha test function. glAlphaFunc,OPENGL32.DLL,NM,2, specifies the alpha test function. glAreTexturesResident,OPENGL.DLL,NM,3, determines whether specified texture objects are resident. glAreTexturesResident,OPENGL32.DLL,NM,3, determines whether specified texture objects are resident. glArrayElement,OPENGL.DLL,NM,1, specifies the array elements used to render a vertex. glArrayElement,OPENGL32.DLL,NM,1, specifies the array elements used to render a vertex. glBindTexture,OPENGL.DLL,NM,2, enables the creation of a named texture that is bound to a texture target. glBindTexture,OPENGL32.DLL,NM,2, enables the creation of a named texture that is bound to a texture target. glBitmap,OPENGL.DLL,NM,7, draws a bitmap. glBitmap,OPENGL32.DLL,NM,7, draws a bitmap. glBlendFunc,OPENGL.DLL,NM,2, specifies pixel arithmetic. glBlendFunc,OPENGL32.DLL,NM,2, specifies pixel arithmetic. glCallList,OPENGL.DLL,NM,1, executes a display list. glCallList,OPENGL32.DLL,NM,1, executes a display list. glCallLists,OPENGL.DLL,NM,3, executes a list of display lists. glCallLists,OPENGL32.DLL,NM,3, executes a list of display lists. glClear,OPENGL.DLL,NM,1, clears buffers to preset values. glClear,OPENGL32.DLL,NM,1, clears buffers to preset values. glClearAccum,OPENGL.DLL,NM,4, clears values for the accumulation buffer. glClearAccum,OPENGL32.DLL,NM,4, clears values for the accumulation buffer. glClearColor,OPENGL.DLL,NM,4, specifies clear values for the color buffers. glClearColor,OPENGL32.DLL,NM,4, specifies clear values for the color buffers. glClearDepth,OPENGL.DLL,NM,2, specifies the clear value for the depth buffer. glClearDepth,OPENGL32.DLL,NM,2, specifies the clear value for the depth buffer. glClearIndex,OPENGL.DLL,NM,1, specifies the clear value for the color- index buffers. glClearIndex,OPENGL32.DLL,NM,1, specifies the clear value for the color- index buffers. glClearStencil,OPENGL.DLL,NM,1, specifies the clear value for the stencil buffer. glClearStencil,OPENGL32.DLL,NM,1, specifies the clear value for the stencil buffer. glColor3b,OPENGL.DLL,NM,3 set the current color glColor3b,OPENGL32.DLL,NM,3 set the current color glColor3bv,OPENGL.DLL,NM,1 set the current color glColor3bv,OPENGL32.DLL,NM,1 set the current color glColor3d,OPENGL.DLL,NM,3 set the current color glColor3d,OPENGL32.DLL,NM,3 set the current color glColor3dv,OPENGL.DLL,NM,1 set the current color glColor3dv,OPENGL32.DLL,NM,1 set the current color glColor3f,OPENGL.DLL,NM,3 set the current color glColor3f,OPENGL32.DLL,NM,3 set the current color glColor3fv,OPENGL.DLL,NM,1 set the current color glColor3fv,OPENGL32.DLL,NM,1 set the current color glColor3i,OPENGL.DLL,NM,3 set the current color glColor3i,OPENGL32.DLL,NM,3 set the current color glColor3iv,OPENGL.DLL,NM,1 set the current color glColor3iv,OPENGL32.DLL,NM,1 set the current color glColor3s,OPENGL.DLL,NM,3 set the current color glColor3s,OPENGL32.DLL,NM,3 set the current color glColor3sv,OPENGL.DLL,NM,1 set the current color glColor3sv,OPENGL32.DLL,NM,1 set the current color glColor3ub,OPENGL.DLL,NM,3 set the current color glColor3ub,OPENGL32.DLL,NM,3 set the current color glColor3ubv,OPENGL.DLL,NM,1 set the current color glColor3ubv,OPENGL32.DLL,NM,1 set the current color glColor3ui,OPENGL.DLL,NM,3 set the current color glColor3ui,OPENGL32.DLL,NM,3 set the current color glColor3uiv,OPENGL.DLL,NM,1 set the current color glColor3uiv,OPENGL32.DLL,NM,1 set the current color glColor3us,OPENGL.DLL,NM,3 set the current color glColor3us,OPENGL32.DLL,NM,3 set the current color glColor3usv,OPENGL.DLL,NM,1 set the current color glColor3usv,OPENGL32.DLL,NM,1 set the current color glColor4b,OPENGL.DLL,NM,4 set the current color glColor4b,OPENGL32.DLL,NM,4 set the current color glColor4bv,OPENGL.DLL,NM,1 set the current color glColor4bv,OPENGL32.DLL,NM,1 set the current color glColor4d,OPENGL.DLL,NM,4 set the current color glColor4d,OPENGL32.DLL,NM,4 set the current color glColor4dv,OPENGL.DLL,NM,1 set the current color glColor4dv,OPENGL32.DLL,NM,1 set the current color glColor4f,OPENGL.DLL,NM,4 set the current color glColor4f,OPENGL32.DLL,NM,4 set the current color glColor4fv,OPENGL.DLL,NM,1 set the current color glColor4fv,OPENGL32.DLL,NM,1 set the current color glColor4i,OPENGL.DLL,NM,4 set the current color glColor4i,OPENGL32.DLL,NM,4 set the current color glColor4iv,OPENGL.DLL,NM,1 set the current color glColor4iv,OPENGL32.DLL,NM,1 set the current color glColor4s,OPENGL.DLL,NM,4 set the current color glColor4s,OPENGL32.DLL,NM,4 set the current color glColor4sv,OPENGL.DLL,NM,1 set the current color glColor4sv,OPENGL32.DLL,NM,1 set the current color glColor4ub,OPENGL.DLL,NM,4 set the current color glColor4ub,OPENGL32.DLL,NM,4 set the current color glColor4ubv,OPENGL.DLL,NM,1 set the current color glColor4ubv,OPENGL32.DLL,NM,1 set the current color glColor4ui,OPENGL.DLL,NM,4 set the current color glColor4ui,OPENGL32.DLL,NM,4 set the current color glColor4uiv,OPENGL.DLL,NM,1 set the current color glColor4uiv,OPENGL32.DLL,NM,1 set the current color glColor4us,OPENGL.DLL,NM,4 set the current color glColor4us,OPENGL32.DLL,NM,4 set the current color glColor4usv,OPENGL.DLL,NM,1 set the current color glColor4usv,OPENGL32.DLL,NM,1 set the current color glColorMask,OPENGL.DLL,NM,4, specifies whether the individual color components in the frame buffer can or cannot be written. glColorMask,OPENGL32.DLL,NM,4, specifies whether the individual color components in the frame buffer can or cannot be written. glColorMaterial,OPENGL.DLL,NM,2, causes a material color to track the current color. glColorMaterial,OPENGL32.DLL,NM,2, causes a material color to track the current color. glColorPointer,OPENGL.DLL,NM,4, defines an array of colors. glColorPointer,OPENGL32.DLL,NM,4, defines an array of colors. glCopyPixels,OPENGL.DLL,NM,5, copies pixels in the frame buffer. glCopyPixels,OPENGL32.DLL,NM,5, copies pixels in the frame buffer. glCopyTexImage1D,OPENGL.DLL,NM,7, copies pixels from the frame buffer into a onedimensional texture image. glCopyTexImage1D,OPENGL32.DLL,NM,7, copies pixels from the frame buffer into a onedimensional texture image. glCopyTexImage2D,OPENGL.DLL,NM,4, copies pixels from the frame buffer into a twodimensional texture image. glCopyTexImage2D,OPENGL32.DLL,NM,4, copies pixels from the frame buffer into a twodimensional texture image. glCopyTexSubImage1D,OPENGL.DLL,NM,3, copies a sub-image of a one- dimensional texture image from the frame buffer. glCopyTexSubImage1D,OPENGL32.DLL,NM,3, copies a sub-image of a one- dimensional texture image from the frame buffer. glCopyTexSubImage2D,OPENGL.DLL,NM,4, copies a sub-image of a two- dimensional texture image from the frame buffer. glCopyTexSubImage2D,OPENGL32.DLL,NM,4, copies a sub-image of a two- dimensional texture image from the frame buffer. glCullFace,OPENGL.DLL,NM,1, specifies whether front- or back-facing facets can be culled. glCullFace,OPENGL32.DLL,NM,1, specifies whether front- or back-facing facets can be culled. glDeleteLists,OPENGL.DLL,NM,2, deletes a contiguous group of display lists. glDeleteLists,OPENGL32.DLL,NM,2, deletes a contiguous group of display lists. glDeleteTextures,OPENGL.DLL,NM,2, deletes named textures. glDeleteTextures,OPENGL32.DLL,NM,2, deletes named textures. glDepthFunc,OPENGL.DLL,NM,1, specifies the value used for depth-buffer comparisons. glDepthFunc,OPENGL32.DLL,NM,1, specifies the value used for depth-buffer comparisons. glDepthMask,OPENGL.DLL,NM,1, enables or disables writing into the depth buffer. glDepthMask,OPENGL32.DLL,NM,1, enables or disables writing into the depth buffer. glDepthRange,OPENGL.DLL,NM,4, specifies the mapping of z values from normalized device coordinates to window coordinates. glDepthRange,OPENGL32.DLL,NM,4, specifies the mapping of z values from normalized device coordinates to window coordinates. glDisable,OPENGL.DLL,NM,1 disable OpenGL capabilities. glDisable,OPENGL32.DLL,NM,1 disable OpenGL capabilities. glDisableClientState,OPENGL.DLL,NM,1 disable array. glDisableClientState,OPENGL32.DLL,NM,1 disable array. glDrawArrays,OPENGL.DLL,NM,3, specifies multiple primitives to render. glDrawArrays,OPENGL32.DLL,NM,3, specifies multiple primitives to render. glDrawBuffer,OPENGL.DLL,NM,1, specifies which color buffers are to be drawn into. glDrawBuffer,OPENGL32.DLL,NM,1, specifies which color buffers are to be drawn into. glDrawElements,OPENGL.DLL,NM,4, renders primitives from array data. glDrawElements,OPENGL32.DLL,NM,4, renders primitives from array data. glDrawPixels,OPENGL.DLL,NM,5, writes a block of pixels to the frame buffer. glDrawPixels,OPENGL32.DLL,NM,5, writes a block of pixels to the frame buffer. glEdgeFlag,OPENGL.DLL,NM,1 flag edges as either boundary or nonboundary glEdgeFlag,OPENGL32.DLL,NM,1 flag edges as either boundary or nonboundary glEdgeFlagPointer,OPENGL.DLL,NM,2, defines an array of edge flags. glEdgeFlagPointer,OPENGL32.DLL,NM,2, defines an array of edge flags. glEdgeFlagv,OPENGL.DLL,NM,1 flag edges as either boundary or nonboundary glEdgeFlagv,OPENGL32.DLL,NM,1 flag edges as either boundary or nonboundary glEnable,OPENGL.DLL,NM,1 enable OpenGL capabilities. glEnable,OPENGL32.DLL,NM,1 enable OpenGL capabilities. glEnableClientState,OPENGL.DLL,NM,1 enable array. glEnableClientState,OPENGL32.DLL,NM,1 enable array. glEnd,OPENGL.DLL,NM,0 delimit the vertices of a primitive or a group of like primitives. glEnd,OPENGL32.DLL,NM,0 delimit the vertices of a primitive or a group of like primitives. glEndList,OPENGL.DLL,NM,0 create or replace a display list. glEndList,OPENGL32.DLL,NM,0 create or replace a display list. glEvalCoord1d,OPENGL.DLL,NM,2 evaluate enabled one- and two-dimensional maps. glEvalCoord1d,OPENGL32.DLL,NM,2 evaluate enabled one- and two-dimensional maps. glEvalCoord1dv,OPENGL.DLL,NM,1 evaluate enabled one- and two-dimensional maps. glEvalCoord1dv,OPENGL32.DLL,NM,1 evaluate enabled one- and two-dimensional maps. glEvalCoord1f,OPENGL.DLL,NM,1 evaluate enabled one- and two-dimensional maps. glEvalCoord1f,OPENGL32.DLL,NM,1 evaluate enabled one- and two-dimensional maps. glEvalCoord1fv,OPENGL.DLL,NM,1 evaluate enabled one- and two-dimensional maps. glEvalCoord1fv,OPENGL32.DLL,NM,1 evaluate enabled one- and two-dimensional maps. glEvalCoord2d,OPENGL.DLL,NM,2 evaluate enabled one- and two-dimensional maps. glEvalCoord2d,OPENGL32.DLL,NM,2 evaluate enabled one- and two-dimensional maps. glEvalCoord2dv,OPENGL.DLL,NM,1 evaluate enabled one- and two-dimensional maps. glEvalCoord2dv,OPENGL32.DLL,NM,1 evaluate enabled one- and two-dimensional maps. glEvalCoord2f,OPENGL.DLL,NM,2 evaluate enabled one- and two-dimensional maps. glEvalCoord2f,OPENGL32.DLL,NM,2 evaluate enabled one- and two-dimensional maps. 133 glIndexi,OPENGL32.DLL,NM,1 set the current color index. glEvalCoord2fv,OPENGL.DLL,NM,1 evaluate enabled one- and two-dimensional maps. glIndexiv,OPENGL.DLL,NM,1 set the current color index. glEvalCoord2fv,OPENGL32.DLL,NM,1 evaluate enabled one- and two-dimensional maps. glIndexiv,OPENGL32.DLL,NM,1 set the current color index. glEvalMesh1,OPENGL.DLL,NM,3 compute a one- or two-dimensional grid of points or lines. glEvalMesh1,OPENGL32.DLL,NM,3 compute a one- or two-dimensional grid of points or lines. glIndexMask,OPENGL.DLL,NM,1, controls the writing of individual bits in the color-index buffers. glEvalMesh2,OPENGL.DLL,NM,5 compute a one- or two-dimensional grid of points or lines. glEvalMesh2,OPENGL32.DLL,NM,5 compute a one- or two-dimensional grid of points or lines. glIndexMask,OPENGL32.DLL,NM,1, controls the writing of individual bits in the color-index buffers. glEvalPoint1,OPENGL.DLL,NM,1 generate and evaluate a single point in a mesh. glIndexPointer,OPENGL.DLL,NM,3, defines an array of color indexes. glEvalPoint1,OPENGL32.DLL,NM,1 generate and evaluate a single point in a mesh. glIndexPointer,OPENGL32.DLL,NM,3, defines an array of color indexes. glEvalPoint2,OPENGL.DLL,NM,2 generate and evaluate a single point in a mesh. glIndexs,OPENGL.DLL,NM,1 set the current color index. glEvalPoint2,OPENGL32.DLL,NM,2 generate and evaluate a single point in a mesh. glIndexs,OPENGL32.DLL,NM,1 set the current color index. glFeedbackBuffer,OPENGL.DLL,NM,3, controls feedback mode. glIndexsv,OPENGL.DLL,NM,1 set the current color index. glFeedbackBuffer,OPENGL32.DLL,NM,3, controls feedback mode. glIndexsv,OPENGL32.DLL,NM,1 set the current color index. glFinish,OPENGL.DLL,NM,0, blocks until all OpenGL execution is complete. glInitNames,OPENGL.DLL,NM,0, initializes the name stack. glFinish,OPENGL32.DLL,NM,0, blocks until all OpenGL execution is complete. glInitNames,OPENGL32.DLL,NM,0, initializes the name stack. glFlush,OPENGL.DLL,NM,0, forces execution of OpenGL functions in finite time. glInterleavedArrays,OPENGL.DLL,NM,3, simultaneously specifies and enables several glFlush,OPENGL32.DLL,NM,0, forces execution of OpenGL functions in finite time. interleaved arrays in a larger aggregate array. glFogf,OPENGL.DLL,NM,2 specify fog parameters. glInterleavedArrays,OPENGL32.DLL,NM,3, simultaneously specifies and enables several glFogf,OPENGL32.DLL,NM,2 specify fog parameters. interleaved arrays in a larger aggregate array. glFogfv,OPENGL.DLL,NM,2 specify fog parameters. glIsEnabled,OPENGL.DLL,NM,1 tests whether a capability is enabled. glFogfv,OPENGL32.DLL,NM,2 specify fog parameters. glIsEnabled,OPENGL32.DLL,NM,1 tests whether a capability is enabled. glFogi,OPENGL.DLL,NM,2 specify fog parameters. glIsList,OPENGL.DLL,NM,1 tests for display list existence. glFogi,OPENGL32.DLL,NM,2 specify fog parameters. glIsList,OPENGL32.DLL,NM,1 tests for display list existence. glFogiv,OPENGL.DLL,NM,2 specify fog parameters. glIsTexture,OPENGL.DLL,NM,1, determines if a name corresponds to a texture. glFogiv,OPENGL32.DLL,NM,2 specify fog parameters. glFrontFace,OPENGL.DLL,NM,1, specifies which of the clockwise and counterclockwise facets glIsTexture,OPENGL32.DLL,NM,1, determines if a name corresponds to a texture. glLightf,OPENGL.DLL,NM,3 set light source parameters. are front-facing and back-facing. glLightf,OPENGL32.DLL,NM,3 set light source parameters. glFrontFace,OPENGL32.DLL,NM,1, specifies which of the clockwise and counterclockwise glLightfv,OPENGL.DLL,NM,3 set light source parameters. facets are front-facing and back-facing. glLightfv,OPENGL32.DLL,NM,3 set light source parameters. glFrustum,OPENGL.DLL,NM,12, multiplies the current matrix by a perspective matrix. glLighti,OPENGL.DLL,NM,3 set light source parameters. glFrustum,OPENGL32.DLL,NM,12, multiplies the current matrix by a perspective matrix. glLighti,OPENGL32.DLL,NM,3 set light source parameters. glGenLists,OPENGL.DLL,NM,1, generates a contiguous set of empty display lists. glLightiv,OPENGL.DLL,NM,3 set light source parameters. glGenLists,OPENGL32.DLL,NM,1, generates a contiguous set of empty display lists. glLightiv,OPENGL32.DLL,NM,3 set light source parameters. glGenTextures,OPENGL.DLL,NM,2, generates texture names. glLightModelf,OPENGL.DLL,NM,2 set the lighting model parameters. glGenTextures,OPENGL32.DLL,NM,2, generates texture names. glLightModelf,OPENGL32.DLL,NM,2 set the lighting model parameters. glGetBooleanv,OPENGL.DLL,NM,2 return the value or values of a selected parameter. glLightModelfv,OPENGL.DLL,NM,2 set the lighting model parameters. glGetBooleanv,OPENGL32.DLL,NM,2 return the value or values of a selected parameter. glLightModelfv,OPENGL32.DLL,NM,2 set the lighting model parameters. glGetClipPlane,OPENGL.DLL,NM,2, returns in equation the four coefficients of the plane glLightModeli,OPENGL.DLL,NM,2 set the lighting model parameters. equation for plane. glLightModeli,OPENGL32.DLL,NM,2 set the lighting model parameters. glGetClipPlane,OPENGL32.DLL,NM,2, returns in equation the four coefficients of the plane glLightModeliv,OPENGL.DLL,NM,2 set the lighting model parameters. equation for plane. glLightModeliv,OPENGL32.DLL,NM,2 set the lighting model parameters. glGetDoublev,OPENGL.DLL,NM,2 return the value or values of a selected parameter. glLineStipple,OPENGL.DLL,NM,2, specifies the line stipple pattern. glGetDoublev,OPENGL32.DLL,NM,2 return the value or values of a selected parameter. glLineStipple,OPENGL32.DLL,NM,2, specifies the line stipple pattern. glGetError,OPENGL.DLL,NM,0, returns error information. glLineWidth,OPENGL.DLL,NM,1, specifies the width of rasterized lines. glGetError,OPENGL32.DLL,NM,0, returns error information. glLineWidth,OPENGL32.DLL,NM,1, specifies the width of rasterized lines. glGetFloatv,OPENGL.DLL,NM,2 return the value or values of a selected parameter. glListBase,OPENGL.DLL,NM,1, makes an additional level of indirection available. glGetFloatv,OPENGL32.DLL,NM,2 return the value or values of a selected parameter. glListBase,OPENGL32.DLL,NM,1, makes an additional level of indirection available. glGetIntegerv,OPENGL.DLL,NM,2 return the value or values of a selected parameter. glLoadIdentity,OPENGL.DLL,NM,0, replaces the current matrix with the identity matrix. glGetIntegerv,OPENGL32.DLL,NM,2 return the value or values of a selected parameter. glLoadIdentity,OPENGL32.DLL,NM,0, replaces the current matrix with the identity matrix. glGetLightfv,OPENGL.DLL,NM,3 return light source parameter values. glLoadMatrixd,OPENGL.DLL,NM,1 replace the current matrix with an arbitrary matrix. glGetLightfv,OPENGL32.DLL,NM,3 return light source parameter values. glLoadMatrixd,OPENGL32.DLL,NM,1 replace the current matrix with an arbitrary matrix. glGetLightiv,OPENGL.DLL,NM,3 return light source parameter values. glLoadMatrixf,OPENGL.DLL,NM,1 replace the current matrix with an arbitrary matrix. glGetLightiv,OPENGL32.DLL,NM,3 return light source parameter values. glLoadMatrixf,OPENGL32.DLL,NM,1 replace the current matrix with an arbitrary matrix. glGetMapdv,OPENGL.DLL,NM,3 return evaluator parameters. glLoadName,OPENGL.DLL,NM,1, loads a name onto the name stack. glGetMapdv,OPENGL32.DLL,NM,3 return evaluator parameters. glLoadName,OPENGL32.DLL,NM,1, loads a name onto the name stack. glGetMapfv,OPENGL.DLL,NM,3 return evaluator parameters. glLogicOp,OPENGL.DLL,NM,1, specifies a logical pixel operation for color index rendering. glGetMapfv,OPENGL32.DLL,NM,3 return evaluator parameters. glLogicOp,OPENGL32.DLL,NM,1, specifies a logical pixel operation for color index rendering. glGetMapiv,OPENGL.DLL,NM,3 return evaluator parameters. glMap1d,OPENGL.DLL,NM,4 define a one-dimensional evaluator. glGetMapiv,OPENGL32.DLL,NM,3 return evaluator parameters. glMap1d,OPENGL32.DLL,NM,4 define a one-dimensional evaluator. glGetMaterialfv,OPENGL.DLL,NM,3 return material parameters. glMap1f,OPENGL.DLL,NM,6 define a one-dimensional evaluator. glGetMaterialfv,OPENGL32.DLL,NM,3 return material parameters. glMap1f,OPENGL32.DLL,NM,6 define a one-dimensional evaluator. glGetMaterialiv,OPENGL.DLL,NM,3 return material parameters. glMap2d,OPENGL.DLL,NM,7 define a two-dimensional evaluator. glGetMaterialiv,OPENGL32.DLL,NM,3 return material parameters. glMap2d,OPENGL32.DLL,NM,7 define a two-dimensional evaluator. glGetPixelMapfv,OPENGL.DLL,NM,2 return the specified pixel map. glMap2f,OPENGL.DLL,NM,10 define a two-dimensional evaluator. glGetPixelMapfv,OPENGL32.DLL,NM,2 return the specified pixel map. glMap2f,OPENGL32.DLL,NM,10 define a two-dimensional evaluator. glGetPixelMapuiv,OPENGL.DLL,NM,2 return the specified pixel map. glMapGrid1d,OPENGL.DLL,NM,5 define a one- or two-dimensional mesh. glGetPixelMapuiv,OPENGL32.DLL,NM,2 return the specified pixel map. glMapGrid1d,OPENGL32.DLL,NM,5 define a one- or two-dimensional mesh. glGetPixelMapusv,OPENGL.DLL,NM,2 return the specified pixel map. glMapGrid1f,OPENGL.DLL,NM,3 define a one- or two-dimensional mesh. glGetPixelMapusv,OPENGL32.DLL,NM,2 return the specified pixel map. glMapGrid1f,OPENGL32.DLL,NM,3 define a one- or two-dimensional mesh. glGetPointerv,OPENGL.DLL,NM,2, returns the address of a vertex data array. glMapGrid2d,OPENGL.DLL,NM,5 define a one- or two-dimensional mesh. glGetPointerv,OPENGL32.DLL,NM,2, returns the address of a vertex data array. glMapGrid2d,OPENGL32.DLL,NM,5 define a one- or two-dimensional mesh. glGetPolygonStipple,OPENGL.DLL,NM,1, returns the polygon stipple pattern. glMapGrid2f,OPENGL.DLL,NM,6 define a one- or two-dimensional mesh. glGetPolygonStipple,OPENGL32.DLL,NM,1, returns the polygon stipple pattern. glMapGrid2f,OPENGL32.DLL,NM,6 define a one- or two-dimensional mesh. glGetString,OPENGL.DLL,NM,1, returns a string describing the current OpenGL connection. glGetString,OPENGL32.DLL,NM,1, returns a string describing the current OpenGL connection. glMaterialf,OPENGL.DLL,NM,3 specify material parameters for the lighting model. glMaterialf,OPENGL32.DLL,NM,3 specify material parameters for the lighting model. glGetTexEnvfv,OPENGL.DLL,NM,3 return texture environment parameters. glMaterialfv,OPENGL.DLL,NM,3 specify material parameters for the lighting model. glGetTexEnvfv,OPENGL32.DLL,NM,3 return texture environment parameters. glMaterialfv,OPENGL32.DLL,NM,3 specify material parameters for the lighting model. glGetTexEnviv,OPENGL.DLL,NM,3 return texture environment parameters. glMateriali,OPENGL.DLL,NM,3 specify material parameters for the lighting model. glGetTexEnviv,OPENGL32.DLL,NM,3 return texture environment parameters. glMateriali,OPENGL32.DLL,NM,3 specify material parameters for the lighting model. glGetTexGendv,OPENGL.DLL,NM,3 return texture coordinate generation parameters. glMaterialiv,OPENGL.DLL,NM,3 specify material parameters for the lighting model. glGetTexGendv,OPENGL32.DLL,NM,3 return texture coordinate generation parameters. glMaterialiv,OPENGL32.DLL,NM,3 specify material parameters for the lighting model. glGetTexGenfv,OPENGL.DLL,NM,3 return texture coordinate generation parameters. glMatrixMode,OPENGL.DLL,NM,1, sets the current matrix mode. glGetTexGenfv,OPENGL32.DLL,NM,3 return texture coordinate generation parameters. glMatrixMode,OPENGL32.DLL,NM,1, sets the current matrix mode. glGetTexGeniv,OPENGL.DLL,NM,3 return texture coordinate generation parameters. glMultMatrixd,OPENGL.DLL,NM,1 multiply the current matrix by an arbitrary matrix. glGetTexGeniv,OPENGL32.DLL,NM,3 return texture coordinate generation parameters. glMultMatrixd,OPENGL32.DLL,NM,1 multiply the current matrix by an arbitrary matrix. glGetTexImage,OPENGL.DLL,NM,5, returns a texture image. glMultMatrixf,OPENGL.DLL,NM,1 multiply the current matrix by an arbitrary matrix. glGetTexImage,OPENGL32.DLL,NM,5, returns a texture image. glGetTexLevelParameterfv,OPENGL.DLL,NM,4 return texture parameter values for a specific glMultMatrixf,OPENGL32.DLL,NM,1 multiply the current matrix by an arbitrary matrix. glNewList,OPENGL.DLL,NM,2 create or replace a display list. level of detail. glGetTexLevelParameterfv,OPENGL32.DLL,NM,4 return texture parameter values for a specific glNewList,OPENGL32.DLL,NM,2 create or replace a display list. glNormal3b,OPENGL.DLL,NM,3 set the current normal vector. level of detail. glGetTexLevelParameteriv,OPENGL.DLL,NM,4 return texture parameter values for a specific glNormal3b,OPENGL32.DLL,NM,3 set the current normal vector. glNormal3bv,OPENGL.DLL,NM,1 set the current normal vector. level of detail. glGetTexLevelParameteriv,OPENGL32.DLL,NM,4 return texture parameter values for a specific glNormal3bv,OPENGL32.DLL,NM,1 set the current normal vector. glNormal3d,OPENGL.DLL,NM,3 set the current normal vector. level of detail. glNormal3d,OPENGL32.DLL,NM,3 set the current normal vector. glGetTexParameterfv,OPENGL.DLL,NM,3 return texture parameter values. glNormal3dv,OPENGL.DLL,NM,1 set the current normal vector. glGetTexParameterfv,OPENGL32.DLL,NM,3 return texture parameter values. glNormal3dv,OPENGL32.DLL,NM,1 set the current normal vector. glGetTexParameteriv,OPENGL.DLL,NM,3 return texture parameter values. glNormal3f,OPENGL.DLL,NM,3 set the current normal vector. glGetTexParameteriv,OPENGL32.DLL,NM,3 return texture parameter values. glNormal3f,OPENGL32.DLL,NM,3 set the current normal vector. glHint,OPENGL.DLL,NM,2, specifies implementation-specific hints. glNormal3fv,OPENGL.DLL,NM,1 set the current normal vector. glHint,OPENGL32.DLL,NM,2, specifies implementation-specific hints. glNormal3fv,OPENGL32.DLL,NM,1 set the current normal vector. glIndexd,OPENGL.DLL,NM,2 set the current color index. glNormal3i,OPENGL.DLL,NM,3 set the current normal vector. glIndexd,OPENGL32.DLL,NM,2 set the current color index. glNormal3i,OPENGL32.DLL,NM,3 set the current normal vector. glIndexdv,OPENGL.DLL,NM,1 set the current color index. glNormal3iv,OPENGL.DLL,NM,1 set the current normal vector. glIndexdv,OPENGL32.DLL,NM,1 set the current color index. glNormal3iv,OPENGL32.DLL,NM,1 set the current normal vector. glIndexf,OPENGL.DLL,NM,1 set the current color index. glNormal3s,OPENGL.DLL,NM,3 set the current normal vector. glIndexf,OPENGL32.DLL,NM,1 set the current color index. glNormal3s,OPENGL32.DLL,NM,3 set the current normal vector. glIndexfv,OPENGL.DLL,NM,1 set the current color index. glNormal3sv,OPENGL.DLL,NM,1 set the current normal vector. glIndexfv,OPENGL32.DLL,NM,1 set the current color index. glNormal3sv,OPENGL32.DLL,NM,1 set the current normal vector. glIndexi,OPENGL.DLL,NM,1 set the current color index. 134 glRasterPos3i,OPENGL32.DLL,NM,3 specify the raster position for pixel operations. glNormalPointer,OPENGL.DLL,NM,3, defines an array of normals. glRasterPos3iv,OPENGL.DLL,NM,1 specify the raster position for pixel operations. glNormalPointer,OPENGL32.DLL,NM,3, defines an array of normals. glRasterPos3iv,OPENGL32.DLL,NM,1 specify the raster position for pixel operations. GlobalAddAtom,KERNEL32.DLL,AW,1 adds a character string to the globalatom table and glRasterPos3s,OPENGL.DLL,NM,3 specify the raster position for pixel operations. returns a unique value (an atom) identifying thestring. glRasterPos3s,OPENGL32.DLL,NM,3 specify the raster position for pixel operations. GlobalAlloc,KERNEL32.DLL,NM,2, allocates the specified number of bytes from the heap. glRasterPos3sv,OPENGL.DLL,NM,1 specify the raster position for pixel operations. GlobalCompact,KERNEL32.DLL,NM,1, is obsolete. glRasterPos3sv,OPENGL32.DLL,NM,1 specify the raster position for pixel operations. GlobalDeleteAtom,KERNEL32.DLL,NM,1, decrements the reference count of a global string glRasterPos4d,OPENGL.DLL,NM,4 specify the raster position for pixel operations. atom. glRasterPos4d,OPENGL32.DLL,NM,4 specify the raster position for pixel operations. GlobalFindAtom,KERNEL32.DLL,AW,1 searches the global atom table for thespecified glRasterPos4dv,OPENGL.DLL,NM,1 specify the raster position for pixel operations. character string and retrieves the global atom associatedwith that string. glRasterPos4dv,OPENGL32.DLL,NM,1 specify the raster position for pixel operations. GlobalFix,KERNEL32.DLL,NM,1, is obsolete. glRasterPos4f,OPENGL.DLL,NM,4 specify the raster position for pixel operations. GlobalFlags,KERNEL32.DLL,NM,1, returns information about the specified global memory glRasterPos4f,OPENGL32.DLL,NM,4 specify the raster position for pixel operations. object. GlobalFree,KERNEL32.DLL,NM,1, frees the specified global memory object and invalidates its glRasterPos4fv,OPENGL.DLL,NM,1 specify the raster position for pixel operations. glRasterPos4fv,OPENGL32.DLL,NM,1 specify the raster position for pixel operations. handle. GlobalGetAtomName,KERNEL32.DLL,AW,3, retrieves a copy of the character string associated glRasterPos4i,OPENGL.DLL,NM,4 specify the raster position for pixel operations. glRasterPos4i,OPENGL32.DLL,NM,4 specify the raster position for pixel operations. with the specified global atom. GlobalHandle,KERNEL32.DLL,NM,1, retrieves the handle associated with the specified pointer glRasterPos4iv,OPENGL.DLL,NM,1 specify the raster position for pixel operations. glRasterPos4iv,OPENGL32.DLL,NM,1 specify the raster position for pixel operations. to a global memory block. glRasterPos4s,OPENGL.DLL,NM,4 specify the raster position for pixel operations. GlobalLock,KERNEL32.DLL,NM,1, locks a global memory object and returns a pointer to the glRasterPos4s,OPENGL32.DLL,NM,4 specify the raster position for pixel operations. first byte of the object?s memory block. GlobalMemoryStatus,KERNEL32.DLL,NM,1 obtains information about thecomputer system?s glRasterPos4sv,OPENGL.DLL,NM,1 specify the raster position for pixel operations. glRasterPos4sv,OPENGL32.DLL,NM,1 specify the raster position for pixel operations. current usage of both physical and virtualmemory. glReadBuffer,OPENGL.DLL,NM,1, selects a color buffer source for pixels. GlobalReAlloc,KERNEL32.DLL,NM,3, changes the size or attributes of a specified global glReadBuffer,OPENGL32.DLL,NM,1, selects a color buffer source for pixels. memory object. glReadPixels,OPENGL.DLL,NM,7, reads a block of pixels from the frame buffer. GlobalSize,KERNEL32.DLL,NM,1, retrieves the current size, in bytes, of the specified global glReadPixels,OPENGL32.DLL,NM,7, reads a block of pixels from the frame buffer. memory object. glRectd,OPENGL.DLL,NM,4 draw a rectangle. GlobalUnfix,KERNEL32.DLL,NM,1, is obsolete. glRectd,OPENGL32.DLL,NM,4 draw a rectangle. GlobalUnWire,KERNEL32.DLL,NM,1, is obsolete. glRectdv,OPENGL.DLL,NM,2 draw a rectangle. GlobalWire,KERNEL32.DLL,NM,1 is obsolete. glRectdv,OPENGL32.DLL,NM,2 draw a rectangle. glOrtho,OPENGL.DLL,NM,12, multiplies the current matrix by an orthographic matrix. glRectf,OPENGL.DLL,NM,4 draw a rectangle. glOrtho,OPENGL32.DLL,NM,12, multiplies the current matrix by an orthographic matrix. glRectf,OPENGL32.DLL,NM,4 draw a rectangle. glPassThrough,OPENGL.DLL,NM,1, places a marker in the feedback buffer. glRectfv,OPENGL.DLL,NM,2 draw a rectangle. glPassThrough,OPENGL32.DLL,NM,1, places a marker in the feedback buffer. glRectfv,OPENGL32.DLL,NM,2 draw a rectangle. glPixelMapfv,OPENGL.DLL,NM,3 set up pixel transfer maps. glRecti,OPENGL.DLL,NM,4 draw a rectangle. glPixelMapfv,OPENGL32.DLL,NM,3 set up pixel transfer maps. glRecti,OPENGL32.DLL,NM,4 draw a rectangle. glPixelMapuiv,OPENGL.DLL,NM,3 set up pixel transfer maps. glRectiv,OPENGL.DLL,NM,2 draw a rectangle. glPixelMapuiv,OPENGL32.DLL,NM,3 set up pixel transfer maps. glRectiv,OPENGL32.DLL,NM,2 draw a rectangle. glPixelMapusv,OPENGL.DLL,NM,3 set up pixel transfer maps. glRects,OPENGL.DLL,NM,4 draw a rectangle. glPixelMapusv,OPENGL32.DLL,NM,3 set up pixel transfer maps. glRects,OPENGL32.DLL,NM,4 draw a rectangle. glPixelStoref,OPENGL.DLL,NM,2, can be used to set any pixel store parameter. glRectsv,OPENGL.DLL,NM,2 draw a rectangle. glPixelStoref,OPENGL32.DLL,NM,2, can be used to set any pixel store parameter. glRectsv,OPENGL32.DLL,NM,2 draw a rectangle. glPixelStorei,OPENGL.DLL,NM,2 set pixel storage modes. glRenderMode,OPENGL.DLL,NM,1, sets the rasterization mode. glPixelStorei,OPENGL32.DLL,NM,2 set pixel storage modes. glRenderMode,OPENGL32.DLL,NM,1, sets the rasterization mode. glPixelTransferf,OPENGL.DLL,NM,2, can be used to set any pixel transfer parameter. glRotated,OPENGL.DLL,NM,4 multiply the current matrix by a rotation matrix. glPixelTransferf,OPENGL32.DLL,NM,2, can be used to set any pixel transfer parameter. glRotated,OPENGL32.DLL,NM,4 multiply the current matrix by a rotation matrix. glPixelTransferi,OPENGL.DLL,NM,2 set pixel storage modes. glRotatef,OPENGL.DLL,NM,4 multiply the current matrix by a rotation matrix. glPixelTransferi,OPENGL32.DLL,NM,2 set pixel storage modes. glRotatef,OPENGL32.DLL,NM,4 multiply the current matrix by a rotation matrix. glPixelZoom,OPENGL.DLL,NM,2, specifies values for the x and y zoom factors. glScaled,OPENGL.DLL,NM,3 multiply the current matrix by a general scaling matrix. glPixelZoom,OPENGL32.DLL,NM,2, specifies values for the x and y zoom factors. glScaled,OPENGL32.DLL,NM,3 multiply the current matrix by a rotation matrix. glPointSize,OPENGL.DLL,NM,1, specifies the diameter of rasterized points. glScalef,OPENGL.DLL,NM,3 multiply the current matrix by a rotation matrix. glPointSize,OPENGL32.DLL,NM,1, specifies the diameter of rasterized points. glScalef,OPENGL32.DLL,NM,3 multiply the current matrix by a rotation matrix. glPolygonMode,OPENGL.DLL,NM,2, selects a polygon rasterization mode. glScissor,OPENGL.DLL,NM,4, defines the scissor box. glPolygonMode,OPENGL32.DLL,NM,2, selects a polygon rasterization mode. glScissor,OPENGL32.DLL,NM,4, defines the scissor box. glPolygonStipple,OPENGL.DLL,NM,1, sets the polygon stippling pattern. glSelectBuffer,OPENGL.DLL,NM,2, establishes a buffer for selection mode values. glPolygonStipple,OPENGL32.DLL,NM,1, sets the polygon stippling pattern. glSelectBuffer,OPENGL32.DLL,NM,2, establishes a buffer for selection mode values. glPopAttrib,OPENGL.DLL,NM,0, restores the values of the state variables saved with the last glShadeModel,OPENGL.DLL,NM,1 selects flat or smooth shading. glPushAttrib command. glPopAttrib,OPENGL32.DLL,NM,0, restores the values of the state variables saved with the last glShadeModel,OPENGL32.DLL,NM,1 selects flat or smooth shading. glStencilFunc,OPENGL.DLL,NM,3, sets the function and reference value for stencil testing. glPushAttrib command. glStencilFunc,OPENGL32.DLL,NM,3, sets the function and reference value for stencil testing. glPopClientAttrib,OPENGL.DLL,NM,0, restores the values of the client- state variables last glStencilMask,OPENGL.DLL,NM,1, controls the writing of individual bits in the stencil planes. saved with glPushClientAttrib. glStencilMask,OPENGL32.DLL,NM,1, controls the writing of individual bits in the stencil planes. glPopClientAttrib,OPENGL32.DLL,NM,0, restores the values of the client- state variables last glStencilOp,OPENGL.DLL,NM,3, sets the stencil test actions. saved with glPushClientAttrib. glStencilOp,OPENGL32.DLL,NM,3, sets the stencil test actions. glPopMatrix,OPENGL.DLL,NM,0 pop the current matrix stack. glTexCoord1d,OPENGL.DLL,NM,2 set the current texture coordinates. glPopMatrix,OPENGL32.DLL,NM,0 pop the current matrix stack. glTexCoord1d,OPENGL32.DLL,NM,2 set the current texture coordinates. glPrioritizeTextures,OPENGL.DLL,NM,3, sets the residence priority of textures. glTexCoord1dv,OPENGL.DLL,NM,1 set the current texture coordinates. glPrioritizeTextures,OPENGL32.DLL,NM,3, sets the residence priority of textures. glPushAttrib,OPENGL.DLL,NM,1, takes one argument, a mask that indicates which groups of glTexCoord1dv,OPENGL32.DLL,NM,1 set the current texture coordinates. glTexCoord1f,OPENGL.DLL,NM,1 set the current texture coordinates. state variables to save on the attribute stack. glPushAttrib,OPENGL32.DLL,NM,1, takes one argument, a mask that indicates which groups of glTexCoord1f,OPENGL32.DLL,NM,1 set the current texture coordinates. glTexCoord1fv,OPENGL.DLL,NM,1 set the current texture coordinates. state variables to save on the attribute stack. glTexCoord1fv,OPENGL32.DLL,NM,1 set the current texture coordinates. glPushClientAttrib,OPENGL.DLL,NM,1 save groups of client-state variables on the clientglTexCoord1i,OPENGL.DLL,NM,1 set the current texture coordinates. attribute stack. glTexCoord1i,OPENGL32.DLL,NM,1 set the current texture coordinates. glPushClientAttrib,OPENGL32.DLL,NM,1 save groups of client-state variables on the clientglTexCoord1iv,OPENGL.DLL,NM,1 set the current texture coordinates. attribute stack. glTexCoord1iv,OPENGL32.DLL,NM,1 set the current texture coordinates. glPushMatrix,OPENGL.DLL,NM,0, pushes the current matrix stack down by one, duplicating glTexCoord1s,OPENGL.DLL,NM,1 set the current texture coordinates. the current matrix. glPushMatrix,OPENGL32.DLL,NM,0, pushes the current matrix stack down by one, duplicating glTexCoord1s,OPENGL32.DLL,NM,1 set the current texture coordinates. glTexCoord1sv,OPENGL.DLL,NM,1 set the current texture coordinates. the current matrix. glTexCoord1sv,OPENGL32.DLL,NM,1 set the current texture coordinates. glPushName,OPENGL.DLL,NM,1, causes name to be pushed onto the name stack, which is glTexCoord2d,OPENGL.DLL,NM,2 set the current texture coordinates. initially empty. glPushName,OPENGL32.DLL,NM,1, causes name to be pushed onto the name stack, which is glTexCoord2d,OPENGL32.DLL,NM,2 set the current texture coordinates. glTexCoord2dv,OPENGL.DLL,NM,1 set the current texture coordinates. initially empty. glTexCoord2dv,OPENGL32.DLL,NM,1 set the current texture coordinates. glRasterPos2d,OPENGL.DLL,NM,2 specify the raster position for pixel operations. glTexCoord2f,OPENGL.DLL,NM,2 set the current texture coordinates. glRasterPos2d,OPENGL32.DLL,NM,2 specify the raster position for pixel operations. glTexCoord2f,OPENGL32.DLL,NM,2 set the current texture coordinates. glRasterPos2dv,OPENGL.DLL,NM,1 specify the raster position for pixel operations. glTexCoord2fv,OPENGL.DLL,NM,1 set the current texture coordinates. glRasterPos2dv,OPENGL32.DLL,NM,1 specify the raster position for pixel operations. glTexCoord2fv,OPENGL32.DLL,NM,1 set the current texture coordinates. glRasterPos2f,OPENGL.DLL,NM,2 specify the raster position for pixel operations. glTexCoord2i,OPENGL.DLL,NM,2 set the current texture coordinates. glRasterPos2f,OPENGL32.DLL,NM,2 specify the raster position for pixel operations. glTexCoord2i,OPENGL32.DLL,NM,2 set the current texture coordinates. glRasterPos2fv,OPENGL.DLL,NM,1 specify the raster position for pixel operations. glTexCoord2iv,OPENGL.DLL,NM,1 set the current texture coordinates. glRasterPos2fv,OPENGL32.DLL,NM,1 specify the raster position for pixel operations. glTexCoord2iv,OPENGL32.DLL,NM,1 set the current texture coordinates. glRasterPos2i,OPENGL.DLL,NM,2 specify the raster position for pixel operations. glTexCoord2s,OPENGL.DLL,NM,2 set the current texture coordinates. glRasterPos2i,OPENGL32.DLL,NM,2 specify the raster position for pixel operations. glTexCoord2s,OPENGL32.DLL,NM,2 set the current texture coordinates. glRasterPos2iv,OPENGL.DLL,NM,1 specify the raster position for pixel operations. glTexCoord2sv,OPENGL.DLL,NM,1 set the current texture coordinates. glRasterPos2iv,OPENGL32.DLL,NM,1 specify the raster position for pixel operations. glTexCoord2sv,OPENGL32.DLL,NM,1 set the current texture coordinates. glRasterPos2s,OPENGL.DLL,NM,2 specify the raster position for pixel operations. glTexCoord3d,OPENGL.DLL,NM,3 set the current texture coordinates. glRasterPos2s,OPENGL32.DLL,NM,2 specify the raster position for pixel operations. glTexCoord3d,OPENGL32.DLL,NM,3 set the current texture coordinates. glRasterPos2sv,OPENGL.DLL,NM,1 specify the raster position for pixel operations. glTexCoord3dv,OPENGL.DLL,NM,1 set the current texture coordinates. glRasterPos2sv,OPENGL32.DLL,NM,1 specify the raster position for pixel operations. glTexCoord3dv,OPENGL32.DLL,NM,1 set the current texture coordinates. glRasterPos3d,OPENGL.DLL,NM,3 specify the raster position for pixel operations. glTexCoord3f,OPENGL.DLL,NM,3 set the current texture coordinates. glRasterPos3d,OPENGL32.DLL,NM,3 specify the raster position for pixel operations. glTexCoord3f,OPENGL32.DLL,NM,3 set the current texture coordinates. glRasterPos3dv,OPENGL.DLL,NM,1 specify the raster position for pixel operations. glTexCoord3fv,OPENGL.DLL,NM,1 set the current texture coordinates. glRasterPos3dv,OPENGL32.DLL,NM,1 specify the raster position for pixel operations. glTexCoord3fv,OPENGL32.DLL,NM,1 set the current texture coordinates. glRasterPos3f,OPENGL.DLL,NM,3 specify the raster position for pixel operations. glTexCoord3i,OPENGL.DLL,NM,3 set the current texture coordinates. glRasterPos3f,OPENGL32.DLL,NM,3 specify the raster position for pixel operations. glTexCoord3i,OPENGL32.DLL,NM,3 set the current texture coordinates. glRasterPos3fv,OPENGL.DLL,NM,1 specify the raster position for pixel operations. glTexCoord3iv,OPENGL.DLL,NM,1 set the current texture coordinates. glRasterPos3fv,OPENGL32.DLL,NM,1 specify the raster position for pixel operations. glTexCoord3iv,OPENGL32.DLL,NM,1 set the current texture coordinates. glRasterPos3i,OPENGL.DLL,NM,3 specify the raster position for pixel operations. 135 glTexCoord3s,OPENGL.DLL,NM,3 set the current texture coordinates. glTexCoord3s,OPENGL32.DLL,NM,3 set the current texture coordinates. glTexCoord3sv,OPENGL.DLL,NM,1 set the current texture coordinates. glTexCoord3sv,OPENGL32.DLL,NM,1 set the current texture coordinates. glTexCoord4d,OPENGL.DLL,NM,4 set the current texture coordinates. glTexCoord4d,OPENGL32.DLL,NM,4 set the current texture coordinates. glTexCoord4dv,OPENGL.DLL,NM,1 set the current texture coordinates. glTexCoord4dv,OPENGL32.DLL,NM,1 set the current texture coordinates. glTexCoord4f,OPENGL.DLL,NM,4 set the current texture coordinates. glTexCoord4f,OPENGL32.DLL,NM,4 set the current texture coordinates. glTexCoord4fv,OPENGL.DLL,NM,1 set the current texture coordinates. glTexCoord4fv,OPENGL32.DLL,NM,1 set the current texture coordinates. glTexCoord4i,OPENGL.DLL,NM,4 set the current texture coordinates. glTexCoord4i,OPENGL32.DLL,NM,4 set the current texture coordinates. glTexCoord4iv,OPENGL.DLL,NM,1 set the current texture coordinates. glTexCoord4iv,OPENGL32.DLL,NM,1 set the current texture coordinates. glTexCoord4s,OPENGL.DLL,NM,4 set the current texture coordinates. glTexCoord4s,OPENGL32.DLL,NM,4 set the current texture coordinates. glTexCoord4sv,OPENGL.DLL,NM,1 set the current texture coordinates. glTexCoord4sv,OPENGL32.DLL,NM,1 set the current texture coordinates. glTexCoordPointer,OPENGL.DLL,NM,4, defines an array of texture coordinates. glTexCoordPointer,OPENGL32.DLL,NM,4, defines an array of texture coordinates. glTexEnvf,OPENGL.DLL,NM,3 set texture environment parameters. glTexEnvf,OPENGL32.DLL,NM,3 set texture environment parameters. glTexEnvfv,OPENGL.DLL,NM,3 set texture environment parameters. glTexEnvfv,OPENGL32.DLL,NM,3 set texture environment parameters. glTexEnvi,OPENGL.DLL,NM,3 set texture environment parameters. glTexEnvi,OPENGL32.DLL,NM,3 set texture environment parameters. glTexEnviv,OPENGL.DLL,NM,3 set texture environment parameters. glTexEnviv,OPENGL32.DLL,NM,3 set texture environment parameters. glTexGend,OPENGL.DLL,NM,2 control the generation of texture coordinates. glTexGend,OPENGL32.DLL,NM,2 control the generation of texture coordinates. glTexGendv,OPENGL.DLL,NM,3 control the generation of texture coordinates. glTexGendv,OPENGL32.DLL,NM,3 control the generation of texture coordinates. glTexGenf,OPENGL.DLL,NM,3 control the generation of texture coordinates. glTexGenf,OPENGL32.DLL,NM,3 control the generation of texture coordinates. glTexGenfv,OPENGL.DLL,NM,3 control the generation of texture coordinates. glTexGenfv,OPENGL32.DLL,NM,3 control the generation of texture coordinates. glTexGeni,OPENGL.DLL,NM,3 control the generation of texture coordinates. glTexGeni,OPENGL32.DLL,NM,3 control the generation of texture coordinates. glTexGeniv,OPENGL.DLL,NM,3 control the generation of texture coordinates. glTexGeniv,OPENGL32.DLL,NM,3 control the generation of texture coordinates. glTexImage1D,OPENGL.DLL,NM,4 specifies a one-dimensional texture image. glTexImage1D,OPENGL32.DLL,NM,4 specifies a one-dimensional texture image. glTexImage2D,OPENGL.DLL,NM,9, specifies a two-dimensional texture image. glTexImage2D,OPENGL32.DLL,NM,9, specifies a two-dimensional texture image. glTexParameterf,OPENGL.DLL,NM,3 set texture parameters. glTexParameterf,OPENGL32.DLL,NM,3 set texture parameters. glTexParameterfv,OPENGL.DLL,NM,3 set texture parameters. glTexParameterfv,OPENGL32.DLL,NM,3 set texture parameters. glTexParameteri,OPENGL.DLL,NM,3 set texture parameters. glTexParameteri,OPENGL32.DLL,NM,3 set texture parameters. glTexParameteriv,OPENGL.DLL,NM,3 set texture parameters. glTexParameteriv,OPENGL32.DLL,NM,3 set texture parameters. glTexSubImage1D,OPENGL.DLL,NM,7, specifies a portion of an existing one-dimensional texture image. glTexSubImage1D,OPENGL32.DLL,NM,7, specifies a portion of an existing one-dimensional texture image.. glTexSubImage2D,OPENGL.DLL,NM,9, specifies a portion of an existing one-dimensional texture image. glTexSubImage2D,OPENGL32.DLL,NM,9, specifies a portion of an existing one-dimensional texture image. glTranslated,OPENGL.DLL,NM,3 multiply the current matrix by a translation matrix. glTranslated,OPENGL32.DLL,NM,3 multiply the current matrix by a translation matrix. glTranslatef,OPENGL.DLL,NM,3 multiply the current matrix by a translation matrix. glTranslatef,OPENGL32.DLL,NM,3 multiply the current matrix by a translation matrix. gluBeginCurve,GLU32.DLL,NM,1 delimit a NURBS curve definition. gluBeginPolygon,GLU32.DLL,NM,1 delimit a polygon description. gluBeginSurface,GLU32.DLL,NM,1 delimit a NURBS surface definition. gluBeginTrim,GLU32.DLL,NM,1 delimit a NURBS trimming loop definition. gluBuild1DMipmaps,GLU32.DLL,NM,6 creates 1-D mipmaps. gluBuild2DMipmaps,GLU32.DLL,NM,7, creates 2-D mipmaps. gluCylinder,GLU32.DLL,NM,9, draws a cylinder. gluDeleteNurbsRenderer,GLU32.DLL,NM,1, destroys a NURBS object. gluDeleteQuadric,GLU32.DLL,NM,1, destroys a quadric object. gluDeleteTess,GLU32.DLL,NM,1, destroys a tessellation object. gluDisk,GLU32.DLL,NM,7, draws a disk. gluEndCurve,GLU32.DLL,NM,1 delimit a NURBS curve definition. gluEndPolygon,GLU32.DLL,NM,1 delimit a polygon description. gluEndSurface,GLU32.DLL,NM,1 delimit a NURBS surface definition. gluEndTrim,GLU32.DLL,NM,1 delimit a NURBS trimming loop definition. gluErrorString,GLU32.DLL,NM,1 produces an error string from an OpenGL or GLU error code. gluGetNurbsProperty,GLU32.DLL,NM,3, gets a NURBS property. gluLoadSamplingMatrices,GLU32.DLL,NM,4, loads NURBS sampling and culling matrices. gluLookAt,GLU32.DLL,NM,18, defines a viewing transformation. gluNewNurbsRenderer,GLU32.DLL,NM,0, creates a NURBS object. gluNewQuadric,GLU32.DLL,NM,0, creates a quadric object. gluNewTess,GLU32.DLL,NM,0, creates a tessellation object. gluNextContour,GLU32.DLL,NM,2, marks the beginning of another contour. gluNurbsCallback,GLU32.DLL,NM,3, defines a callback for a NURBS object. gluNurbsCurve,GLU32.DLL,NM,7, defines the shape of a NURBS curve. gluNurbsProperty,GLU32.DLL,NM,3, sets a NURBS property. gluNurbsSurface,GLU32.DLL,NM,11, defines the shape of a NURBS surface. gluOrtho2D,GLU32.DLL,NM,8, defines a 2-D orthographic projection matrix. gluPartialDisk,GLU32.DLL,NM,11, draws an arc of a disk. gluPerspective,GLU32.DLL,NM,8, sets up a perspective projection matrix. gluPickMatrix,GLU32.DLL,NM,9, defines a picking region. gluProject,GLU32.DLL,NM,12, maps object coordinates to window coordinates. gluPwlCurve,GLU32.DLL,NM,5, describes a piecewise linear NURBS trimming curve. gluQuadricCallback,GLU32.DLL,NM,3, defines a callback for a quadric object. gluQuadricDrawStyle,GLU32.DLL,NM,2, specifies the draw style for quadrics rendered with qobj. gluQuadricNormals,GLU32.DLL,NM,2, specifies what kind of normals are to be used for quadrics. gluQuadricOrientation,GLU32.DLL,NM,2, specifies inside or outside orientation for quadrics. gluQuadricTexture,GLU32.DLL,NM,2, specifies whether quadrics are to be textured. gluScaleImage,GLU32.DLL,NM,9, scales an image to an arbitrary size. gluSphere,GLU32.DLL,NM,5, draws a sphere. gluTessCallback,GLU32.DLL,NM,3, defines a callback for a tessellation object. gluTessVertex,GLU32.DLL,NM,3, describes a vertex on a polygon that the user is defining. gluUnProject,GLU32.DLL,NM,12, maps window coordinates to object coordinates. glVertex2d,OPENGL.DLL,NM,2 specify a vertex. glVertex2d,OPENGL32.DLL,NM,2 specify a vertex. glVertex2dv,OPENGL.DLL,NM,1 specify a vertex. glVertex2dv,OPENGL32.DLL,NM,1 specify a vertex. glVertex2f,OPENGL.DLL,NM,2 specify a vertex. glVertex2f,OPENGL32.DLL,NM,2 specify a vertex. glVertex2fv,OPENGL.DLL,NM,1 specify a vertex. glVertex2fv,OPENGL32.DLL,NM,1 specify a vertex. glVertex2i,OPENGL.DLL,NM,2 specify a vertex. glVertex2i,OPENGL32.DLL,NM,2 specify a vertex. glVertex2iv,OPENGL.DLL,NM,1 specify a vertex. glVertex2iv,OPENGL32.DLL,NM,1 specify a vertex. glVertex2s,OPENGL.DLL,NM,2 specify a vertex. glVertex2s,OPENGL32.DLL,NM,2 specify a vertex. glVertex2sv,OPENGL.DLL,NM,1 specify a vertex. glVertex2sv,OPENGL32.DLL,NM,1 specify a vertex. glVertex3d,OPENGL.DLL,NM,3 specify a vertex. glVertex3d,OPENGL32.DLL,NM,3 specify a vertex. glVertex3dv,OPENGL.DLL,NM,1 specify a vertex. glVertex3dv,OPENGL32.DLL,NM,1 specify a vertex. glVertex3f,OPENGL.DLL,NM,3 specify a vertex. glVertex3f,OPENGL32.DLL,NM,3 specify a vertex. glVertex3fv,OPENGL.DLL,NM,1 specify a vertex. glVertex3fv,OPENGL32.DLL,NM,1 specify a vertex. glVertex3i,OPENGL.DLL,NM,3 specify a vertex. glVertex3i,OPENGL32.DLL,NM,3 specify a vertex. glVertex3iv,OPENGL.DLL,NM,1 specify a vertex. glVertex3iv,OPENGL32.DLL,NM,1 specify a vertex. glVertex3s,OPENGL.DLL,NM,3 specify a vertex. glVertex3s,OPENGL32.DLL,NM,3 specify a vertex. glVertex3sv,OPENGL.DLL,NM,1 specify a vertex. glVertex3sv,OPENGL32.DLL,NM,1 specify a vertex. glVertex4d,OPENGL.DLL,NM,4 specify a vertex. glVertex4d,OPENGL32.DLL,NM,4 specify a vertex. glVertex4dv,OPENGL.DLL,NM,1 specify a vertex. glVertex4dv,OPENGL32.DLL,NM,1 specify a vertex. glVertex4f,OPENGL.DLL,NM,4 specify a vertex. glVertex4f,OPENGL32.DLL,NM,4 specify a vertex. glVertex4fv,OPENGL.DLL,NM,1 specify a vertex. glVertex4fv,OPENGL32.DLL,NM,1 specify a vertex. glVertex4i,OPENGL.DLL,NM,4 specify a vertex. glVertex4i,OPENGL32.DLL,NM,4 specify a vertex. glVertex4iv,OPENGL.DLL,NM,1 specify a vertex. glVertex4iv,OPENGL32.DLL,NM,1 specify a vertex. glVertex4s,OPENGL.DLL,NM,4 specify a vertex. glVertex4s,OPENGL32.DLL,NM,4 specify a vertex. glVertex4sv,OPENGL.DLL,NM,1 specify a vertex. glVertex4sv,OPENGL32.DLL,NM,1 specify a vertex. glVertexPointer,OPENGL.DLL,NM,4, defines an array of vertex data. glVertexPointer,OPENGL32.DLL,NM,4, defines an array of vertex data. glViewport,OPENGL.DLL,NM,4, sets the viewport. glViewport,OPENGL32.DLL,NM,4, sets the viewport. GopherCreateLocator,WININET.DLL,AW,7,Creates a Gopher or Gopher+ locator string from the selector string's component parts. GopherFindFirstFile,WININET.DLL,AW,6,Uses a Gopher locator and search criteria to create a session with the server and locate the requested documents, binary files, index servers, or directory trees. GopherGetAttribute,WININET.DLL,AW,8,Retrieves the specific attribute information from the server. GopherGetLocatorType,WININET.DLL,AW,2,Parses a Gopher locator and determines its attributes. GopherOpenFile,WININET.DLL,AW,5,Begins reading a Gopher data file from a Gopher server. GrayString,USER32.DLL,AW,9, draws gray text at the specified location. Heap32First,TOOLHELP.DLL,NM,3, retrieves information about the first block of a heap that has been allocated by a process. Heap32ListFirst,TOOLHELP.DLL,NM,2, retrieves information about the first heap that has been allocated by a specified process. Heap32ListNext,TOOLHELP.DLL,NM,2, retrieves information about the next heap that has been allocated by a process. Heap32Next,TOOLHELP.DLL,NM,1, retrieves information about the next block of a heap that has been allocated by a process. HeapAlloc,KERNEL32.DLL,NM,3, allocates a block of memory from a heap. HeapCompact,KERNEL32.DLL,NM,2, attempts to compact a specified heap. HeapCreate,KERNEL32.DLL,NM,3, creates a heap object that can be used by the calling process. HeapDestroy,KERNEL32.DLL,NM,1, destroys the specified heap object. HeapFree,KERNEL32.DLL,NM,3, frees a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function. HeapLock,KERNEL32.DLL,NM,1, attempts to acquire the critical section object, or lock, that is associated with a specified heap. HeapReAlloc,KERNEL32.DLL,NM,4, reallocates a block of memory from a heap. HeapSize,KERNEL32.DLL,NM,3, returns the size, in bytes, of a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function. HeapUnlock,KERNEL32.DLL,NM,1, releases ownership of the critical section object, or lock, that is associated with a specified heap. HeapValidate,KERNEL32.DLL,NM,3, attempts to validate a specified heap. HeapWalk,KERNEL32.DLL,NM,2, enumerates the memory blocks in a specified heap. HexFromBin,MAPI32.DLL,NM,3, converts a binary number into a string representation of a hexadecimal number. HideCaret,USER32.DLL,NM,1, removes the caret from the screen. HiliteMenuItem,USER32.DLL,NM,4, highlights or removes the highlighting from an item in a menu bar. HlinkClone,HLINK.DLL,NM,5, HlinkClone Function Not currently supported. HlinkCreateBrowseContext,HLINK.DLL,NM,3, Creates an empty, default instance of the system browse context object. HlinkCreateExtensionServices,HLINK.DLL,NM,7, HlinkCreateExtensionServices Function Not currently supported. HlinkCreateFromData,HLINK.DLL,NM,6, Creates a standard hyperlink object from a Component Object Model (COM) object that supports the IDataObject interface. HlinkCreateFromMoniker,HLINK.DLL,NM,8, Creates a new system hyperlink object from a moniker, a location string, and a friendly name string (used for displaying the hyperlink). HlinkCreateFromString,HLINK.DLL,NM,8, Creates a new hyperlink object from strings representing the hyperlink target, the location within the target, and a friendly name. HlinkCreateShortcut,HLINK.DLL,NM,6,FromString HlinkCreateShortcutFromString Function Not currently supported. HlinkCreateShortcutFromMoniker,HLINK.DLL,NM,7, HlinkCreateShortcutFromMoniker Function Not currently supported. 136 htons,WSOCK32.DLL,NM,1 converts a u_short from host toTCP/IP network byte order. HlinkCreateShortcutFromString,HLINK.DLL,NM,7, HlinkCreateShortcutFromString Function HttpAddRequestHeaders,WININET.DLL,AW,4,Adds one or more HTTP request headers to the Not currently supported. HTTP request handle. HlinkGetSpecialReference,HLINK.DLL,NM,2, Retrieves a string for a given value from the HttpEndRequest,WININET.DLL,AW,4,Ends an HTTP request that was initiated by HLSR enumeration. HttpSendRequestEx. HlinkGetValueFromParams,HLINK.DLL,NM,3, HlinkGetValueFromParams Function Not HttpOpenRequest,WININET.DLL,AW,8,Creates an HTTP request handle. currently supported. HlinkGoBack,URLMON.DLL,NM,1, Executes a hyperlink jump backward within the navigation HttpQueryInfo,WININET.DLL,AW,5,Retrieves header information associated with an HTTP request. stack. HlinkGoForward,URLMON.DLL,NM,1, Executes a hyperlink jump forward within the navigation HttpSendRequest,WININET.DLL,AW,5,Sends the specified request to the HTTP server. HttpSendRequestEx,WININET.DLL,AW,5,Sends the specified request to the HTTP server. stack. ICClose,MSVFW32.DLL,NM,1, closes a compressor or decompressor. HlinkIsShortcut,HLINK.DLL,NM,1, HlinkIsShortcut Function Not currently supported. ICCompressorChoose,MSVFW32.DLL,NM,6, displays a dialog box in which a user can select a HlinkNavigate,HLINK.DLL,NM,6,String Executes a hyperlink jump, specified by a string, to a compressor. new document or object. For information about how this function relates to ICCompressorFree,MSVFW32.DLL,NM,1, frees the resources in the COMPVARS structure HlinkSimpleNavigateToString, see the Remarks section. HlinkNavigateMoniker,URLMON.DLL,NM,2, Executes a hyperlink jump, specified by a moniker, used by other VCM functions. ICGetDisplayFormat,MSVFW32.DLL,NM,6, determines the best format available for displaying to a new document or object. For information about how this function relates to the a compressed image. HlinkSimpleNavigateToMoniker function, see the Remarks section. HlinkNavigateString,URLMON.DLL,NM,2, Executes a hyperlink jump, specified by a string, to a ICGetInfo,MSVFW32.DLL,NM,3, obtains information about a compressor. ICImageCompress,MSVFW32.DLL,NM,7, compresses an image to a given size. new document or object. For information about how this function relates to ICImageDecompress,MSVFW32.DLL,NM,5, decompresses an image without using initialization HlinkSimpleNavigateToString, see the Remarks section. functions. HlinkNavigateToStringReference,HLINK.DLL,NM,9, Creates a hyperlink site from strings representing the hyperlink target, the location within the target, and a friendly name, and then ICInfo,MSVFW32.DLL,NM,3, retrieves information about specific installed compressors or enumerates the installed compressors. navigates to that site. HlinkOnNavigate,HLINK.DLL,NM,7, Notifies a hyperlink browse context and hyperlink frame, if ICInstall,MSVFW32.DLL,NM,5, installs a new compressor or decompressor. ICLocate,MSVFW32.DLL,NM,5 finds a compressor or decompressor that can handle images it exists, that a hyperlink target has been navigated to. with the specified formats, or finds a driver that can decompress an image with a specified HlinkOnRenameDocument,HLINK.DLL,NM,4, HlinkOnRenameDocument Function Not format directly to hardware. currently supported. IcmpCloseHandle,ICMP.DLL,NM,1,closes a handle opened by a call to IcmpCreateFile. HlinkParseDisplayName,HLINK.DLL,NM,5, HlinkParseDisplayName Function Not currently IcmpCreateFile,ICMP.DLL,NM,0, opens a handle on which ICMP Echo Requests can be supported. issued. HlinkPreprocessMoniker,HLINK.DLL,NM,3, HlinkPreprocessMoniker Function Not currently IcmpParseReplies,ICMP.DLL,NM,2, parses the reply buffer provided and returns the number of supported. ICMP responses found. HlinkQueryCreateFromData,HLINK.DLL,NM,1, Determines if a new hyperlink can be created IcmpSendEcho,ICMP.DLL,NM,8,sends an ICMP Echo request and returns any replies. from an IDataObject interface. IcmpSendEcho2,ICMP.DLL,NM,11,sends an ICMP Echo request and returns either HlinkResolveMonikerForData,HLINK.DLL,NM,7, HlinkResolveMonikerForData Function Not immediately (if Event or ApcRoutine is non-NULL) or returns after the specified time-out. currently supported. HlinkResolveShortcut,HLINK.DLL,NM,6,ToString HlinkResolveShortcutToString Function Not ICOpen,MSVFW32.DLL,NM,3, opens a compressor or decompressor. ICOpenFunction,MSVFW32.DLL,NM,4, opens a compressor or decompressor defined as a currently supported. HlinkResolveShortcutToMoniker,HLINK.DLL,NM,3, HlinkResolveShortcutToMoniker Function function. ICRemove,MSVFW32.DLL,NM,3, removes an installed compressor. Not currently supported. HlinkResolveShortcutToString,HLINK.DLL,NM,3, HlinkResolveShortcutToString Function Not ICSendMessage,MSVFW32.DLL,NM,4, sends a message to a compressor. ICSeqCompressFrame,MSVFW32.DLL,NM,5, compresses one frame in a sequence of frames. currently supported. ICSeqCompressFrameEnd,MSVFW32.DLL,NM,1 ends sequence compression thatwas initiated HlinkResolveStringForData,HLINK.DLL,NM,7, HlinkResolveStringForData Function Not by using the ICSeqCompressFrameStart andICSeqCompressFrame functions. currently supported. ICSeqCompressFrameStart,MSVFW32.DLL,NM,2 initializes resources forcompressing a HlinkSetSpecialReference,HLINK.DLL,NM,2, Inserts a string into a specified member of the sequence of frames using the ICSeqCompressFramefunction. HLSR enumeration. HlinkSimpleNavigateToMoniker,URLMON.DLL,NM,8, Executes a hyperlink jump, specified by a IIDFromString,OLE32.DLL,NM,2,4.2 IIDFromString This function converts a string generated by the function back into the original interface identifier (IID). WINOLEAPI moniker, to a new document or object. For information about how this function relates to the ImageAddCertificate,IMAGEHLP.DLL,NM,3, is used to add a certificate to the specified file. HlinkNavigateMoniker function, see the Remarks section. ImageDirectoryEntryToData,IMAGEHLP.DLL,NM,4, obtains access to image-specific data. HlinkSimpleNavigateToString,URLMON.DLL,NM,8, Executes a hyperlink jump to a new document or object. For information about how this function relates to HlinkNavigateString, see ImageEnumerateCertificates,IMAGEHLP.DLL,NM,5, is used to return information about the certificates currently contained in an image file. the Remarks section. ImageGetCertificateData,IMAGEHLP.DLL,NM,4, is used to retrieve a complete certificate from HlinkTranslateURL,HLINK.DLL,NM,3, HlinkTranslateURL Function Not currently supported. a file. HlinkUpdateStackItem,HLINK.DLL,NM,6, HlinkUpdateStackItem Function Not currently ImageGetCertificateHeader,IMAGEHLP.DLL,NM,3, is used to retrieve the header of the supported. specified certificate, up to, but not including, the section offset array. HrAddColumns,MAPI32.DLL,NM,4 adds or moves columns to the beginning of an existing ImageGetDigestStream,IMAGEHLP.DLL,NM,5, retrieves the requested data from the specified table. HrAddColumnsEx,MAPI32.DLL,NM,5, adds or moves columns to the beginning of an existing image file. ImagehlpApiVersion,IMAGEHLP.DLL,NM,0, retrieves the information about the version of the table. library installed on the system. HrAllocAdviseSink,MAPI32.DLL,NM,3 creates an advise sink object, givena context specified ImagehlpApiVersionEx,IMAGEHLP.DLL,NM,1, modifies the information about the version of the by the calling implementation and a callbackfunction to be triggered by an event notification. library used by the application. HrBackupClose,EDBBCLI.DLL,NM,1, closes the file that is being backed up. ImageList_Add,COMCTL32.DLL,NM,3, adds an image or images to an image list. HrBackupEnd,EDBBCLI.DLL,NM,1, cleans up after a backup operation is finished. ImageList_AddIcon,COMCTL32.DLL,NM,2, adds an icon to an image list. HrBackupGetBackupLogs,EDBBCLI.DLL,AW,3, obtains the list of log files to back up. HrBackupGetDatabaseNames,EDBBCLI.DLL,AW,3, obtains the list of attached databases on ImageList_AddMasked,COMCTL32.DLL,NM,3, copies the bitmap to an internal data structure. ImageList_BeginDrag,COMCTL32.DLL,NM,4, begins dragging an image. the remote computer. HrBackupOpenFile,EDBBCLI.DLL,AW,4 opens a remote file for backup and performs whatever ImageList_Create,COMCTL32.DLL,NM,5, creates a new image list. ImageList_Destroy,COMCTL32.DLL,NM,1, destroys an image list. client and server side operations are necessary to prepare for the backup. ImageList_DragEnter,COMCTL32.DLL,NM,3 locks updates to the specifiedwindow during a HrBackupPrepare,EDBBCLI.DLL,AW,5, connects to a remote Microsoft Exchange Server drag operation and displays the drag image at thespecified position within the window. database and prepares it for backup. ImageList_DragLeave,COMCTL32.DLL,NM,1, unlocks the specified window and hides the drag HrBackupRead,EDBBCLI.DLL,NM,4, reads one block from a backup file. image, allowing the window to be updated. HrBackupTruncateLogs,EDBBCLI.DLL,NM,1, deletes the committed database log files. HrComposeEID,MAPI32.DLL,NM,7, creates a compound entry identifier for an object, usually a ImageList_DragMove,COMCTL32.DLL,NM,2, moves the image that is being dragged during a drag-and-drop operation. message in a message store. HrComposeMsgID,MAPI32.DLL,NM,6 creates an ASCII string representing acompound entry ImageList_DragShowNolock,COMCTL32.DLL,NM,1, shows or hides the image being dragged. ImageList_Draw,COMCTL32.DLL,NM,6, draws an image list item in the specified device identifier for an object, usually a message in amessage store. context. HrDecomposeEID,MAPI32.DLL,NM,7 separates the compound entry identifier of an object, usually a message in a message store, into the entry identifier of that object within the store and ImageList_DrawEx,COMCTL32.DLL,NM,10, draws an image list item in the specified device context. the store's entry identifier. HrDecomposeMsgID,MAPI32.DLL,NM,6 separates the ASCII representation of the compound ImageList_DrawIndirect,COMCTL32.DLL,NM,1,Draws an image list image based on an IMAGELISTDRAWPARAMS structure entry identifier of an object, usually a message in a message store, into the entry identifier of ImageList_Duplicate,COMCTL32.DLL,NM,1,Creates a duplicate of an existing image list. that object within the store and the store's entry identifier. ImageList_EndDrag,COMCTL32.DLL,NM,0, ends a drag operation. HrDispatchNotifications,MAPI32.DLL,NM,1, forces dispatching of all queued notifications. ImageList_GetBkColor,COMCTL32.DLL,NM,1, retrieves the current background color for an HrEntryIDFromSz,MAPI32.DLL,NM,3, recreates an entry identifier from its ASCII encoding. image list. HrGetOneProp,MAPI32.DLL,NM,3 retrieves the value of a single propertyfrom a property ImageList_GetDragImage,COMCTL32.DLL,NM,2, retrieves the temporary image list that is interface, that is, an interface derived fromIMAPIProp. used for the drag image. HrIStorageFromStream,MAPI32.DLL,NM,4, layers an IStorage interface onto an IStream ImageList_GetIcon,COMCTL32.DLL,NM,3, creates an icon or cursor based on an image and object. mask in an image list. HrQueryAllRows,MAPI32.DLL,NM,6 retrieves all rows of a table. ImageList_GetIconSize,COMCTL32.DLL,NM,3, retrieves the dimensions of images in an image HrRestoreEnd,EDBBCLI.DLL,NM,1, cleans up after a restore operation has been performed. HrRestoreGetDatabaseLocations,EDBBCLI.DLL,AW,3, obtains the database locations for the list. ImageList_GetImageCount,COMCTL32.DLL,NM,1, retrieves the number of images in an image server and service. list. HrRestorePrepare,EDBBCLI.DLL,AW,3, connects to a remote Microsoft Exchange Server ImageList_GetImageInfo,COMCTL32.DLL,NM,3, retrieves information about an image. database and prepares it for restore. ImageList_LoadImage,COMCTL32.DLL,AW,7 Creates an image list from the specified bitmap. HrRestoreRegister,EDBBCLI.DLL,AW,8 registers a restore operation, interlocking all ImageList_Merge,COMCTL32.DLL,NM,6, creates a new image by combining two existing subsequent restore operations and preventing the restore target from starting until images. HrRestoreRegisterComplete is called. ImageList_Read,COMCTL32.DLL,NM,1, reads an image list from a stream. HrRestoreRegisterComplete,EDBBCLI.DLL,NM,2 completes a restore operation, allowing ImageList_Remove,COMCTL32.DLL,NM,2, removes an image from an image list. subsequent restore operations. ImageList_Replace,COMCTL32.DLL,NM,4, replaces an image in an image list with a new HrSetCurrentBackupLog,EDBBCLI.DLL,AW,3, sets the last log number that was backed up. HrSetOneProp,MAPI32.DLL,NM,2, sets or changes the value of a single property on a property image. ImageList_ReplaceIcon,COMCTL32.DLL,NM,3, replaces an image with an icon. interface, that is, an interface derived from IMAPIProp . ImageList_SetBkColor,COMCTL32.DLL,NM,2, sets the background color for an image list. HrSzFromEntryID,MAPI32.DLL,NM,3, encodes an entry identifier into an ASCII string. ImageList_SetDragCursorImage,COMCTL32.DLL,NM,4 creates a new drag imageby HrThisThreadAdviseSink,MAPI32.DLL,NM,2, creates an advise sink that wraps an existing combining the specified image (typically a mouse cursor image)with the current drag image. advise sink for thread safety. HrValidateIPMSubtree,MAPI32.DLL,NM,5, adds standard interpersonal message (IPM) folders ImageList_SetIconSize,COMCTL32.DLL,NM,3, sets the dimensions of images in an image list and removes all images from the list. to a message store. ImageList_SetImageCount,COMCTL32.DLL,NM,2,Resizes an existing image list. htonl,WS2_32.DLL,NM,1 converts a u_long from host toTCP/IP network byte order. ImageList_SetOverlayImage,COMCTL32.DLL,NM,3, adds a specified image to the list of htonl,WSOCK32.DLL,NM,1 converts a u_long from host toTCP/IP network byte order. images to be used as overlay masks. htons,WS2_32.DLL,NM,1 converts a u_short from host toTCP/IP network byte order. 137 ImageList_Write,COMCTL32.DLL,NM,2, writes an image list to a stream. ImageLoad,IMAGEHLP.DLL,NM,2, maintains a list of loaded DLLs. ImageNtHeader,IMAGEHLP.DLL,NM,1, locates the IMAGE_NT_HEADERS structure in a PE image and returns a pointer to the data. ImageRemoveCertificate,IMAGEHLP.DLL,NM,2, is used to remove the specified certificate from the given file. ImageRvaToSection,IMAGEHLP.DLL,NM,3, locates a relative virtual address (RVA) within the image header of a file that is mapped as a file and returns a pointer to the section table entry for that RVA. ImageRvaToVa,IMAGEHLP.DLL,NM,4, locates a relative virtual address (RVA) within the image header of a file that is mapped as a file and returns the virtual address of the corresponding byte in the file. ImageUnload,IMAGEHLP.DLL,NM,1, is used to deallocate resources from a previous call to the ImageLoad function. ImmAssociateContext,IMM32.DLL,NM,2, associates the specified input context with the specified window. ImmAssociateContextEx,IMM32.DLL,NM,3, changes the association between the input method context and the specified window or its children. ImmConfigureIME,IMM32.DLL,AW,4, displays the configuration dialog box for the IME of the specified input locale identifier (HKL). ImmCreateContext,IMM32.DLL,NM,0, creates a new input context, allocating memory for the context and initializing it. ImmCreateIMCC,IMM32.DLL,NM,1, (Windows CE .NET Application Development)This function enables an input method editor (IME) to create a new input method context (IMC) component that is a member of an IMC. (Windows CE .NET 4.2) ImmDestroyContext,IMM32.DLL,NM,1, releases the input context and frees any memory associated with it. ImmDestroyIMCC,IMM32.DLL,NM,1, Handle to the IMC component. ImmDisableIME,IMM32.DLL,NM,1, disables the input method editor (IME) for a thread or all threads in a process. ImmEnumInputContext,IMM32.DLL,NM,3, retrieves the input context for the specified thread. ImmEnumRegisterWord,IMM32.DLL,AW,6 enumerates the register strings having the specified reading string, style, and register string. ImmEscape,IMM32.DLL,AW,4, accesses capabilities of particular IMEs that are not available through other IMM APIs. and is used mainly for country-specific operations. ImmGenerateMessage,IMM32.DLL,NM,1,This function enables an input method editor (IME) to generate messages that are sent to the window associated with the input method context (IMC). ImmGetCandidateList,IMM32.DLL,AW,4, retrieves a specified candidate list, copying the list to the specified buffer. ImmGetCandidateListCount,IMM32.DLL,AW,2 retrieves the size of the candidate lists. ImmGetCandidateWindow,IMM32.DLL,NM,3, gets information about the candidate list window. ImmGetCompositionFont,IMM32.DLL,AW,2 retrieves information about the logical font currently used to display characters in the composition window. ImmGetCompositionString,IMM32.DLL,AW,4, retrieves information about the composition string. ImmGetCompositionWindow,IMM32.DLL,NM,2 retrieves information about the composition window. ImmGetContext,IMM32.DLL,NM,1, retrieves the input context associated with the specified window. ImmGetConversionList,IMM32.DLL,AW,6, retrieves the conversion result list of characters or words without generating any IME-related messages. ImmGetConversionStatus,IMM32.DLL,NM,3, gets the current conversion status. ImmGetDefaultIMEWnd,IMM32.DLL,NM,1, gets the default window handle to the IME class. ImmGetDescription,IMM32.DLL,AW,3, copies the description of the IME to the specified buffer. ImmGetGuideLine,IMM32.DLL,AW,4 retrieves information about errors. ImmGetHotKey,IMM32.DLL,NM,4, This function retrieves the value of the input method editor (IME) hot key. ImmGetIMCCLockCount,IMM32.DLL,NM,1, Handle to the IMC component. ImmGetIMCCSize,IMM32.DLL,NM,1, Handle to the IMC component. ImmGetIMCLockCount,IMM32.DLL,NM,1,This function enables an input method editor (IME) to get the lock count of the input method context (IMC). ImmGetIMEFileName,IMM32.DLL,AW,3, gets the filename of the IME associated with the specified keyboard layout. ImmGetImeMenuItems,IMM32.DLL,AW,6, retrieves the menu items that are registered in the IME menu of a specified input context. ImmGetOpenStatus,IMM32.DLL,NM,1, checks whether the IME is open or closed. ImmGetProperty,IMM32.DLL,NM,2, gets the property and capabilities of the IME associated with the specified keyboard layout. ImmGetRegisterWordStyle,IMM32.DLL,AW,3, gets a list of the styles support by the IME associated with the specified keyboard layout. ImmGetStatusWindowPos,IMM32.DLL,NM,2, gets the position of the status window. ImmGetVirtualKey,IMM32.DLL,NM,1 recovers the original virtual-keyvalue associated with a key input message that has already beenprocessed by the IME. ImmInstallIME,IMM32.DLL,AW,2, installs an IME into the system. ImmIsIME,IMM32.DLL,NM,1, checks whether the specified handle identifies an IME. ImmIsUIMessage,IMM32.DLL,AW,4, checks for messages intended for the IME window and sends those messages to the specified window. ImmLockIMC,IMM32.DLL,NM,1,C This function enables an input method editor (IME) to get a pointer to an input method context (IMC) component that can be a member of the IMC. ImmLockIMCC,IMM32.DLL,NM,1, This function enables an input method editor (IME) to get a pointer to an input method context (IMC) component that can be a member of the IMC. ImmNotifyIME,IMM32.DLL,NM,4, notifies the IME about changes to the status of the input context. ImmRegisterWord,IMM32.DLL,AW,4, registers a string into the dictionary of the IME associated with the specified input locale. ImmReleaseContext,IMM32.DLL,NM,2, releases the input context and unlocks the memory associated in the context. ImmReSizeIMCC,IMM32.DLL,NM,2,This function changes the size of an input method context (IMC) component. ImmSetCandidateWindow,IMM32.DLL,NM,2, sets information about the candidate list window. ImmSetCompositionFont,IMM32.DLL,AW,2, sets the logical font to be used to display characters in the composition window. ImmSetCompositionString,IMM32.DLL,AW,6, sets the characters, attributes, and clauses of the composition and reading strings. ImmSetCompositionWindow,IMM32.DLL,NM,2, causes a IMN_SETSCOMPOSITIONWINDOW message to be sent to the application. ImmSetConversionStatus,IMM32.DLL,NM,3 sets the current conversion status. ImmSetHotKey,IMM32.DLL,NM,4,This function is called by the IME control panel application to set the value of the input method editor (IME) hot key. ImmSetOpenStatus,IMM32.DLL,NM,2, opens or closes the IME. ImmSetStatusWindowPos,IMM32.DLL,NM,2, sets the position of the status window. ImmSimulateHotKey,IMM32.DLL,NM,2 simulates the specified IME hot key,causing the same response as if the user had pressed the hot key inthe specified window. ImmUnlockIMC,IMM32.DLL,NM,1, Handle to the IMC. (Windows CE .NET 4.2) ImmUnlockIMCC,IMM32.DLL,NM,1,This function reduces the lock count for the input method context (IMC) component. ImmUnregisterWord,IMM32.DLL,AW,4 removes a register string from thedictionary of the IME associated with the specified keyboardlayout. ImpersonateDdeClientWindow,USER32.DLL,NM,2 enables a Dynamic Data Exchange (DDE) server application to impersonate a DDE client application's security context. ImpersonateLoggedOnUser,ADVAPI32.DLL,NM,1, lets the calling thread impersonate a user. ImpersonateNamedPipeClient,ADVAPI32.DLL,NM,1, impersonates a named-pipe client application. ImpersonateSecurityContext,SECUR32.DLL,NM,1,Allows a server to impersonate a client by using a token previously obtained by a call to AcceptSecurityContext (General) or QuerySecurityContextToken. ImpersonateSelf,ADVAPI32.DLL,NM,1, obtains an access token that impersonates the security context of the calling process. ImportNtmsDatabase,NTMSAPI.DLL,NM,1, causes RSM to import the database files from the database Export directory at the next restart of the RSM. ImportSecurityContext,SECUR32.DLL,AW,4,Imports a security context. The security context must have been exported to the process calling ImportSecurityContext by a previous call to ExportSecurityContext. InetIsOffline,URL.DLL,NM,1,Determines whether or not the system is connected to the Internet. inet_addr,WS2_32.DLL,NM,1, converts a string containing an (Ipv4) Internet Protocol dotted address into a proper address for the IN_ADDR structure. inet_addr,WSOCK32.DLL,NM,1, converts a string containing an (Ipv4) Internet Protocol dotted address into a proper address for the IN_ADDR structure. inet_ntoa,WS2_32.DLL,NM,1 converts an (Ipv4) Internet network address into a string in Internet standard dotted format. inet_ntoa,WSOCK32.DLL,NM,1 converts an (Ipv4) Internet network address into a string in Internet standard dotted format. InflateRect,USER32.DLL,NM,3, increases or decreases the width and height of the specified rectangle. InitAtomTable,KERNEL32.DLL,NM,1, initializes the local atom table and sets it to the specified size. InitCommonControls,COMCTL32.DLL,NM,0 Registers and initializes the common control window classes. This function is obsolete. InitCommonControlsEx,COMCTL32.DLL,NM,1,Registers specific common control classes from the common control dynamic-link library InitializeAcl,ADVAPI32.DLL,NM,3, creates a new ACL structure. InitializeCriticalSection,KERNEL32.DLL,NM,1, initializes a critical section object. InitializeFlatSB,COMCTL32.DLL,NM,1,Initializes flat scroll bars for a particular window. InitializeProcessForWsWatch,PSAPI.DLL,NM,1, initiates monitoring of the working set of the specified process. You must call this function before calling the GetWsChanges function. InitializeSecurityContext,SECUR32.DLL,AW,12,Initiates the client side, outbound security context from a credential handle by using the Negotiate security package. InitializeSecurityDescriptor,ADVAPI32.DLL,NM,2, initializes a new security descriptor. InitializeSid,ADVAPI32.DLL,NM,3 initializes a security identifier (SID). InitiateSystemShutdown,ADVAPI32.DLL,AW,5, displays a dialog box that notifies the user that the system is shutting down. InitSecurityInterface,SECUR32.DLL,AW,0, returns a pointer to an SSPI dispatch table. This function enables clients to use SSPI without binding directly to an implementation of the interface. InjectNtmsCleaner,NTMSAPI.DLL,NM,5, allows a cleaner cartridge to be inserted into the specified library unit. InjectNtmsMedia,NTMSAPI.DLL,NM,4, allows media to be inserted into the port of the specified library. If the library is busy, RSM queues InjectNtmsMedia and returns success. InSendMessage,USER32.DLL,NM,0 specifies whether the current windowprocedure is processing a message that was sent from another threadby a call to the SendMessage function. InsertMenu,USER32.DLL,AW,5, inserts a new menu item into a menu, moving other items down the menu. InsertMenuItem,USER32.DLL,AW,4, inserts a new menu item at the specified position in a menu. InstallColorProfile,MSCMS.DLL,AW,2, installs a given profile for use on a specified machine. The profile is also copied to the COLOR directory. InterlockedCompareExchange,KERNEL32.DLL,NM,3 performs an atomic comparison of the values specified in the Destination and Comperand parameters and exchange of the values, based on the outcome of the comparison. InterlockedDecrement,KERNEL32.DLL,NM,1 both decrements (decreases byone) the value of the specified 32-bit variable and checks theresulting value. InterlockedExchange,KERNEL32.DLL,NM,2, atomically exchanges a pair of 32- bit values. InterlockedExchangeAdd,KERNEL32.DLL,NM,2, performs an atomic addition of the Increment value to the value pointed to by Addend. InterlockedIncrement,KERNEL32.DLL,NM,1 both increments (increases by one) the value of the specified 32-bit variable and checks the resulting value. InternetAttemptConnect,WININET.DLL,NM,1,Attempts to make a connection to the Internet. InternetAutodial,WININET.DLL,NM,2,Causes the modem to automatically dial the default Internet connection. InternetAutodialHangup,WININET.DLL,NM,1,Disconnects an automatic dial-up connection. InternetCanonicalizeUrl,WININET.DLL,AW,4,Canonicalizes a URL, which includes converting unsafe characters and spaces into escape sequences. InternetCheckConnection,WININET.DLL,AW,3,Allows an application to check if a connection to the Internet can be established. InternetCloseHandle,WININET.DLL,NM,1,Closes a single Internet handle. InternetCombineUrl,WININET.DLL,AW,5,Combines a base and relative URL into a single URL. The resultant URL is canonicalized (see InternetCanonicalizeUrl). InternetConfirmZoneCrossing,WININET.DLL,AW,4,Checks for changes between secure and nonsecure URLs. Always inform the user when a change occurs in security between two URLs. Typically, an application should allow the user to acknowledge the change through interaction with a dialog box. InternetConnect,WININET.DLL,AW,8,Opens an File Transfer Protocol (FTP), Gopher, or HTTP session for a given site. InternetCrackUrl,WININET.DLL,AW,4,Cracks a URL into its component parts. InternetCreateUrl,WININET.DLL,AW,4,Creates a URL from its component parts. InternetDial,WININET.DLL,NM,5,Initiates a connection to the Internet using a modem. InternetErrorDlg,WININET.DLL,NM,5,Displays a dialog box for the error that is passed to InternetErrorDlg, if an appropriate dialog box exists. InternetFindNextFile,WININET.DLL,AW,2,Continues a file search started as a result of a previous call to FtpFindFirstFile or GopherFindFirstFile. InternetGetConnectedState,WININET.DLL,NM,2,Retrieves the connected state of the local system. InternetGetConnectedStateEx,WININET.DLL,NM,4,Retrieves the connected state of the specified Internet connection. InternetGetCookie,WININET.DLL,AW,4,Retrieves the cookie for the specified URL. InternetGetLastResponseInfo,WININET.DLL,AW,3,Retrieves the last error description or server response on the thread calling this function. InternetGoOnline,WININET.DLL,NM,3,Prompts the user for permission to initiate connection to a URL. InternetHangUp,WININET.DLL,NM,2,Instructs the modem to disconnect from the Internet. InternetLockRequestFile,WININET.DLL,NM,2,Places a lock on the file that is being used. InternetOpen,WININET.DLL,AW,5,Initializes an application's use of the WinINet functions. InternetOpenUrl,WININET.DLL,AW,6,Opens a resource specified by a complete FTP, Gopher, or HTTP URL. InternetQueryDataAvailable,WININET.DLL,NM,4,Queries the server to determine the amount of data available. 138 joyGetNumDevs,WINMM.DLL,NM,0, queries the joystick driver for the number of joysticks it InternetQueryOption,WININET.DLL,AW,4,Queries an Internet option on the specified handle. supports. InternetReadFile,WININET.DLL,NM,4,Reads data from a handle opened by the joyGetPos,WINMM.DLL,NM,2, queries a joystick for its position and button status InternetOpenUrl, FtpOpenFile, GopherOpenFile, or HttpOpenRequest function. joyGetPosEx,WINMM.DLL,NM,2, queries a joystick for its position and button status. InternetReadFileEx,WININET.DLL,AW,4,Reads data from a handle opened by the joyGetThreshold,WINMM.DLL,NM,2, queries a joystick for its current movement threshold. InternetOpenUrl or HttpOpenRequest function. joyReleaseCapture,WINMM.DLL,NM,1, releases the specified captured joystick. InternetSetCookie,WININET.DLL,AW,3,Creates a cookie associated with the specified URL. joySetCapture,WINMM.DLL,NM,4 captures a joystick by causing itsmessages to be sent to the InternetSetDialState,WININET.DLL,NM,3,This function is obsolete. Do not use. specified window. InternetSetFilePointer,WININET.DLL,NM,5,Sets a file position for InternetReadFile. This is a synchronous call; however, subsequent calls to InternetReadFile might block or return pending joySetThreshold,WINMM.DLL,NM,2, sets the movement threshold of a joystick. keybd_event,USER32.DLL,NM,4, synthesizes a keystroke. if the data is not available from the cache and the server does not support random access. KillTimer,USER32.DLL,NM,2, destroys the specified timer. InternetSetOption,WININET.DLL,AW,4,Sets an Internet option. LaunchWizard,MAPI32.DLL,NM,5 Call LaunchWizard to add the MSEMS service. InternetSetOptionEx,WININET.DLL,AW,5,Implemented only as a stub that calls the InternetSetOption function; InternetSetOptionEx has no functionality of its own. Do not use this LBItemFromPt,COMCTL32.DLL,NM,4, retrieves the index of the item at the specified point in a list box. function at this time. LCMapString,KERNEL32.DLL,AW,6, maps one character string to another, performing a InternetSetStatusCallback,WININET.DLL,AW,2,Sets up a callback function that WinINet specified locale-dependent transformation. functions can call as progress is made during an operation. InternetTimeFromSystemTime,WININET.DLL,AW,4,Formats a date and time according to the LeaveCriticalPolicySection,USERENV.DLL,NM,1, resumes the background application of policy. This function closes the handle to the policy section. HTTP version 1.0 specification. LeaveCriticalSection,KERNEL32.DLL,NM,1, releases ownership of the specified critical section InternetTimeToSystemTime,WININET.DLL,AW,3,Converts an HTTP time/date string to a object. SYSTEMTIME structure. LHashValOfNameSys,OLEAUT32.DLL,AW,3,Computes a hash value for a name that can then InternetUnlockRequestFile,WININET.DLL,NM,1,Unlocks a file that was locked using be passed to ITypeComp::Bind, ITypeComp::BindType, ITypeLib::FindName, or InternetLockRequestFile. lineAccept,TAPI32.DLL,NM,3, accepts the specified offered call. InternetWriteFile,WININET.DLL,NM,4,Writes data to an open Internet file. lineAddProvider,TAPI32.DLL,AW,3, installs a new telephony service provider into the telephony IntersectClipRect,GDI32.DLL,NM,5 creates a new clipping region fromthe intersection of the system. current clipping region and the specifiedrectangle. lineAddToConference,TAPI32.DLL,NM,2, adds the call specified by hConsultCall to the IntersectRect,USER32.DLL,NM,3 calculates the intersection of two source rectangles and conference call specified by hConfCall. places the coordinates of the intersection rectangle into the destination rectangle. InvalidateRect,USER32.DLL,NM,3, adds a rectangle to the specified window?s update region. lineAgentSpecific,TAPI32.DLL,NM,5 allows the application to accessproprietary handlerspecific functions of the agent handlerassociated with the address. InvalidateRgn,USER32.DLL,NM,3, invalidates the client area within the window. InventoryNtmsLibrary,NTMSAPI.DLL,NM,3, queues an inventory of the specified library. If the lineAnswer,TAPI32.DLL,NM,3, answers the specified offering call. lineBlindTransfer,TAPI32.DLL,AW,3 performs a blind or single-steptransfer of the specified call library is busy, RSM queues InventoryNtmsLibrary and returns success. to the specified destinationaddress. InvertRect,USER32.DLL,NM,2 inverts a rectangle in a window byperforming a logical NOT lineClose,TAPI32.DLL,NM,1, closes the specified open line device. operation on the color values for eachpixel in the rectangle?s interior. lineCompleteCall,TAPI32.DLL,NM,4, specifies how a call that could not be connected normally InvertRgn,GDI32.DLL,NM,2, inverts the colors in the specified region. should be completed instead. ioctlsocket,WS2_32.DLL,NM,3, can be used on any socket in any state. lineCompleteTransfer,TAPI32.DLL,NM,4, completes the transfer of the specified call to the ioctlsocket,WSOCK32.DLL,NM,3, can be used on any socket in any state. party connected in the consultation call. IsAccelerator,OLE32.DLL,NM,4,Determines whether the keystroke maps to an accelerator in lineConfigDialog,TAPI32.DLL,AW,3 causes the provider of the specified line device to display a the given accelerator table. dialog box (attached to hwndOwner of the application) to allow the user to configure parameters IsAsyncMoniker,URLMON.DLL,NM,1, Tests to determine whether a moniker supports related to the line device. asynchronous binding. IsBadCodePtr,KERNEL32.DLL,NM,1, determines whether the calling process has read access lineConfigDialogEdit,TAPI32.DLL,AW,6 causes the provider of the specified line device to display a dialog box (attached to hwndOwner of the application) to allow the user to configure to the memory at the specified address. IsBadHugeReadPtr,KERNEL32.DLL,NM,2, verifies that the calling process has read access to parameters related to the line device. lineConfigProvider,TAPI32.DLL,NM,2, causes a service provider to display its configuration the specified range of memory. IsBadHugeWritePtr,KERNEL32.DLL,NM,2, verifies that the calling process has write access to dialog box. LineDDA,GDI32.DLL,NM,6 determines which pixels should be highlighted for a line defined by the specified range of memory. the specified starting and ending points. IsBadReadPtr,KERNEL32.DLL,NM,2, verifies that the calling process has read access to the lineDeallocateCall,TAPI32.DLL,NM,1, deallocates the specified call handle. specified range of memory. lineDevSpecific,TAPI32.DLL,NM,5, enables service providers to provide access to features not IsBadStringPtr,KERNEL32.DLL,AW,2, verifies that the calling process has read access to a offered by other TAPI functions. range of memory pointed to by a string pointer. lineDevSpecificFeature,TAPI32.DLL,NM,4, enables service providers to provide access to IsBadWritePtr,KERNEL32.DLL,NM,2, verifies that the calling process has write access to the features not offered by other TAPI functions. specified range of memory. lineDial,TAPI32.DLL,AW,3, dials the specified dialable number on the specified call. IsCharAlpha,USER32.DLL,AW,1, determines whether a character is an alphabetic character. lineDrop,TAPI32.DLL,NM,3, drops or disconnects the specified call. IsCharAlphaNumeric,USER32.DLL,AW,1, determines whether a character is either an lineForward,TAPI32.DLL,AW,7 forwards calls destined for the specified address on the alphabetic or a numeric character. specified line, according to the specified forwarding instructions. IsCharLower,USER32.DLL,AW,1, determines whether a character is lowercase. lineGatherDigits,TAPI32.DLL,AW,7 initiates the buffered gathering of digits on the specified call. IsCharUpper,USER32.DLL,AW,1, determines whether a character is uppercase. IsChild,USER32.DLL,NM,2, tests whether a window is a child window or descendant window of lineGenerateDigits,TAPI32.DLL,AW,4 initiates the generation of thespecified digits on the specified call as inband tones using thespecified signaling mode. a specified parent window. lineGenerateTone,TAPI32.DLL,NM,5, generates the specified inband tone over the specified IsClipboardFormatAvailable,USER32.DLL,NM,1, determines whether the clipboard contains call. data in the specified format. lineGetAddressCaps,TAPI32.DLL,AW,6, queries the specified address on the specified line IsColorProfileTagPresent,MSCMS.DLL,NM,3, reports whether a specified International Color device to determine its telephony capabilities. Consortium (ICC) tag is present in the specified color profile. IsColorProfileValid,MSCMS.DLL,NM,2, allows an application to determine whether the specified lineGetAddressID,TAPI32.DLL,AW,5 returns the address identifierassociated with an address in a different format on the specifiedline. profile is a valid International Color Consortium (ICC) profile that can be used for color lineGetAddressStatus,TAPI32.DLL,AW,3, allows an application to query the specified address management. IsDBCSLeadByte,KERNEL32.DLL,NM,1 determines whether a character is alead byte / that is, for its current status. lineGetAgentActivityList,TAPI32.DLL,AW,3 obtains the identities of activities that the application the first byte of a character in a double-byte character set (DBCS). IsDBCSLeadByteEx,KERNEL32.DLL,NM,2 determines whether a character is alead byte / that can select using lineSetAgentActivity to indicate what function the agent is actually performing at the moment. is, the first byte of a character in a double-byte character set (DBCS). lineGetAgentCaps,TAPI32.DLL,AW,5, obtains the agent-related capabilities supported on the IsDebuggerPresent,KERNEL32.DLL,NM,0, indicates whether the calling process is running specified line device. under the context of a debugger. lineGetAgentGroupList,TAPI32.DLL,AW,3 obtains the identities of agent groups (combination of IsDialogMessage,USER32.DLL,AW,2 determines whether a message isintended for the queue, supervisor, skill level, and so on) into which the agent currently logged in on the specified dialog box and, if it is, processes themessage. workstation is permitted to log into on the automatic call distributor. IsDlgButtonChecked,USER32.DLL,NM,2 determines whether a button control has a check lineGetAgentStatus,TAPI32.DLL,AW,3, obtains the agent-related status on the specified mark next to it or whether a three-state button control is grayed, checked, or neither. IsEqualGUID,OLE32.DLL,NM,2, GUID to compare to rguid2. rguid2 [in] GUID to compare to address. lineGetAppPriority,TAPI32.DLL,AW,6 allows an application to determine whether or not it is in rguid1. the handoff priority list for a particular media mode or Assisted Telephony request mode and, if IsIconic,USER32.DLL,NM,1, determines whether the specified window is minimized (iconic). so, its position in the priority list. IsMenu,USER32.DLL,NM,1, determines whether a handle is a menu handle. IsProcessorFeaturePresent,KERNEL32.DLL,NM,1 determines whether thespecified processor lineGetCallInfo,TAPI32.DLL,AW,2, enables an application to obtain fixed information about the specified call. feature is supported by at least one processoron the current machine. lineGetCallStatus,TAPI32.DLL,NM,2, returns the current status of the specified call. IsRectEmpty,USER32.DLL,NM,1, determines whether the specified rectangle is empty. IsTextUnicode,ADVAPI32.DLL,NM,3, determines whether a buffer probably contains a form of lineGetConfRelatedCalls,TAPI32.DLL,NM,2 returns a list of call handles that are part of the same conference call as the specified call. Unicode text. lineGetCountry,TAPI32.DLL,AW,3 fetches the stored dialing rules and other information related IsValidAcl,ADVAPI32.DLL,NM,1 validates an access-control list (ACL). to a specified country, the first country in the country list, or all countries. IsValidCodePage,KERNEL32.DLL,NM,1 determines whether a specified code page isvalid. lineGetDevCaps,TAPI32.DLL,AW,5, queries a specified line device to determine its telephony IsValidIid,OLE32.DLL,NM,1,4.2 IsValidIid This function is obsolete. Last updated on capabilities. Wednesday, April 13, 2005 B) 2005 IsValidInterface,OLE32.DLL,NM,1,4.2 IsValidInterface This function is obsolete. Last updated lineGetDevConfig,TAPI32.DLL,AW,3 returns an "opaque" data structure object, the contents of which are specific to the line (service provider) and device class. on Wednesday, April 13, 2005 B) lineGetIcon,TAPI32.DLL,AW,3 allows an application to retrieve aservice line device-specific (or IsValidLocale,KERNEL32.DLL,NM,2, applies a validity test to a locale identifier. provider-specific) icon fordisplay to the user. IsValidPtrIn,OLE32.DLL,NM,2,4.2 IsValidPtrIn This function is obsolete. Last updated on lineGetID,TAPI32.DLL,AW,6 returns a device identifier for thespecified device class associated Wednesday, April 13, 2005 B) 2005 with the selected line, address,or call. IsValidPtrOut,OLE32.DLL,NM,2,4.2 IsValidPtrOut This function is obsolete. lineGetLineDevStatus,TAPI32.DLL,AW,2, enables an application to query the specified open IsValidSecurityDescriptor,ADVAPI32.DLL,NM,1, determines whether the components of a line device for its current status. security descriptor are valid. IsValidSid,ADVAPI32.DLL,NM,1 validates a SID structure by verifying thatthe revision number lineGetMessage,TAPI32.DLL,NM,3 returns the next TAPI message that is queued for delivery to an application that is using the Event Handle notification mechanism is within a known range and that the number ofsubauthorities is less than the maximum. lineGetNewCalls,TAPI32.DLL,NM,4 returns call handles to calls on aspecified line or address IsValidURL,URLMON.DLL,NM,3, Determines if a specified string is a valid URL. for which the application currently doesnot have handles. IsWindow,USER32.DLL,NM,1, determines whether the specified window handle identifies an lineGetNumRings,TAPI32.DLL,NM,3 determines the number of rings anincoming call on the existing window. IsWindowEnabled,USER32.DLL,NM,1, determines whether the specified window is enabled for given address should ring prior to answeringthe call. lineGetProviderList,TAPI32.DLL,AW,2, returns a list of service providers currently installed in mouse and keyboard input. the telephony system. IsWindowUnicode,USER32.DLL,NM,1, determines whether the specified window is a native lineGetRequest,TAPI32.DLL,AW,3, retrieves the next by-proxy request for the specified request Unicode window. mode. IsWindowVisible,USER32.DLL,NM,1, retrieves the visibility state of the specified window. IsZoomed,USER32.DLL,NM,1, determines whether a window is maximized. joyGetDevCaps,WINMM.DLL,AW,3, queries a joystick to determine its capabilities. 139 LoadModule,KERNEL32.DLL,NM,2, loads and executes an application or creates a new lineGetStatusMessages,TAPI32.DLL,NM,3 enables an application to query which notification instance of an existing application. messages the application is set up to receive for events related to status changes for the LoadPerfCounterTextStrings,LOADPERF.DLL,AW,2, loads performance objects and counters specified line or any of its addresses. from the system that are identified by the specified initialization file. lineGetTranslateCaps,TAPI32.DLL,AW,3, returns address translation capabilities. LoadRegTypeLib,OLEAUT32.DLL,NM,5,4.2 LoadRegTypeLib This function uses registry lineHandoff,TAPI32.DLL,AW,3, gives ownership of the specified call to another application. information to load a type library. HRESULT LoadRegTypeLib( REFGUID rguid, unsigned lineHold,TAPI32.DLL,NM,1, places the specified call on hold. short lineInitialize,TAPI32.DLL,NM,5, is obsolete. lineInitializeEx,TAPI32.DLL,AW,7, initializes the application's use of TAPI for subsequent use of LoadResource,KERNEL32.DLL,NM,2, loads the specified resource into global memory. LoadString,USER32.DLL,AW,4 loads a string resource from the executablefile associated with the line abstraction. a specified module, copies the string into abuffer, and appends a terminating null character. lineMonitorDigits,TAPI32.DLL,NM,2, enables and disables the unbuffered detection of digits LoadTypeLib,OLEAUT32.DLL,NM,2,ExLoads a type library and (optionally) registers it in the received on the call. lineMonitorTones,TAPI32.DLL,NM,3, enables and disables the detection of inband tones on the system registry. LoadTypeLibEx,OLEAUT32.DLL,NM,3,Loads a type library and (optionally) registers it in the call. lineNegotiateAPIVersion,TAPI32.DLL,NM,6, allows an application to negotiate an API version system registry. LoadUserProfile,USERENV.DLL,AW,2, loads the specified user's profile. The profile can be a to use. local user profile or a roaming user profile. lineNegotiateExtVersion,TAPI32.DLL,NM,6 allows an application to negotiate an extension LocalAlloc,KERNEL32.DLL,NM,2, allocates the specified number of bytes from the heap. version to use with the specified line device. lineOpen,TAPI32.DLL,AW,9 opens the line device specified by its deviceidentifier and returns a LocalCompact,KERNEL32.DLL,NM,1, is obsolete. LocalFileTimeToFileTime,KERNEL32.DLL,NM,2 converts a local file time to a file time based line handle for the corresponding openedline device. on the Coordinated Universal Time (UTC). linePark,TAPI32.DLL,AW,4, parks the specified call according to the specified park mode. LocalFlags,KERNEL32.DLL,NM,1 returns information about the specified local memory object. linePickup,TAPI32.DLL,AW,5 picks up a call alerting at the specified destination address and LocalFree,KERNEL32.DLL,NM,1, frees the specified local memory object and invalidates its returns a call handle for the picked-up call. linePrepareAddToConference,TAPI32.DLL,AW,3, prepares an existing conference call for the handle. LocalHandle,KERNEL32.DLL,NM,1 retrieves the handle associated with the specified pointer to addition of another party. a local memory object. lineProxyMessage,TAPI32.DLL,NM,6, is used by a registered proxy request handler to LocalReAlloc,KERNEL32.DLL,NM,3, changes the size or the attributes of a specified local generate TAPI messages related to its role. lineProxyResponse,TAPI32.DLL,NM,3 used by a registered proxy request handler to generate memory object. LocalShrink,KERNEL32.DLL,NM,2, is obsolete. TAPI messages related to its role. lineRedirect,TAPI32.DLL,AW,3, redirects the specified offering call to the specified destination LocalSize,KERNEL32.DLL,NM,1, returns the current size, in bytes, of the specified local memory object. address. lineRegisterRequestRecipient,TAPI32.DLL,NM,4 registers the invokingapplication as a recipient LocalUnlock,KERNEL32.DLL,NM,1, unlocks it and decrements the lock count by one. LockFile,KERNEL32.DLL,NM,5, locks a region in an open file. of requests for the specified requestmode. LockFileEx,KERNEL32.DLL,NM,6, locks a byte range within an open file for shared or exclusive lineReleaseUserUserInfo,TAPI32.DLL,NM,1 informs the service provider that the application access. has processed the user-user information contained in the LINECALLINFO structure, and that LockResource,KERNEL32.DLL,NM,1, locks the specified resource in memory. subsequently received user-user information can now be written into that structure. LockServiceDatabase,ADVAPI32.DLL,NM,1, locks the specified service control manager lineRemoveFromConference,TAPI32.DLL,NM,1, removes the specified call from the database. conference call to which it currently belongs. LockWindowUpdate,USER32.DLL,NM,1, disables or reenables drawing in the specified lineRemoveProvider,TAPI32.DLL,NM,2, removes an existing telephony service provider from window. the telephony system. LogonUser,ADVAPI32.DLL,AW,6, attempts to log a user on to the local was called. lineSecureCall,TAPI32.DLL,NM,1, secures the call from any interruptions or interference that LookupAccountName,ADVAPI32.DLL,AW,7, accepts the name of a system and an account as can affect the call's media stream. lineSendUserUserInfo,TAPI32.DLL,NM,3, sends user-user information to the remote party on input. LookupAccountSid,ADVAPI32.DLL,AW,7, accepts a security identifier (SID) as input. the specified call. lineSetAgentActivity,TAPI32.DLL,NM,3, sets the agent activity code associated with a particular LookupIconIdFromDirectory,USER32.DLL,NM,2, searches through icon or cursor data for the icon or cursor that best fits the current display device. address. lineSetAgentGroup,TAPI32.DLL,NM,3, sets the agent groups into which the agent is logged into LookupIconIdFromDirectoryEx,USER32.DLL,NM,5 searches through icon or cursor data for the icon or cursor that best fits the current display device. on a particular address. lineSetAgentState,TAPI32.DLL,NM,4, sets the agent state associated with a particular address. LookupPrivilegeDisplayName,ADVAPI32.DLL,AW,5, retrieves a displayable name representing a specified privilege. lineSetAppPriority,TAPI32.DLL,AW,6 allows an application to set its priority in the handoff priority list for a particular media mode or Assisted Telephony request mode, or to remove itself LookupPrivilegeName,ADVAPI32.DLL,AW,4 retrieves the name correspondingto the privilege represented on a specific system by a specifiedlocally unique identifier (LUID). from the priority list. lineSetAppSpecific,TAPI32.DLL,NM,2 enables an application to set theapplication-specific field LookupPrivilegeValue,ADVAPI32.DLL,AW,3 retrieves the locally unique identifier (LUID) used on a specified system to locally represent the specified privilege name. of the specified call's call-informationrecord. LookupSecurityDescriptorParts,ADVAPI32.DLL,AW,7, retrieves security information from a selflineSetCallData,TAPI32.DLL,NM,3, sets the CallData member in LINECALLINFO. lineSetCallParams,TAPI32.DLL,NM,5 allows an application to change bearer mode and/or the relative security descriptor. LPropCompareProp,MAPI32.DLL,NM,2, compares two property values to determine if they are rate parameters of an existing call. lineSetCallPrivilege,TAPI32.DLL,NM,2, sets the application's privilege to the specified privilege. equal. lineSetCallQualityOfService,TAPI32.DLL,NM,5 allows the application to attempt to change the LPtoDP,GDI32.DLL,NM,3, converts logical coordinates into device coordinates. quality of service parameters (reserved capacity and performance guarantees) for an existing LsaCallAuthenticationPackage,SECUR32.DLL,NM,7,Used by a logon application to communicate with an authentication package. call. lineSetCallTreatment,TAPI32.DLL,NM,2, sets the sounds a party on a call that is unanswered LsaConnectUntrusted,SECUR32.DLL,NM,1,Establishes an untrusted connection to the LSA server. or on hold hears. LsaDeregisterLogonProcess,SECUR32.DLL,NM,1,Deletes the caller's logon application context lineSetCurrentLocation,TAPI32.DLL,NM,2 sets the location used as the context for address and closes the connection to the LSA server. translation. LsaFreeReturnBuffer,SECUR32.DLL,NM,1,Frees the memory used by a buffer previously lineSetDevConfig,TAPI32.DLL,AW,4 allows the application to restore the configuration of a media stream device on a line device to a setup previously obtained using lineGetDevConfig . allocated by the LSA. LsaLogonUser,SECUR32.DLL,NM,14,Authenticates a security principal's logon data using lineSetLineDevStatus,TAPI32.DLL,NM,3, sets the line device status. stored credentials information. lineSetMediaControl,TAPI32.DLL,NM,12 enables and disables controlactions on the media LsaLookupAuthenticationPackage,SECUR32.DLL,NM,3,Obtains the unique identifier of an stream associated with the specified line,address, or call. authentication package. lineSetMediaMode,TAPI32.DLL,NM,2, changes the call's media mode in its LINECALLINFO LsaRegisterLogonProcess,SECUR32.DLL,NM,3,Establishes a connection to the LSA server structure. and verifies that the caller is a logon application. lineSetNumRings,TAPI32.DLL,NM,3, sets the number of rings that must occur before an LsaRegisterPolicyChangeNotification,SECUR32.DLL,NM,2, registers an event handle with the incoming call is answered. lineSetTerminal,TAPI32.DLL,NM,7 enables an application to specifywhich terminal information local security authority (LSA). This event handle is signaled whenever the indicated LSA policy is modified. related to the specified line, address,or call is to be routed. LsaUnregisterPolicyChangeNotification,SECUR32.DLL,NM,2, disables a previously registered lineSetTollList,TAPI32.DLL,AW,4, manipulates the toll list. lineSetupConference,TAPI32.DLL,AW,6, sets up a conference call for the addition of the third notification event. LSEnumProviders,LSAPI32.DLL,NM,2, returns a unique string for each installed license system party. service provider. lineSetupTransfer,TAPI32.DLL,AW,3, initiates a transfer of the call specified by the hCall LSEnumProviders,MSLSP32.DLL,NM,2, returns a unique string for each installed license parameter. lineShutdown,TAPI32.DLL,NM,1, shuts down the application's usage of the line abstraction of system service provider. LSFreeHandle,LSAPI32.DLL,NM,1, frees the licensing handle context. the API. LSFreeHandle,MSLSP32.DLL,NM,1, frees the licensing handle context. lineSwapHold,TAPI32.DLL,NM,2, swaps the specified active call with the specified call on LSQuery,LSAPI32.DLL,NM,5 returns information about the service provider or the license consultation hold. system context associated with the specified handle obtained by a call to the LSRequest LineTo,GDI32.DLL,NM,3, draws a line from the current position up to, but not including, the function. specified point. lineTranslateAddress,TAPI32.DLL,AW,7, translates the specified address into another format. LSQuery,MSLSP32.DLL,NM,5 returns information about the service provider or the license system context associated with the specified handle obtained by a call to the LSRequest lineUncompleteCall,TAPI32.DLL,NM,2, cancels the specified call completion request on the function. specified line. LSRelease,LSAPI32.DLL,NM,3 requests the license system release. lineUnhold,TAPI32.DLL,NM,1, retrieves the specified held call. lineUnpark,TAPI32.DLL,AW,4, retrieves the call parked at the specified address and returns a LSRelease,MSLSP32.DLL,NM,3 requests that the license system release theNotice:be supported in future releases of Microsoft Windows. call handle for it. LSRequest,LSAPI32.DLL,NM,9, asks that the license system grant the licensing resources so listen,WS2_32.DLL,NM,2,WSAEINVAL was not invoked prior to accept. the calling application can execute. listen,WSOCK32.DLL,NM,2,WSAEINVAL was not invoked prior to accept. LSRequest,MSLSP32.DLL,NM,9, asks that the license system grant the licensing resources so LoadAccelerators,USER32.DLL,AW,2, loads the specified accelerator table. the calling application can execute. LoadBitmap,USER32.DLL,AW,2, loads the specified bitmap resource from a module?s lstrcat,KERNEL32.DLL,AW,2, appends one string to another. executable file. lstrcmp,KERNEL32.DLL,AW,2, compares two character strings. LoadCursor,USER32.DLL,AW,2, loads the specified cursor resource from the executable (. lstrcmpi,KERNEL32.DLL,AW,2, compares two character strings. LoadCursorFromFile,USER32.DLL,AW,1, creates a cursor based on data contained in a file. lstrcpy,KERNEL32.DLL,AW,2, copies a string to a buffer. LoadIcon,USER32.DLL,AW,2, can load only icons of these dimensions. lstrcpyn,KERNEL32.DLL,AW,3, copies a specified number of characters from a source string LoadImage,USER32.DLL,AW,6, loads an icon, cursor, or bitmap. into a buffer. LoadKeyboardLayout,USER32.DLL,AW,2, loads a new keyboard layout into the system. lstrlen,KERNEL32.DLL,AW,1 returns the length in bytes (ANSI version) orcharacters (Unicode LoadLibrary,KERNEL32.DLL,AW,1, maps the specified executable module into the address version) of the specified string (not includingthe terminating null character). space of the calling process. LSUpdate,LSAPI32.DLL,NM,6, updates the synchronization between the licensed application LoadLibraryEx,KERNEL32.DLL,AW,3, maps a specified executable module into the address software and the license system. space of the calling process. LSUpdate,MSLSP32.DLL,NM,6, updates the synchronization between the licensed application LoadMenu,USER32.DLL,AW,2, loads the specified menu resource from the executable (. software and the license system. LoadMenuIndirect,USER32.DLL,AW,1, loads the specified menu template in memory. LZClose,LZ32.DLL,NM,1 closes a file that was opened by using the LZOpenFile function. 140 MessageBoxIndirect,USER32.DLL,AW,1, creates, displays, and operates a message box. LZCopy,LZ32.DLL,NM,2, copies a source file to a destination file. midiConnect,WINMM.DLL,NM,3 connects a MIDI input device to a MIDIthru or output device, or LZDone,LZ32.DLL,NM,0 is obsolete. LZInit,LZ32.DLL,NM,1 allocates memory for the internal datastructures required to decompress connects a MIDI thru device to a MIDIoutput device. midiDisconnect,WINMM.DLL,NM,3 disconnects a MIDI input device from aMIDI thru or output files, and then creates andinitializes them. device, or disconnects a MIDI thru device froma MIDI output device. LZOpenFile,LZ32.DLL,AW,3 creates, opens, reopens, or deletes the specified file. LZRead,LZ32.DLL,NM,3, reads (at most) the specified number of bytes from a file and copies midiInAddBuffer,WINMM.DLL,NM,3 sends an input buffer to a specified opened MIDI input device. them into a buffer. midiInClose,WINMM.DLL,NM,1, closes the specified MIDI input device. LZSeek,LZ32.DLL,NM,3, moves a file pointer a number of bytes from a starting position. midiInGetDevCaps,WINMM.DLL,AW,3, determines the capabilities of a specified MIDI input LZStart,LZ32.DLL,NM,0 is obsolete. device. MakeAbsoluteSD,ADVAPI32.DLL,NM,11 creates a security descriptor inabsolute format by midiInGetErrorText,WINMM.DLL,AW,3, retrieves a textual description for an error identified by using a security descriptor in self-relativeformat as a template. MakeDragList,COMCTL32.DLL,NM,1, changes the specified single-selection list box to a drag the specified error code. midiInGetID,WINMM.DLL,NM,2, gets the device identifier for the given MIDI input device. list box. midiInGetNumDevs,WINMM.DLL,NM,0, retrieves the number of MIDI input devices in the MakeSelfRelativeSD,ADVAPI32.DLL,NM,3 creates a security descriptor inself-relative format system. by using a security descriptor in absoluteformat as a template. midiInMessage,WINMM.DLL,NM,4, sends a message to the MIDI device driver. MakeSignature,SECUR32.DLL,NM,4,Generates a cryptographic checksum of the message, midiInOpen,WINMM.DLL,NM,5, opens a specified MIDI input device. and also includes sequencing information to prevent message loss or insertion. MakeSureDirectoryPathExists,IMAGEHLP.DLL,NM,1, creates all the directories in the specified midiInPrepareHeader,WINMM.DLL,NM,3, prepares a buffer for MIDI input. midiInReset,WINMM.DLL,NM,1, stops input on a given MIDI input device. DirPath, beginning with the root. MapAndLoad,IMAGEHLP.DLL,NM,5, maps an image and preloads data from the mapped file. midiInStart,WINMM.DLL,NM,1, starts MIDI input on the specified MIDI input device. MapDebugInformation,IMAGEHLP.DLL,NM,4, gains access to the debugging information for an midiInStop,WINMM.DLL,NM,1, stops MIDI input on the specified MIDI input device. midiInUnprepareHeader,WINMM.DLL,NM,3, cleans up the preparation performed by the image. midiInPrepareHeader function. MapDialogRect,USER32.DLL,NM,2, converts (maps) the specified dialog box units to screen midiOutCacheDrumPatches,WINMM.DLL,NM,4 requests that an internal MIDIsynthesizer units (pixels). device preload and cache a specified set of key-basedpercussion patches. MapFileAndCheckSum,IMAGEHLP.DLL,AW,3, computes the checksum of the specified file. MapGenericMask,ADVAPI32.DLL,NM,2 maps the generic access rights in an access mask to midiOutCachePatches,WINMM.DLL,NM,4, requests that an internal MIDI synthesizer device preload and cache a specified set of patches. specific and standard access rights. midiOutClose,WINMM.DLL,NM,1, closes the specified MIDI output device. MAPIAdminProfiles,MAPI32.DLL,NM,2, creates a profile administration object. midiOutGetDevCaps,WINMM.DLL,AW,3, queries a specified MIDI output device to determine MAPIAllocateBuffer,MAPI32.DLL,NM,2, allocates a memory buffer. MAPIAllocateMore,MAPI32.DLL,NM,3 allocates a memory buffer that islinked to another buffer its capabilities. midiOutGetErrorText,WINMM.DLL,AW,3, retrieves a textual description for an error identified by previously allocated with theMAPIAllocateBuffer function. the specified error code. MAPIFreeBuffer,MAPI32.DLL,NM,1 frees a memory buffer allocated with a call to the midiOutGetID,WINMM.DLL,NM,2 retrieves the device identifier for the given MIDI output MAPIAllocateBuffer function or the MAPIAllocateMore function. MAPIGetDefaultMalloc,MAPI32.DLL,NM,0, retrieves the address of the default MAPI memory device. midiOutGetNumDevs,WINMM.DLL,NM,0, retrieves the number of MIDI output devices present allocation function. in the system. MAPIInitialize,MAPI32.DLL,NM,1, increments the MAPI subsystem reference count and midiOutLongMsg,WINMM.DLL,NM,3 sends a system-exclusive MIDI message to the specified initializes global data for the MAPI DLL. MIDI output device. MAPIInitIdle,MAPI32.DLL,NM,1, initializes the MAPI idle engine for the calling application. MAPILogonEx,MAPI32.DLL,NM,5 logs a client application on to a session with the messaging midiOutMessage,WINMM.DLL,NM,4, sends a message to the MIDI device drivers. midiOutOpen,WINMM.DLL,NM,5, opens a MIDI output device for playback. system. midiOutPrepareHeader,WINMM.DLL,NM,3, prepares a MIDI system-exclusive or stream buffer MAPIOpenFormMgr,MAPI32.DLL,NM,2, opens an IMAPIFormMgr interface on a form library for output. provider object in the context of an existing session. midiOutReset,WINMM.DLL,NM,1, turns off all notes on all MIDI channels for the specified MIDI MAPIOpenLocalFormContainer,MAPI32.DLL,NM,1, returns an interface pointer to the local output device. form library. MAPIUninitialize,MAPI32.DLL,NM,0, decrements the reference count, -instance global data for midiOutSetVolume,WINMM.DLL,NM,2, sets the volume of a MIDI output device. midiOutShortMsg,WINMM.DLL,NM,2 sends a short MIDI message to the MAPI DLL. MapStorageSCode,MAPI32.DLL,NM,1, maps an HRESULT return value from an OLE storage themidiOutGetVolumespecified MIDI output device. midiOutUnprepareHeader,WINMM.DLL,NM,3, cleans up the preparation performed by the object to a MAPI return value of the SCODE type. midiOutPrepareHeader function. MapViewOfFile,KERNEL32.DLL,NM,5, maps a view of a file into the address space of the midiStreamClose,WINMM.DLL,NM,1, closes an open MIDI stream. calling process. midiStreamOpen,WINMM.DLL,NM,6, opens a MIDI stream for output. MapViewOfFileEx,KERNEL32.DLL,NM,6, maps a view of a file into the address space of the midiStreamOut,WINMM.DLL,NM,3, plays or queues a stream (buffer) of MIDI data to a MIDI calling process. output device. MapVirtualKey,USER32.DLL,AW,2 translates (maps) a virtual-key codeinto a scan code or midiStreamPause,WINMM.DLL,NM,1, pauses playback of a specified MIDI stream. character value, or translates a scan code intoa virtual-key code. MapVirtualKeyEx,USER32.DLL,AW,3 translates (maps) a virtual-key codeinto a scan code or midiStreamPosition,WINMM.DLL,NM,3, retrieves the current position in a MIDI stream. midiStreamProperty,WINMM.DLL,NM,3, sets or retrieves properties of a MIDI data stream character value, or translates a scan code intoa virtual-key code. MapWindowPoints,USER32.DLL,NM,4 converts (maps) a set of points from a coordinate space associated with a MIDI output device. midiStreamRestart,WINMM.DLL,NM,1, restarts a paused MIDI stream. relative to one window to a coordinate space relative to another window. midiStreamStop,WINMM.DLL,NM,1, turns off all notes on all MIDI channels for the specified MaskBlt,GDI32.DLL,NM,12, combines the color data for the source and destination bitmaps MIDI output device. using the specified mask and raster operation. mciDriverNotify,WINMM.DLL,NM,3,MCI drivers call mciDriverNotify to post an MM_MCINOTIFY MIMEAssociationDialog,URL.DLL,AW,6,Runs the unregistered Multipurpose Internet Mail Extensions (MIME) content type dialog box. message to an application. mixerClose,WINMM.DLL,NM,1, closes the specified mixer device. mciDriverYield,WINMM.DLL,NM,1,calls the application’s yield function. The yield function mixerGetControlDetails,WINMM.DLL,AW,3, retrieves details about a single control associated checks to see if the user has pressed the break key. mciFreeCommandResource,WINMM.DLL,NM,1,function frees from memory a command table with an audio line. mixerGetDevCaps,WINMM.DLL,AW,3, queries a specified mixer device to determine its that was loaded with mciLoadCommandResource. mciGetCreatorTask,WINMM.DLL,NM,1, retrieves a handle to the creator task for the specified capabilities. mixerGetID,WINMM.DLL,NM,3, retrieves the device identifier for a mixer device associated with device. mciGetDeviceID,WINMM.DLL,AW,1, retrieves the device identifier corresponding to the name a specified device handle. mixerGetLineControls,WINMM.DLL,AW,3, retrieves one or more controls associated with an of an open device. audio line. mciGetDriverData,WINMM.DLL,NM,1,returns instance-specific information that was set with mixerGetLineInfo,WINMM.DLL,AW,3, retrieves information about a specific line of a mixer mciSetDriverData. mciGetErrorString,WINMM.DLL,AW,3, retrieves a string that describes the specified MCI error device. mixerGetNumDevs,WINMM.DLL,NM,0, retrieves the number of mixer devices present in the code. mciGetYieldProc,WINMM.DLL,NM,2, retrieves the address of the callback function associated system. mixerMessage,WINMM.DLL,NM,4, sends a custom mixer driver message directly to a mixer with the "wait" (MCI_WAIT) flag. mciLoadCommandResource,WINMM.DLL,NM,3,loads the specified resource and registers it as driver. mixerOpen,WINMM.DLL,NM,5 opens a specified mixer device and ensures that the device will an MCI command table. not be removed until the application closes the handle. mciSendCommand,WINMM.DLL,AW,4, sends a command message to the specified MCI mixerSetControlDetails,WINMM.DLL,NM,3, sets properties of a single control associated with device. an audio line. mciSendString,WINMM.DLL,AW,4, sends a command string to an MCI device. MkParseDisplayName,OLE32.DLL,NM,4,Ex Creates a moniker to the object that is specified by mciSetDriverData,WINMM.DLL,NM,2,is used for storing instance-specific information for an the given string. MCI driver. MkParseDisplayNameEx,URLMON.DLL,NM,4, Creates a moniker to the object that is specified mciSetYieldProc,WINMM.DLL,NM,3 sets the address of a procedure to becalled periodically when an MCI device is waiting for a command tofinish because the "wait" (MCI_WAIT) flag was by the given string. mmioAdvance,WINMM.DLL,NM,3, advances the I/O buffer of a file set up for direct I/O buffer specified. access with the mmioGetInfo function. MenuHelp,COMCTL32.DLL,NM,7 processes WM_MENUSELECT and WM_COMMANDmessages and displays help text about the current menu in thespecified status mmioAscend,WINMM.DLL,NM,3 ascends out of a chunk in a RIFF filedescended into with the mmioDescend function or created with themmioCreateChunk function. window. mmioClose,WINMM.DLL,NM,2, closes a file that was opened by using the mmioOpen function. MenuItemFromPoint,USER32.DLL,NM,4, determines which menu item, if any, is at the mmioCreateChunk,WINMM.DLL,NM,3, creates a chunk in a RIFF file that was opened by using specified location. the mmioOpen function. MesBufferHandleReset,RPCRT4.DLL,NM,6, re-initializes the handle for buffer serialization. MesDecodeBufferHandleCreate,RPCRT4.DLL,NM,3, creates a decoding handle and initializes mmioDescend,WINMM.DLL,NM,4, descends into a chunk of a RIFF file that was opened by using the mmioOpen function. it for a (fixed) buffer style of serialization. MesDecodeIncrementalHandleCreate,RPCRT4.DLL,NM,3, creates a decoding handle for the mmioFlush,WINMM.DLL,NM,2, writes the I/O buffer of a file to disk if the buffer has been written to. incremental style of serialization. MesEncodeDynBufferHandleCreate,RPCRT4.DLL,NM,3 creates an encoding handle and then mmioGetInfo,WINMM.DLL,NM,3 retrieves information about a file openedby using the mmioOpen function. initializes it for a dynamic buffer style of serialization. MesEncodeFixedBufferHandleCreate,RPCRT4.DLL,NM,4 creates an encodinghandle and then mmioInstallIOProc,WINMM.DLL,AW,3, maintains a separate list of installed I/O procedures for each Windows application. initializes it for a fixed buffer style ofserialization. mmioOpen,WINMM.DLL,AW,3, opens a file for unbuffered or buffered I/O. MesEncodeIncrementalHandleCreate,RPCRT4.DLL,NM,4, creates an encoding and then mmioRead,WINMM.DLL,NM,3, reads a specified number of bytes from a file opened by using initializes it for the incremental style of serialization. the mmioOpen function. MesHandleFree,RPCRT4.DLL,NM,1, frees the memory allocated by the serialization handle. mmioRename,WINMM.DLL,AW,4, renames the specified file. MesIncrementalHandleReset,RPCRT4.DLL,NM,6, re-initializes the handle for incremental mmioSeek,WINMM.DLL,NM,3, changes the current file position in a file opened by using the serialization. mmioOpen function. MesInqProcEncodingId,RPCRT4.DLL,NM,3 provides the identity of an encoding. mmioSendMessage,WINMM.DLL,NM,4, sends a message to the I/O procedure associated with MessageBeep,USER32.DLL,NM,1, plays a waveform sound. the specified file. MessageBox,USER32.DLL,AW,4, creates, displays, and operates a message box. MessageBoxEx,USER32.DLL,AW,5, creates, displays, and operates a message box. 141 MprAdminPortEnum,MPRAPI.DLL,NM,8, enumerates all active ports in a specific connection, mmioSetBuffer,WINMM.DLL,NM,4 enables or disables buffered I/O, or changes the buffer or or all ports available for use or currently in use by RAS. buffer size for a file opened by using the mmioOpen function. mmioSetInfo,WINMM.DLL,NM,3 updates the information retrieved by themmioGetInfo function MprAdminPortGetInfo,MPRAPI.DLL,NM,4, gets information for a specific port. MprAdminPortReset,MPRAPI.DLL,NM,2, resets the communication device attached to the about a file opened by using the mmioOpenfunction. specified port. mmioStringToFOURCC,WINMM.DLL,AW,2 converts a null-terminated string to a fourMprAdminRegisterConnectionNotification,MPRAPI.DLL,NM,2, registers an event object with the character code. mmioWrite,WINMM.DLL,NM,3 writes a specified number of bytes to a filemmioOpenopened by Demand Dial Manager (DDM) so that, if an interface connects or disconnects, the event is signaled. using the function. MprAdminSendUserMessage,MPRAPI.DLL,NM,3, sends a message to the user connected on ModifyMenu,USER32.DLL,AW,5, changes an existing menu item. ModifyWorldTransform,GDI32.DLL,NM,3, changes the world transformation for a device context the specified connection. MprAdminServerConnect,MPRAPI.DLL,NM,2, establishes a connection to a router for the using the specified mode. Module32First,TOOLHELP.DLL,NM,2, retrieves information about the first module associated purpose of administering that router. MprAdminServerDisconnect,MPRAPI.DLL,NM,1, disconnects the connection made by a with a process. Module32Next,TOOLHELP.DLL,NM,2, retrieves information about the next module associated previous call to MprAdminServerConnect. MprAdminServerGetInfo,MPRAPI.DLL,NM,3, retrieves information about the specified RRAS with a process or thread. server. MonikerCommonPrefixWith,OLE32.DLL,NM,3,This function creates a new moniker based on the common prefix that this moniker (the one comprising the data of this moniker object) shares MprAdminTransportGetInfo,MPRAPI.DLL,NM,6, retrieves global information, default client interface information, or both, for a specified transport. with another moniker. MonikerRelativePathTo,OLE32.DLL,NM,4,4.2 MonikerRelativePathTo This function provides MprAdminTransportSetInfo,MPRAPI.DLL,NM,6, sets global information, or default client a moniker that, when composed onto the end of the first specified moniker (or one with a similar interface information, or both, for a specified transport. MprAdminUserGetInfo,MPRAPI.DLL,NM,4, retrieves all RAS information for a particular user. MountNtmsMedia,NTMSAPI.DLL,NM,7, synchronously mounts one or more pieces of media. MprAdminUserSetInfo,MPRAPI.DLL,NM,4, sets RAS information for the specified user. mouse_event,USER32.DLL,NM,5, synthesizes mouse motion and button clicks. MprConfigBufferFree,MPRAPI.DLL,NM,1,The Routing and Remote Access Service (RRAS) MoveFile,KERNEL32.DLL,AW,2, renames an existing file or a directory (including all its API makes it possible to create applications to administer the routing and remote access children). service capabilities of Microsoft Windows 2003 Server family and Windows Server 2000 MoveFileEx,KERNEL32.DLL,AW,3, renames an existing file or directory. MoveToEx,GDI32.DLL,NM,4, updates the current position to the specified point and optionally operating systems. MprConfigGetFriendlyName,MPRAPI.DLL,NM,4, returns the friendly name for an interface that returns the previous position. corresponds to the specified GUID name. MoveToNtmsMediaPool,NTMSAPI.DLL,NM,3, moves the specified medium from its current MprConfigGetGuidName,MPRAPI.DLL,NM,4, returns the GUID name for an interface that media pool to the specified media pool. corresponds to the specified friendly name. MoveWindow,USER32.DLL,NM,6, changes the position and dimensions of the specified MprConfigInterfaceCreate,MPRAPI.DLL,NM,4, creates a router interface in the specified router window. configuration. MprAdminBufferFree,MPRAPI.DLL,NM,1, frees memory buffers returned by: MprConfigInterfaceDelete,MPRAPI.DLL,NM,2, removes a router interface from the router MprAdminInterfaceGetInfo, MprAdminInterfaceEnum, MprAdminServerGetInfo, configuration. All transport information associated with this interface is also removed. MprAdminInterfaceTransportGetInfo, and MprAdminTransportGetInfo. MprConfigInterfaceEnum,MPRAPI.DLL,NM,7, enumerates the interfaces that are configured for MprAdminConnectionEnum,MPRAPI.DLL,NM,7, enumerates all active connections. the router. MprAdminConnectionGetInfo,MPRAPI.DLL,NM,4, provides information on a specific MprConfigInterfaceGetHandle,MPRAPI.DLL,NM,3, retrieves a handle to the specified connection. interface's configuration in the specified router configuration. MprAdminDeregisterConnectionNotification,MPRAPI.DLL,NM,2, deregisters an event object MprConfigInterfaceGetInfo,MPRAPI.DLL,NM,5, retrieves the configuration for the specified that was previously registered using MprAdminRegisterConnectionNotification. Once interface from the router. deregistered, this event is no longer signaled when an interface connects or disconnects. MprAdminEstablishDomainRasServer,MPRAPI.DLL,NM,3, establishes the given machine as a MprConfigInterfaceSetInfo,MPRAPI.DLL,NM,4, sets the configuration for the specified interface. Remote Access Server in the domain. This function must be executed only on a machine joined MprConfigInterfaceTransportAdd,MPRAPI.DLL,NM,7, adds the specified transport to the specified interface configuration on the router. to a domain. MprAdminGetErrorString,MPRAPI.DLL,NM,2, returns the string associated with a router error MprConfigInterfaceTransportEnum,MPRAPI.DLL,NM,8, enumerates the transports configured on the specified interface. from Mprerror.h. MprAdminGetPDCServer,MPRAPI.DLL,NM,3, retrieves the name of the server with the master MprConfigInterfaceTransportGetHandle,MPRAPI.DLL,NM,4, retrieves a handle to the specified transport configuration on the specified interface in the specified router configuration. User Accounts Subsystem (UAS) from either a domain name or a server name. Either the MprConfigInterfaceTransportGetInfo,MPRAPI.DLL,NM,5, retrieves the configuration information domain name parameter or the server name parameter may be NULL, but not both. for the specified client on the specified interface. MprAdminInterfaceConnect,MPRAPI.DLL,NM,4, creates a connection to the specified WAN MprConfigInterfaceTransportRemove,MPRAPI.DLL,NM,3, removes the specified transport from interface. the specified interface configuration on the router. MprAdminInterfaceCreate,MPRAPI.DLL,NM,4, creates an interface on a specified server. MprConfigInterfaceTransportSetInfo,MPRAPI.DLL,NM,5, updates the configuration information MprAdminInterfaceDelete,MPRAPI.DLL,NM,2, deletes an interface on a specified server. for the client on the specified interface and transport. MprAdminInterfaceDisconnect,MPRAPI.DLL,NM,2, disconnects a connected WAN interface. MprConfigServerBackup,MPRAPI.DLL,NM,2, creates a backup of the router-manager, MprAdminInterfaceEnum,MPRAPI.DLL,NM,7, enumerates all the interfaces on a specified interface, and phone-book configuration for the router. server. MprConfigServerConnect,MPRAPI.DLL,NM,2, connects to the router to be configured. MprAdminInterfaceGetCredentials,MPRAPI.DLL,NM,5,Use the MprAdminInterfaceGetCredentials function to retrieve the domain, user name, and password for MprConfigServerDisconnect,MPRAPI.DLL,NM,1, disconnects a connection made by a previous call to MprConfigServerConnect. dialing out on the specified demand-dial interface. MprAdminInterfaceGetHandle,MPRAPI.DLL,NM,4, retrieves a handle to a specified interface. MprConfigServerGetInfo,MPRAPI.DLL,NM,3, retrieves server-level configuration information for MprAdminInterfaceGetInfo,MPRAPI.DLL,NM,4, retrieves information for a specified interface on the specified router. MprConfigServerRestore,MPRAPI.DLL,NM,2, restores the router-manager, interface, and a specified server. phone-book configuration from a backup created by a previous call to MprConfigServerBackup. MprAdminInterfaceQueryUpdateResult,MPRAPI.DLL,NM,4, returns the result of the last MprConfigTransportCreate,MPRAPI.DLL,NM,9, adds the specified transport to the list of request to a specified router manager to update its routes for a specified interface. For more transports present in the specified router configuration. information, see MprAdminInterfaceUpdateRoutes. MprAdminInterfaceSetCredentials,MPRAPI.DLL,NM,5,Use MprAdminInterfaceSetCredentials MprConfigTransportDelete,MPRAPI.DLL,NM,2, removes the specified transport from the list of transports present in the specified router configuration. function to set the domain, user name, and password that will be used for dialing out on the MprConfigTransportEnum,MPRAPI.DLL,NM,7, enumerates the transports configured on the specified demand-dial interface. router. MprAdminInterfaceSetInfo,MPRAPI.DLL,NM,4, sets information for a specified interface on a MprConfigTransportGetHandle,MPRAPI.DLL,NM,3, retrieves a handle to the specified specified server. MprAdminInterfaceTransportAdd,MPRAPI.DLL,NM,5, adds a transport (for example, IP or IPX) transport's configuration in the specified router configuration. MprConfigTransportGetInfo,MPRAPI.DLL,NM,7, retrieves the configuration for the specified to a specified interface. MprAdminInterfaceTransportGetInfo,MPRAPI.DLL,NM,5, retrieves information about a transport transport from the router. MprConfigTransportSetInfo,MPRAPI.DLL,NM,7, changes the configuration for the specified running on a specified interface. MprAdminInterfaceTransportRemove,MPRAPI.DLL,NM,3, removes a transport (for example, IP transport in the specified router configuration. MprInfoBlockAdd,MPRAPI.DLL,NM,6, creates a new header that is identical to an existing or IPX) from a specified interface. header with the addition of a new block. MprAdminInterfaceTransportSetInfo,MPRAPI.DLL,NM,5, sets information for a transport MprInfoBlockFind,MPRAPI.DLL,NM,5, locates a specified block in an information header, and running on a specified interface. retrieves information about the block. MprAdminInterfaceUpdatePhonebookInfo,MPRAPI.DLL,NM,2, forces the router to pick up changes made on a specified demand-dial interface. Call this function after changes are made MprInfoBlockRemove,MPRAPI.DLL,NM,3, creates a new header that is identical to an existing header with a specified block removed. to a phone-book entry for a demand-dial interface. MprAdminInterfaceUpdateRoutes,MPRAPI.DLL,NM,4, requests a specified router manager to MprInfoBlockSet,MPRAPI.DLL,NM,6,The MprInfoBlockSet creates a new header that is identical to an existing header with a specified block modified. update its routing information for a specified interface. MprAdminIsDomainRasServer,MPRAPI.DLL,NM,3, returns information regarding whether the MprInfoCreate,MPRAPI.DLL,NM,2, creates a new information header. MprInfoDelete,MPRAPI.DLL,NM,1, deletes an information header created using MprInfoCreate, given machine is registered as the remote access server in the domain. or retrieved by MprInfoBlockAdd, MprInfoBlockRemove, or MprInfoBlockSet. MprAdminIsServiceRunning,MPRAPI.DLL,NM,1,, if the calling process has access, checks MprInfoDuplicate,MPRAPI.DLL,NM,2, duplicates an existing information header. whether RRAS is running on a specified machine. MprAdminMIBBufferFree,MPRAPI.DLL,NM,1, frees buffers returned by the following functions: MprInfoRemoveAll,MPRAPI.DLL,NM,2, removes all information blocks from the specified header. MprAdminMIBEntryGet, MprAdminMIBEntryGetFirst, MprAdminMIBEntryGetNext MsgWaitForMultipleObjects,USER32.DLL,NM,5 returns when either any one or all of the MprAdminMIBEntryCreate,MPRAPI.DLL,NM,5, creates an entry for one of the variables specified objects are in the signaled state or The time-out interval elapses. exported by a routing protocol or router manager. MsgWaitForMultipleObjectsEx,USER32.DLL,NM,5 returns when Either any one or all of the MprAdminMIBEntryDelete,MPRAPI.DLL,NM,5, deletes an entry for one of the variables specified objects are in the signaled state or An I/O completion routine or asynchronous exported by a routing protocol or router manager. MprAdminMIBEntryGet,MPRAPI.DLL,NM,7, retrieves the value of one of the variables exported procedure call (APC) is queued to the thread. orThe time-out interval elapses. MulDiv,KERNEL32.DLL,NM,3 multiplies two 32-bit values and then dividesthe 64-bit result by a by a routing protocol or router manager. third 32-rounded up or down to the nearest integer. MprAdminMIBEntryGetFirst,MPRAPI.DLL,NM,7, retrieves the first variable of some set of variables exported by a protocol or router manager. The module that services the call defines MultiByteToWideChar,KERNEL32.DLL,NM,6 maps a character string to a wide-character (Unicode) string. first. MultinetGetConnectionPerformance,MPR.DLL,AW,2 returns informationabout the expected MprAdminMIBEntryGetNext,MPRAPI.DLL,NM,7, retrieves the next variable of some set of variables exported by a protocol or router manager. The module that services the call defines performance of a connection used to access anetwork resource. NetAccessAdd,SVRAPI.DLL,NM,4, is obsolete. next. MprAdminMIBEntrySet,MPRAPI.DLL,NM,5, sets the value of one of the variables exported by a NetAccessCheck,SVRAPI.DLL,NM,5, is obsolete. NetAccessDel,SVRAPI.DLL,NM,2, is obsolete. routing protocol or router manager. MprAdminMIBServerConnect,MPRAPI.DLL,NM,2, establishes a connection to the router being NetAccessEnum,SVRAPI.DLL,NM,8, is obsolete. NetAccessGetInfo,SVRAPI.DLL,NM,6, is obsolete. administered. This call should be made before any other calls to the server. The handle NetAccessGetUserPerms,SVRAPI.DLL,NM,4, is obsolete. returned by this function is used in subsequent MIB calls. NetAccessSetInfo,SVRAPI.DLL,NM,6,s is obsolete. MprAdminMIBServerDisconnect,MPRAPI.DLL,NM,1, disconnects the connection made by a NetAlertRaise,NETAPI32.DLL,NM,3, notifies all registered clients that a particular event previous call to MprAdminMIBServerConnect. occurred. MprAdminPortClearStats,MPRAPI.DLL,NM,2, resets the statistics for the specified port. MprAdminPortDisconnect,MPRAPI.DLL,NM,2, disconnects a connection on a specific port. 142 NetAlertRaiseEx,NETAPI32.DLL,NM,4, simplifies the raising of an Administrators interrupting message. NetApiBufferAllocate,NETAPI32.DLL,NM,2, allocates memory from the heap. NetApiBufferFree,NETAPI32.DLL,NM,1, frees the memory that NetApiBufferAllocate allocates. NetApiBufferReallocate,NETAPI32.DLL,NM,3, changes the size of a buffer allocated with NetApiBufferAllocate. NetApiBufferSize,NETAPI32.DLL,NM,2, returns the size, in bytes, of the allocated buffer using NetApiBufferAllocate. NetAuditClear,NETAPI32.DLL,NM,3 is obsolete. NetAuditRead,NETAPI32.DLL,NM,11, is obsolete. Netbios,NETAPI32.DLL,NM,1, interprets and executes the specified network control block (NCB). NetConfigGet,NETAPI32.DLL,NM,4 is obsolete. NetConfigGetAll,NETAPI32.DLL,NM,3, is obsolete. NetConfigSet,NETAPI32.DLL,NM,7, is obsolete. NetConnectionEnum,NETAPI32.DLL,NM,8 lists all connections made to ashared resource on the server or all connections established from aparticular computer. NetConnectionEnum,SVRAPI.DLL,NM,7 lists all connections made to ashared resource on the server or all connections established from aparticular computer. NetErrorLogClear,NETAPI32.DLL,NM,3, is obsolete. NetErrorLogRead,NETAPI32.DLL,NM,11, is obsolete. NetFileClose,NETAPI32.DLL,NM,2, is obsolete in the Win32-based application programming interface (API). NetFileEnum,NETAPI32.DLL,NM,9 supplies information about some or all open files on a server, allowing the user to supply a resume handle and get required information through repeated calls to the function. NetFileEnum,SVRAPI.DLL,NM,7 returns information about some or all open files on a server, depending on the parameters specified. NetFileGetInfo,NETAPI32.DLL,NM,4, retrieves information about a particular opening of a server resource. NetGetAnyDCName,NETAPI32.DLL,NM,3, gets the name of any domain controller for a domain that is directly trusted by the server name. NetGetDCName,NETAPI32.DLL,NM,3, returns the name of the Primary Domain Controller (PDC) for the specified domain. NetGroupAdd,NETAPI32.DLL,NM,4, creates a global group in the security database. NetGroupAddUser,NETAPI32.DLL,NM,3, gives an existing user account membership in an existing global group. NetGroupDel,NETAPI32.DLL,NM,2, deletes a global group account from the account database. NetGroupDelUser,NETAPI32.DLL,NM,3, removes a user from a particular global group in the security database. NetGroupEnum,NETAPI32.DLL,NM,7, retrieves information about each global group account. NetGroupGetInfo,NETAPI32.DLL,NM,4, retrieves information about a particular global group account on a server. NetGroupGetUsers,NETAPI32.DLL,NM,8, retrieves a list of the members of a particular global group in the security database. NetGroupSetInfo,NETAPI32.DLL,NM,5, sets the parameters of a global group account. NetGroupSetUsers,NETAPI32.DLL,NM,5 sets the global group membership for the specified global group. NetLocalGroupAdd,NETAPI32.DLL,NM,4 creates a local group in the security database. NetLocalGroupAddMember,NETAPI32.DLL,NM,3, is obsolete. NetLocalGroupDel,NETAPI32.DLL,NM,2, deletes a local group account and all its members from the accounts database. NetLocalGroupDelMember,NETAPI32.DLL,NM,3, is obsolete. NetLocalGroupEnum,NETAPI32.DLL,NM,7, retrieves information about each local group account. NetLocalGroupGetInfo,NETAPI32.DLL,NM,4, retrieves information about a particular local group account on a server. NetLocalGroupGetMembers,NETAPI32.DLL,NM,8, retrieves a list of the members of a particular local group in the security database. NetLocalGroupSetInfo,NETAPI32.DLL,NM,5, sets the parameters of a local group. NetLocalGroupSetMembers,NETAPI32.DLL,NM,5, sets the local group membership for the specified local group. NetMessageBufferSend,NETAPI32.DLL,NM,5, sends a buffer of information to a registered message alias. NetMessageNameAdd,NETAPI32.DLL,NM,2, registers a message alias in the message name table. NetMessageNameDel,NETAPI32.DLL,NM,2, deletes a message alias from the table of message aliases on a computer. NetMessageNameEnum,NETAPI32.DLL,NM,7 lists the message aliases that will receive messages on a specified computer. NetMessageNameGetInfo,NETAPI32.DLL,NM,4, retrieves information about a particular message alias in the message name table. NetRemoteTOD,NETAPI32.DLL,NM,2 returns the time of day information from a specified server. NetReplExportDirAdd,NETAPI32.DLL,NM,4 registers an existing directory inthe export path to be replicated. NetReplExportDirDel,NETAPI32.DLL,NM,2, removes registration of a replicated directory. NetReplExportDirEnum,NETAPI32.DLL,NM,7, lists the replicated directories in the export path. NetReplExportDirGetInfo,NETAPI32.DLL,NM,4, retrieves the control information of a replicated directory. NetReplExportDirLock,NETAPI32.DLL,NM,2, locks a replicated directory so that replication from it can be suspended. NetReplExportDirSetInfo,NETAPI32.DLL,NM,5, modifies the control information of a replicated directory. NetReplExportDirUnlock,NETAPI32.DLL,NM,3, unlocks a directory so that replication from it can resume. NetReplGetInfo,NETAPI32.DLL,NM,3, retrieves configuration information for the Replicator service. NetReplImportDirAdd,NETAPI32.DLL,NM,4, registers an existing directory in the import path to receive replication from a master. NetReplImportDirDel,NETAPI32.DLL,NM,2, removes the registration of a directory so that it no longer receives updates from the master. NetReplImportDirEnum,NETAPI32.DLL,NM,7, lists the replicated directories in the import path. NetReplImportDirGetInfo,NETAPI32.DLL,NM,4, retrieves the status information on a client replicated directory. NetReplImportDirLock,NETAPI32.DLL,NM,2, locks a replicated directory so that replication to it can be suspended. NetReplImportDirUnlock,NETAPI32.DLL,NM,3, unlocks a directory so that replication to it can resume. NetReplSetInfo,NETAPI32.DLL,NM,4, modifies the Replicator service configuration information. NetScheduleJobAdd,NETAPI32.DLL,NM,3, submits a job to run at a specified future time and date. NetScheduleJobDel,NETAPI32.DLL,NM,3 deletes a range of jobs queued to, Net Functionsrun at a computer. NetScheduleJobEnum,NETAPI32.DLL,NM,6, lists the jobs queued on a specified computer. NetScheduleJobGetInfo,NETAPI32.DLL,NM,3 retrieves information about a particular job queued on a specified computer. NetServerDiskEnum,NETAPI32.DLL,NM,7, retrieves a list of disk drives on a server. NetServerEnum,NETAPI32.DLL,NM,9, lists all servers of the specified type that are visible in the specified domain. NetServerGetInfo,NETAPI32.DLL,NM,3, retrieves information about the specified server. NetServerGetInfo,SVRAPI.DLL,NM,5, retrieves information about the specified server. NetServerSetInfo,NETAPI32.DLL,NM,4, sets a server?s operating parameters; it can set them individually or collectively. NetServerTransportAdd,NETAPI32.DLL,NM,3, binds the server to the transport. NetServerTransportDel,NETAPI32.DLL,NM,3 unbinds (or disconnects) the transport protocol from the server. NetServerTransportEnum,NETAPI32.DLL,NM,7, supplies information about transports that are managed by the server. NetServiceControl,NETAPI32.DLL,NM,5, is obsolete. NetServiceEnum,NETAPI32.DLL,NM,7 is obsolete. NetServiceGetInfo,NETAPI32.DLL,NM,4, is obsolete. NetServiceInstall,NETAPI32.DLL,NM,5, is obsolete. NetSessionDel,NETAPI32.DLL,NM,3, ends a session between a server and a workstation. NetSessionDel,SVRAPI.DLL,NM,3, ends a session between a server and a workstation. NetSessionEnum,NETAPI32.DLL,NM,9, provides information about all current sessions. NetSessionEnum,SVRAPI.DLL,NM,6, provides information about all current sessions. NetSessionGetInfo,NETAPI32.DLL,NM,5, retrieves information about a session established between a particular server and workstation. NetSessionGetInfo,SVRAPI.DLL,NM,6, retrieves information about a session established between a particular server and workstation. NetShareAdd,NETAPI32.DLL,NM,4, shares a server resource. NetShareAdd,SVRAPI.DLL,NM,4, shares a server resource. NetShareCheck,NETAPI32.DLL,NM,3, checks whether or not a server is sharing a device. NetShareDel,NETAPI32.DLL,NM,3 deletes a share name from a server?s listof shared resources, disconnecting all connections to the sharedresource. NetShareDel,SVRAPI.DLL,NM,3 deletes a share name from a server?s listof shared resources, disconnecting all connections to the sharedresource. NetShareGetInfo,NETAPI32.DLL,NM,4, retrieves information about a particular shared resource on a server. NetShareGetInfo,SVRAPI.DLL,NM,6, retrieves information about a particular shared resource on a server. NetShareSetInfo,NETAPI32.DLL,NM,5 sets the parameters of a shared resource. NetShareSetInfo,SVRAPI.DLL,NM,6 sets the parameters of a shared resource. NetStatisticsGet,NETAPI32.DLL,NM,5 is obsolete. NetUseDel,NETAPI32.DLL,NM,3, is obsolete. NetUseEnum,NETAPI32.DLL,NM,7 is obsolete. NetUseGetInfo,NETAPI32.DLL,NM,4, is obsolete. NetUserAdd,NETAPI32.DLL,NM,4, adds a user account and assigns a password and privilege level. NetUserDel,NETAPI32.DLL,NM,2, deletes a user account from a server. NetUserEnum,NETAPI32.DLL,NM,8, provides information about all user accounts on a server. NetUserGetGroups,NETAPI32.DLL,NM,7, retrieves a list of global groups to which a specified user belongs. NetUserGetInfo,NETAPI32.DLL,NM,4, retrieves information about a particular user account on a server. NetUserGetLocalGroups,NETAPI32.DLL,NM,8, retrieves a list of local groups to which a specified user belongs. NetUserModalsGet,NETAPI32.DLL,NM,3 retrieves global information for all users and global groups in the security database. NetUserModalsSet,NETAPI32.DLL,NM,4, sets global information for all users and global groups in the security database. NetUserSetGroups,NETAPI32.DLL,NM,5 sets global group memberships for a specified user account. NetUserSetInfo,NETAPI32.DLL,NM,5, sets the parameters of a user account. NetWkstaGetInfo,NETAPI32.DLL,NM,3, returns information about the configuration elements for a workstation. NetWkstaSetInfo,NETAPI32.DLL,NM,4, configures a workstation. NetWkstaTransportAdd,NETAPI32.DLL,NM,4, binds (or connects) the redirector to the transport. NetWkstaTransportDel,NETAPI32.DLL,NM,3 unbinds the transport protocolfrom the redirector, which is the software on the client computerwhich generates file requests to the server computer. NetWkstaTransportEnum,NETAPI32.DLL,NM,7 supplies information about transport protocols that are managed by the redirector, which is the software on the client computer that generates file requests to the server computer. NetWkstaUserEnum,NETAPI32.DLL,NM,7, lists information about all users currently logged on to the workstation. NetWkstaUserGetInfo,NETAPI32.DLL,NM,3, returns information about the currently logged-on user. NetWkstaUserSetInfo,NETAPI32.DLL,NM,4, sets the user-specific information about the configuration elements for a workstation. NotifyBootConfigStatus,ADVAPI32.DLL,NM,1, reports the boot status to the service control manager. NotifyChangeEventLog,ADVAPI32.DLL,NM,2 enables an application to receivenotification when an event is written to the specified event logfile. NTExport,DAPI.DLL,AW,1 exports user information from a Windows NTServer domain controller in a form that can later be imported intothe Microsoft Exchange Server directory. ntohl,WS2_32.DLL,NM,1, converts a u_long from TCP/IP network order to host byte order (which is little-endian on Intel processors). ntohl,WSOCK32.DLL,NM,1, converts a u_long from TCP/IP network order to host byte order (which is little-endian on Intel processors). ntohs,WS2_32.DLL,NM,1, converts a u_short from TCP/IP network byte order to host byte order (which is little-endian on Intel processors). ntohs,WSOCK32.DLL,NM,1, converts a u_short from TCP/IP network byte order to host byte order (which is little-endian on Intel processors). NWExport,DAPI.DLL,AW,1 exports user information from a NovellNetWare server in a form that can later be imported into theMicrosoft Exchange Server directory. OaBuildVersion,OLEAUT32.DLL,NM,0, This function retrieves the build version of OLE Automation. WINOLEAUTAPI_(ULONG) OaBuildVersion(void); Return Values The return value is a number that indicates the build number. ObjectCloseAuditAlarm,ADVAPI32.DLL,AW,3, generates audit messages when a handle of an object is deleted. ObjectDeleteAuditAlarm,ADVAPI32.DLL,AW,3, generates audit messages when an object is deleted. ObjectOpenAuditAlarm,ADVAPI32.DLL,AW,12 generates audit messages when aclient application attempts to gain access to an object or tocreate a new one. ObjectPrivilegeAuditAlarm,ADVAPI32.DLL,AW,6, requires the calling process to have SE_AUDIT_NAME privilege. OemKeyScan,USER32.DLL,NM,1, maps OEM ASCII codes 0 through 0x0FF into the OEM scan codes and shift states. OemToChar,USER32.DLL,AW,2, translates a string from the OEM-defined character set into either an ANSI or a wide-character string. OemToCharBuff,USER32.DLL,AW,3 translates a specified number ofcharacters in a string from the OEM-defined character set intoeither an ANSI or a wide-character string. OffsetClipRgn,GDI32.DLL,NM,3, moves the clipping region of a device context by the specified offsets. 143 OleGetIconOfFile,OLE32.DLL,NM,2,Returns a handle to a metafile containing an icon and OffsetRect,USER32.DLL,NM,3, moves the specified rectangle by the specified offsets. string label for the specified file name. OffsetRgn,GDI32.DLL,NM,3, moves a region by the specified offsets. OffsetViewportOrgEx,GDI32.DLL,NM,4, modifies the viewport origin for a device context using OleIconToCursor,OLEAUT32.DLL,NM,2,Converts an icon to a cursor. For Win32 applications, this function calls the Win32 function CopyCursor(hIcon). the specified horizontal and vertical offsets. OleIconToCursor,OLEPRO32.DLL,NM,2,Converts an icon to a cursor. For Win32 applications, OffsetWindowOrgEx,GDI32.DLL,NM,4, modifies the window origin for a device context using this function calls the Win32 function CopyCursor(hIcon). the specified horizontal and vertical offsets. OleInitialize,OLE32.DLL,NM,1,Initializes the COM library on the current apartment, identifies OleConvertIStorageToOLESTREAM,OLE32.DLL,NM,2, converts the specified storage object the concurrency model as single-thread apartment (STA), and enables additional functionality from OLE 2 structured storage to the OLE 1 storage object model but does not include the described in the Remarks section below. presentation data. This is one of several compatibility functions. OleConvertIStorageToOLESTREAMEx,OLE32.DLL,NM,7, converts the specified storage object OleIsCurrentClipboard,OLE32.DLL,NM,1,Determines whether the data object pointer previously placed on the clipboard by the OleSetClipboard function is still on the clipboard. from OLE 2 structured storage to the OLE 1 storage object model, including the presentation OleIsRunning,OLE32.DLL,NM,1,This function determines whether a compound document data. OleConvertOLESTREAMToIStorage,OLE32.DLL,NM,3,Converts the specified object from the object is currently in the running state. OleLoad,OLE32.DLL,NM,4,PicturePathCreates a new picture object and initializes it from the OLE 1 storage model to an OLE 2 structured storage object without specifying presentation contents of a stream. This is equivalent to calling OleCreatePictureIndirect(NULL, ...) followed data. by IPersistStream::Load. OleConvertOLESTREAMToIStorageEx,OLE32.DLL,NM,7, converts the specified object from OleLoadFromStream,OLE32.DLL,NM,3, Loads an object from the stream. the OLE 1 storage model to an OLE 2 structured storage object including presentation data. OleLoadPicture,OLEAUT32.DLL,NM,5,PathCreates a new picture object and initializes it from This is one of several compatibility functions. OleCreate,OLE32.DLL,NM,7,PropertyFrameIndirectCreates a property frame, that is, a property the contents of a stream. This is equivalent to calling OleCreatePictureIndirect(NULL, ...) sheet dialog box, based on a structure (OCPFIPARAMS) that contains the parameters, rather followed by IPersistStream::Load. OleLoadPicture,OLEPRO32.DLL,NM,5,PathCreates a new picture object and initializes it from than specifying separate parameters as when calling OleCreatePropertyFrame. OleCreateDefaultHandler,OLE32.DLL,NM,4,Creates a new instance of the default embedding the contents of a stream. This is equivalent to calling OleCreatePictureIndirect(NULL, ...) followed by IPersistStream::Load. handler. This instance is initialized so it creates a local server when the embedded object OleLoadPicturePath,OLEAUT32.DLL,NM,6,Creates a new picture object and initializes it from enters the running state. OleCreateEmbeddingHelper,OLE32.DLL,NM,6,Creates an OLE embedding helper object using the contents of a stream. This is equivalent to calling OleCreatePictureIndirect(NULL, ...) application-supplied code aggregated with pieces of the OLE default object handler. This helper followed by IPersistStream::Load. OleLockRunning,OLE32.DLL,NM,3,Locks an already running object into its running state or object can be created and used in a specific context and role, as determined by the caller. OleCreateEx,OLE32.DLL,NM,12,Extends OleCreate functionality by supporting more efficient unlocks it from its running state. instantiation of objects in containers requiring caching of multiple presentation formats or data, OleMetafilePictFromIconAndLabel,OLE32.DLL,NM,4,Creates a METAFILEPICT structure that contains a metafile in which the icon and label are drawn. instead of the single format supported OleNoteObjectVisible,OLE32.DLL,NM,2,Increments or decrements an external reference that OleCreateFontIndirect,OLEAUT32.DLL,NM,3, This function creates and initializes a standard keeps an object in the running state. font object using an initial description of the font's properties in a FONTDESC structure. The OleQueryCreateFromData,OLE32.DLL,NM,1,Checks whether a data object has one of the function returns an interface pointer to the new font object specified by caller in the riid formats that would allow it to become an embedded object through a call to either the parameter. OleCreateFontIndirect,OLEPRO32.DLL,NM,3, This function creates and initializes a standard OleCreateFromData or OleQueryLinkFromData,OLE32.DLL,NM,1, determines whether an OLE linked object (rather font object using an initial description of the font's properties in a FONTDESC structure. The than an OLE embedded object) can be created from a clipboard data object. function returns an interface pointer to the new font object specified by caller in the riid OleRegEnumFormatEtc,OLE32.DLL,NM,3,Supplies a pointer to an enumeration object that can parameter. OleCreateFromData,OLE32.DLL,NM,7,Extends OleCreateFromData functionality by supporting be used to enumerate data formats that an OLE object server has registered in the system registry. An object application or object handler calls this function when it must enumerate those more efficient instantiation of objects in containers requiring caching of multiple formats of formats. presentation or data, instead of the single OleRegEnumVerbs,OLE32.DLL,NM,2,Supplies an enumeration of the registered verbs for the OleCreateFromDataEx,OLE32.DLL,NM,12,Extends OleCreateFromData functionality by specified class. Developers of custom DLL object applications use this function to emulate the supporting more efficient instantiation of objects in containers requiring caching of multiple behavior of the default object handler. formats of presentation or data, instead of the single OleRegGetMiscStatus,OLE32.DLL,NM,3,Gets miscellaneous information about the OleCreateFromFile,OLE32.DLL,NM,8,ExExtends OLeCreateFromFile functionality by presentation and behaviors supported by the specified CLSID from the registry. Used by supporting more efficient instantiation of objects in containers requiring caching of multiple developers of custom DLL object applications to emulate the behavior of the OLE default presentation formats or data, instead of the single format handler. OleCreateFromFileEx,OLE32.DLL,NM,13,Extends OLeCreateFromFile functionality by OleRegGetUserType,OLE32.DLL,NM,3,Gets the user type of the specified class from the supporting more efficient instantiation of objects in containers requiring caching of multiple registry. Developers of custom DLL object applications use this function to emulate the behavior presentation formats or data, instead of the single format of the OLE default handler. OleCreateLink,OLE32.DLL,NM,7,ToFileExExtends OleCreateLinkToFile functionality by OleRun,OLE32.DLL,NM,1, This function puts an OLE compound document object into the supporting more efficient instantiation of objects in containers requiring caching of multiple running state. formats of presentations or data, instead of the single OleCreateLinkEx,OLE32.DLL,NM,12,Extends OleCreateLink functionality by supporting more OleSave,OLE32.DLL,NM,3,ToStream Saves an object with the IPersistStream interface on it to the specified stream. efficient instantiation of objects in containers requiring caching of multiple formats of OleSaveToStream,OLE32.DLL,NM,2, Saves an object with the IPersistStream interface on it to presentations or data, instead of the single format OleCreateLinkFromData,OLE32.DLL,NM,7,ExExtends OleCreateLinkFromData functionality by the specified stream. OleSaveToStreamEx,HLINK.DLL,NM,3, OleSaveToStreamEx Function Not currently supporting more efficient instantiation of objects in containers requiring caching of multiple supported. formats of presentations or data, instead of the single OleCreateLinkFromDataEx,OLE32.DLL,NM,12,Extends OleCreateLinkFromData functionality OleSetAutoConvert,OLE32.DLL,NM,2,Specifies a CLSID for automatic conversion to a different by supporting more efficient instantiation of objects in containers requiring caching of multiple class when an object of that class is loaded. OleSetClipboard,OLE32.DLL,NM,1,Places a pointer to a specific data object onto the clipboard. formats of presentations or data, instead of the single This makes the data object accessible to the OleGetClipboard function. OleCreateLinkToFile,OLE32.DLL,NM,7,ExExtends OleCreateLinkToFile functionality by OleSetContainedObject,OLE32.DLL,NM,2, This function notifies an object embedded in an supporting more efficient instantiation of objects in containers requiring caching of multiple OLE container to ensure correct reference. formats of presentations or data, instead of the single OleSetMenuDescriptor,OLE32.DLL,NM,5, This function installs or removes OLE dispatching OleCreateLinkToFileEx,OLE32.DLL,NM,12,Extends OleCreateLinkToFile functionality by code from the containers frame window. supporting more efficient instantiation of objects in containers requiring caching of multiple OleTranslateAccelerator,OLE32.DLL,NM,3,Called by the object application, allows an object's formats of presentations or data, instead of the single OleCreateMenuDescriptor,OLE32.DLL,NM,2,Creates and returns an OLE menu descriptor (that container to translate accelerators according to the container's accelerator table. is, an OLE-provided data structure that describes the menus) for OLE to use when dispatching OleTranslateColor,OLEAUT32.DLL,NM,3,Converts an OLE_COLOR type to a COLORREF. OleTranslateColor,OLEPRO32.DLL,NM,3,Converts an OLE_COLOR type to a COLORREF. menu messages and commands. OleUIAddVerbMenu,OLEDLG.DLL,AW,9,Adds the Verb menu for the specified object to the OleCreatePictureIndirect,OLEAUT32.DLL,NM,4,Creates a new picture object initialized according to a PICTDESC structure, which can be NULL to create an uninitialized object if the given menu. OleUIBusy,OLEDLG.DLL,AW,1, (COM)Invokes the standard Busy dialog box, allowing the user caller wishes to have the picture initialize itself through IPersistStream::Load. to manage concurrency. OleCreatePictureIndirect,OLEPRO32.DLL,NM,4,Creates a new picture object initialized according to a PICTDESC structure, which can be NULL to create an uninitialized object if the OleUICanConvertOrActivateAs,OLEDLG.DLL,NM,3,Determines if there are any OLE object classes in the registry that can be used to convert or activate the specified CLSID from. caller wishes to have the picture initialize itself through IPersistStream::Load. OleUIConvert,OLEDLG.DLL,AW,1, (COM)Invokes the standard Convert dialog box, allowing OleCreatePropertyFrame,OLEAUT32.DLL,NM,11,IndirectCreates a property frame, that is, a property sheet dialog box, based on a structure (OCPFIPARAMS) that contains the parameters, the user to change the type of a single specified object, or the type of all OLE objects of the specified object's class. rather than specifying separate parameters as when calling OleCreatePropertyFrame. OleUIObjectProperties,OLEDLG.DLL,AW,1,Invokes the Object Properties dialog box, which OleCreatePropertyFrame,OLEPRO32.DLL,NM,11,IndirectCreates a property frame, that is, a property sheet dialog box, based on a structure (OCPFIPARAMS) that contains the parameters, displays General, View, and Link information about an object. OleUIUpdateLinks,OLEDLG.DLL,AW,4,Updates all links in the link container and displays a rather than specifying separate parameters as when calling OleCreatePropertyFrame. dialog box that shows the progress of the updating process. The process is stopped if the user OleCreatePropertyFrameIndirect,OLEAUT32.DLL,NM,1,Creates a property frame, that is, a property sheet dialog box, based on a structure (OCPFIPARAMS) that contains the parameters, presses the Stop button or when all links are processed. OleUninitialize,OLE32.DLL,NM,0,Closes the COM library on the apartment, releases any class rather than specifying separate parameters as when calling OleCreatePropertyFrame. factories, other COM objects, or servers held by the apartment, disables RPC on the apartment, OleCreatePropertyFrameIndirect,OLEPRO32.DLL,NM,1,Creates a property frame, that is, a property sheet dialog box, based on a structure (OCPFIPARAMS) that contains the parameters, and frees any resources the apartment maintains. OpenBackupEventLog,ADVAPI32.DLL,AW,2, opens a handle of a backup event log. rather than specifying separate parameters as when calling OleCreatePropertyFrame. OpenClipboard,USER32.DLL,NM,1, opens the clipboard for examination and prevents other OleCreateStaticFromData,OLE32.DLL,NM,7,Creates a static object (containing only a applications from modifying the clipboard content. representation, with no native data) from a data transfer object. OleDestroyMenuDescriptor,OLE32.DLL,NM,1,Called by the container to free the shared menu OpenColorProfile,MSCMS.DLL,AW,4, creates a handle to a specified color profile. The handle can then be used in other profile management functions. descriptor allocated by the OleCreateMenuDescriptor function. OpenDesktop,USER32.DLL,AW,4, returns a handle to an existing desktop. OleDoAutoConvert,OLE32.DLL,NM,2,Automatically converts an object to a new class if OpenEvent,KERNEL32.DLL,AW,3, returns a handle of an existing named event object. automatic conversion for that object class is set in the registry. OpenEventLog,ADVAPI32.DLL,AW,2, opens a handle to an event log. OleDraw,OLE32.DLL,NM,4,The OleDraw helper function can be used to draw objects more OpenFile,KERNEL32.DLL,NM,3, creates, opens, reopens, or deletes a file. easily. You can use it instead of calling IViewObject::Draw directly. OpenFileMapping,KERNEL32.DLL,AW,3, opens a named file-mapping object. OleDuplicateData,OLE32.DLL,NM,3,Duplicates the data found in the specified handle and OpenIcon,USER32.DLL,NM,1, restores a minimized (iconic) window to its previous size and returns a handle to the duplicated data. The source data is in a clipboard format. position; it then activates the window. OleFlushClipboard,OLE32.DLL,NM,0,Carries out the clipboard shutdown sequence. It also OpenIMsgOnIStg,MAPI32.DLL,NM,11 builds a new IMessage object on top ofan existing OLE releases the IDataObject pointer that was placed on the clipboard by the OleSetClipboard IStorage object, to be used within a messagesession. function. OpenIMsgSession,MAPI32.DLL,NM,3 creates and opens a message session that groups the OleGetAutoConvert,OLE32.DLL,NM,2,Determines whether the registry is set for objects of a messages created within it. specified CLSID to be automatically converted to another CLSID, and if so, retrieves the new OpenInputDesktop,USER32.DLL,NM,3, returns a handle to the desktop that receives user CLSID. input. OleGetClipboard,OLE32.DLL,NM,1,Retrieves a data object that you can use to access the OpenMutex,KERNEL32.DLL,AW,3 returns a handle of an existing named mutex object. contents of the clipboard. OleGetIconOfClass,OLE32.DLL,NM,3,Returns a handle to a metafile containing an icon and a OpenNtmsNotification,NTMSAPI.DLL,NM,2, opens a channel to receive RSM object change notifications for objects of the specified type. string label for the specified CLSID. 144 OpenNtmsSession,NTMSAPI.DLL,AW,3, sets up a session with a RSM server. OpenPrinter,WINMM.DLL,AW,3 retrieves a handle identifying the specified printer or print server. OpenProcess,KERNEL32.DLL,NM,3, returns a handle of an existing process object. OpenProcessToken,ADVAPI32.DLL,NM,3, opens the access token associated with a process. OpenSCManager,ADVAPI32.DLL,AW,3 establishes a connection to the service control manager on the specified computer and opens the specified service control manager database. OpenSemaphore,KERNEL32.DLL,AW,3, returns a handle of an existing named semaphore object. OpenService,ADVAPI32.DLL,AW,3, opens a handle to an existing service. OpenStreamOnFile,MAPI32.DLL,NM,6, allocates and initializes an OLE IStream object to access the contents of a file. OpenThreadToken,ADVAPI32.DLL,NM,4, opens the access token associated with a thread. OpenTnefStream,MAPI32.DLL,NM,7 is called by a transport provider toinitiate a MAPI Transport Neutral Encapsulation Format (TNEF)session. OpenTnefStreamEx,MAPI32.DLL,NM,8 creates a TNEF object that can beused to encode or decode a message object into a TNEF data streamfor use by transports or gateways and message stores. OpenWaitableTimer,KERNEL32.DLL,AW,3, returns a handle to an existing named ?waitable? timer object. OpenWindowStation,USER32.DLL,AW,3, returns a handle to an existing window station. OutputDebugString,KERNEL32.DLL,AW,1, sends a string to the debugger for the current application. PackDDElParam,USER32.DLL,NM,3 packs a DDE lParam value into an internal structure used for sharing DDE data between processes. PageSetupDlg,COMDLG32.DLL,AW,1, creates a Page Setup dialog box that enables the user to specify the attributes of a printed page. PaintDesktop,USER32.DLL,NM,1, fills the clipping region in the specified device context with the desktop pattern or wallpaper. PaintRgn,GDI32.DLL,NM,2, paints the specified region by using the brush currently selected into the device context. PatBlt,GDI32.DLL,NM,6, paints the given rectangle using the brush that is currently selected into the specified device context. PathToRegion,GDI32.DLL,NM,1, creates a region from the path that is selected into the specified device context. PdhAddCounter,PDH.DLL,AW,4, creates the specified counter and adds it to the specified query. PdhBrowseCounters,PDH.DLL,AW,1, displays the counter browsing dialog box so that the user can select the counters to be returned to the caller. PdhCalculateCounterFromRawValue,PDH.DLL,NM,5, computes the current value of a counter as referenced by the hCounter parameter, using the raw counter data passed in the parameter list. PdhCloseQuery,PDH.DLL,NM,1, closes all counters contained in the specified query, closes all handles related to the query, and frees all memory associated with the query. PdhCollectQueryData,PDH.DLL,NM,1, collects the current raw data value for all counters in the specified query and updates the status code of each counter. PdhComputeCounterStatistics,PDH.DLL,NM,6, computes statistics for a counter from an array of raw values. PdhConnectMachine,PDH.DLL,AW,1, connects to the specified computer, and creates and initializes a computer entry in the PDH DLL. PdhEnumMachines,PDH.DLL,AW,3, returns a list of the names of the computers that have been opened previously by the PDH DLL. PdhEnumObjectItems,PDH.DLL,AW,9, returns the available counters and instances provided by the specified object on the specified computer. PdhEnumObjects,PDH.DLL,AW,6, returns a list of objects available on the specified computer. PdhExpandCounterPath,PDH.DLL,AW,3, examines the specified computer (or local computer if none is specified) for counters and instances of counters that match the wildcard strings in the counter path. PdhGetCounterInfo,PDH.DLL,AW,4, retrieves information about a counter, such as data size, counter type, path, and user-supplied data values. PdhGetDefaultPerfCounter,PDH.DLL,AW,5, retrieves the name of the default counter for the specified object. This name can be used to set the initial selection of the counter browser list/combo box. PdhGetDefaultPerfObject,PDH.DLL,AW,4, retrieves the name of the default performance object. This name can be used to select the default entry in the object browser list box. PdhGetDllVersion,PDH.DLL,NM,1, returns the version of the currently installed Pdh.dll file. PdhGetFormattedCounterValue,PDH.DLL,NM,4, returns the current value of a specified counter in the format requested by the caller. PdhGetRawCounterValue,PDH.DLL,NM,3, returns the current raw value of the counter. PdhMakeCounterPath,PDH.DLL,AW,4, creates a full counter path using the members specified in the structure passed in the parameter list. PdhOpenQuery,PDH.DLL,NM,3, creates and initializes a unique query structure that is used to manage the collection of performance data. PdhParseCounterPath,PDH.DLL,AW,4, parses the elements of the counter path and stores the results in the structure passed by the caller. PdhParseInstanceName,PDH.DLL,AW,6, parses the elements of an instance string and returns them in the buffers supplied by the caller. PdhRemoveCounter,PDH.DLL,NM,1, removes a counter from a query. PdhSetCounterScaleFactor,PDH.DLL,NM,2, sets the scale factor that is applied to the calculated value of the specified counter when you request the formatted counter value. If the PDH_FMT_NOSCALE flag is set, then this scale factor is ignored. PdhValidatePath,PDH.DLL,AW,1, validates that the specified counter is present on the computer specified in the counter path. PdhVbAddCounter,PDH.DLL,NM,3, creates a counter entry in the specified query object, and returns a handle to that counter upon successful completion. PdhVbCreateCounterPathList,PDH.DLL,NM,2, displays the performance counter browsing dialog box, which lets the user select several performance counters. Each selected counter path must then be read using the PdhVbGetCounterPathFromList function. PdhVbGetCounterPathElements,PDH.DLL,NM,7, parses a fully qualified performance counter path string into its individual elements. PdhVbGetCounterPathFromList,PDH.DLL,NM,3, copies the counter path referenced by the Index parameter from a counter path list created by the user from the most recent call to the PdhVbCreateCounterPathList function. PdhVbGetDoubleCounterValue,PDH.DLL,NM,2, returns the current value of the specified counter as a double-precision floating point value. PdhVbGetOneCounterPath,PDH.DLL,NM,4, displays a dialog box that lets the user browse the available performance counters and select one counter. PdhVbIsGoodStatus,PDH.DLL,NM,1, tests a status value to determine if it is a success or failure code. If the status value is a successful one, then the return value will be nonzero. If it is a failure status code, the return value will be zero. PdhVbOpenQuery,PDH.DLL,NM,1, creates and initializes a unique query structure that is used to manage the collection of performance data. PeekConsoleInput,KERNEL32.DLL,AW,4, reads data from the specified console input buffer without removing it from the buffer. PeekMessage,USER32.DLL,AW,5, checks a thread message queue for a message and places the message (if any) in the specified structure. PeekNamedPipe,KERNEL32.DLL,NM,6, copies data from a named or anonymous pipe into a buffer without removing it from the pipe. phoneClose,TAPI32.DLL,NM,1, closes the specified open phone device. phoneConfigDialog,TAPI32.DLL,AW,3 causes the provider of the specified phone device to display a modal dialog box (attached to the application's hwndOwner parameter) that allows the user to configure parameters related to the phone device specified by dwDeviceID. phoneDevSpecific,TAPI32.DLL,NM,3 is used as a general extension mechanism to enable a Telephony API implementation to provide features not described in the other TAPI functions. phoneGetButtonInfo,TAPI32.DLL,AW,3, returns information about the specified button. phoneGetData,TAPI32.DLL,NM,4 uploads the information from the specified location in the open phone device to the specified buffer. phoneGetDevCaps,TAPI32.DLL,AW,5 queries a specified phone device to determine its telephony capabilities. phoneGetDisplay,TAPI32.DLL,NM,2 returns the current contents of thespecified phone display. phoneGetGain,TAPI32.DLL,NM,3, returns the gain setting of the microphone of the specified phone's hookswitch device. phoneGetHookSwitch,TAPI32.DLL,NM,2, returns the current hookswitch mode of the specified open phone device. phoneGetIcon,TAPI32.DLL,AW,3 allows an application to retrieve a service phone devicespecific (or provider-specific) icon that can be displayed to the user. phoneGetID,TAPI32.DLL,AW,3, can be used to retrieve a phone device identifier given a phone handle. phoneGetLamp,TAPI32.DLL,NM,3, returns the current lamp mode of the specified lamp. phoneGetMessage,TAPI32.DLL,NM,3 returns the next TAPI message that is queued for delivery to an application that is using the Event Handle notification mechanism phoneGetRing,TAPI32.DLL,NM,3, enables an application to query the specified open phone device as to its current ring mode. phoneGetStatus,TAPI32.DLL,AW,2, enables an application to query the specified open phone device for its overall status. phoneGetStatusMessages,TAPI32.DLL,NM,4 returns which phone-state changes on the specified phone device generate a callback to the application. phoneGetVolume,TAPI32.DLL,NM,3, returns the volume setting of the specified phone's hookswitch device. phoneInitialize,TAPI32.DLL,NM,5 is obsolete. phoneInitializeEx,TAPI32.DLL,AW,7, initializes the application's use of TAPI for subsequent use of the phone abstraction. phoneNegotiateAPIVersion,TAPI32.DLL,NM,6, is used to negotiate the API version number to use with the specified phone device. phoneNegotiateExtVersion,TAPI32.DLL,NM,6 allows an application to negotiate an extension version to use with the specified phone device. phoneOpen,TAPI32.DLL,NM,7, opens the specified phone device. phoneSetButtonInfo,TAPI32.DLL,AW,3, sets information about the specified button on the specified phone. phoneSetData,TAPI32.DLL,NM,4 downloads the information in thespecified buffer to the opened phone device at the selected dataidentifier. phoneSetDisplay,TAPI32.DLL,NM,5, causes the specified string to be displayed on the specified open phone device. phoneSetGain,TAPI32.DLL,NM,3, sets the gain of the microphone of the specified hookswitch device to the specified gain level. phoneSetHookSwitch,TAPI32.DLL,NM,3 sets the hook state of thes pecified open phone's hookswitch devices to the specified mode. phoneSetLamp,TAPI32.DLL,NM,3, causes the specified lamp to be lit on the specified open phone device in the specified lamp mode. phoneSetRing,TAPI32.DLL,NM,3, rings the specified open phone device using the specified ring mode and volume. phoneSetStatusMessages,TAPI32.DLL,NM,4 enables an application to monitor the specified phone device for selected status events. phoneSetVolume,TAPI32.DLL,NM,3 sets the volume of the speakercomponent of the specified hookswitch device to the specifiedlevel. phoneShutdown,TAPI32.DLL,NM,1, shuts down the application's usage of TAPI's phone abstraction. Pie,GDI32.DLL,NM,9, draws a pie-shaped wedge bounded by the intersection of an ellipse and two radials. PlayEnhMetaFile,GDI32.DLL,NM,3, displays the picture stored in the specified enhancedformat metafile. PlayEnhMetaFileRecord,GDI32.DLL,NM,4 plays an enhanced-metafile record by executing the graphics device interface (GDI) functions identified by the record. PlayMetaFile,GDI32.DLL,NM,2, displays the picture stored in the given Windows-format metafile on the specified device. PlayMetaFileRecord,GDI32.DLL,NM,4 plays a Windows-format metafilerecord by executing the graphics device interface (GDI) functioncontained within that record. PlaySound,WINMM.DLL,AW,3, plays a sound specified by the given filename, resource, or system event. PlgBlt,GDI32.DLL,NM,10 performs a bit-block transfer of the bits of color data from the specified rectangle in the source device context to the specified parallelogram in the destination device context. PolyBezier,GDI32.DLL,NM,3, draws one or more B? er curves. PolyBezierTo,GDI32.DLL,NM,3, draws one or more B? er curves. PolyDraw,GDI32.DLL,NM,4 draws a set of line segments and Bezier curves. Polygon,GDI32.DLL,NM,3, draws a polygon consisting of two or more vertices connected by straight lines. Polyline,GDI32.DLL,NM,3, draws a series of line segments by connecting the points in the specified array. PolylineTo,GDI32.DLL,NM,3 draws one or more straight lines. PolyPolygon,GDI32.DLL,NM,4, draws a series of closed polygons. PolyPolyline,GDI32.DLL,NM,4, draws multiple series of connected line segments. PolyTextOut,GDI32.DLL,AW,3, draws several strings using the font and text colors currently selected in the specified device context. PostMessage,USER32.DLL,AW,4 places (posts) a message in the message queue associated with the thread that created the specified window and then returns without waiting for the thread to process the message. PostQueuedCompletionStatus,KERNEL32.DLL,NM,4, lets you post an I/O completion packet to an I/O completion port. PostQuitMessage,USER32.DLL,NM,1, indicates to Windows that a thread has made a request to terminate (quit). PostThreadMessage,USER32.DLL,AW,4 places (posts) a message in the message queue of the specified thread and then returns without waiting for the thread to process the message. PpropFindProp,MAPI32.DLL,NM,3, searches for a specified property in a property set. PrepareTape,KERNEL32.DLL,NM,3 prepares the tape to be accessed or removed. PrintDlg,COMDLG32.DLL,AW,1,PDERR_CREATEICFAILURE failed when it attempted to create an information context. PrinterMessageBox,WINMM.DLL,AW,6 displays a message box that lets an application that is printing notify the user of a printing job error. PrinterProperties,WINMM.DLL,NM,2, displays a printer-properties dialog box for the specified printer. PrivilegeCheck,ADVAPI32.DLL,NM,3, determines whether a specified set of privileges are enabled in an access token. PrivilegedServiceAuditAlarm,ADVAPI32.DLL,AW,5 generates audit messages when an attempt is made to perform privileged system service operations. Process32First,TOOLHELP.DLL,NM,2,Retrieves information about the first process encountered in a system snapshot. 145 Process32Next,TOOLHELP.DLL,NM,2,Retrieves information about the next process recorded RasGetErrorString,RASAPI32.DLL,AW,3, obtains an error message string for a specified RAS error value. in a system snapshot. RasGetProjectionInfo,RASAPI32.DLL,AW,4 obtains information about aremote access ProcessGroupPolicyCompleted,USERENV.DLL,NM,3, notifies the system that the specified projection operation for a specified remote accesscomponent protocol. extension has finished applying policy. RasGetSubEntryHandle,RASAPI32.DLL,AW,3 retrieves a connection handle for a specified ProgIDFromCLSID,OLE32.DLL,NM,2,This function retrieves the ProgID for a given CLSID. subentry of a multilink connection. PropCopyMore,MAPI32.DLL,NM,4 copies a single property value from a source location to a RasGetSubEntryProperties,RASAPI32.DLL,AW,7, retrieves information about a subentry for a destination location. PropertySheet,COMCTL32.DLL,AW,1, creates a property sheet and adds the pages defined in specified phone-book entry. RasHangUp,RASAPI32.DLL,AW,1, terminates a remote access connection. the specified property sheet header structure. PropStgNameToFmtId,IPROP.DLL,NM,2,Converts a property set storage or stream name to its RasMonitorDlg,RASDLG.DLL,AW,2, displays the Dial-Up Networking Monitor property sheet that describes the status of RAS connections. format identifier. RasRenameEntry,RASAPI32.DLL,AW,3, changes the name of an entry in a phone book. PropVariantClear,IPROP.DLL,NM,1,Frees all elements that can be freed in a given RasSetAutodialAddress,RASAPI32.DLL,AW,5, can add an address to the AutoDial mapping PROPVARIANT structure. database. PropVariantClear,OLE32.DLL,NM,1,Frees all elements that can be freed in a given RasSetAutodialEnable,RASAPI32.DLL,AW,2, enables or disables the AutoDial feature for a PROPVARIANT structure. specified TAPI dialing location. PropVariantCopy,IPROP.DLL,NM,2, copies the contents of one PROPVARIANT structure to RasSetAutodialParam,RASAPI32.DLL,AW,3, sets the value of an AutoDial parameter. another. RasSetCredentials,RASAPI32.DLL,AW,4, sets the user credentials associated with a specified PropVariantCopy,OLE32.DLL,NM,2, copies the contents of one PROPVARIANT structure to RAS phone-book entry. another. RasSetEntryDialParams,RASAPI32.DLL,AW,3 deletes an entry from a phone book. PtInRect,USER32.DLL,NM,3, determines whether the specified point lies within the specified RasSetEntryProperties,RASAPI32.DLL,AW,6 changes the connectioninformation for an entry in rectangle. the phone book or creates a new phone-book entry. PtInRegion,GDI32.DLL,NM,3, determines whether the specified point is inside the specified RasSetSubEntryProperties,RASAPI32.DLL,AW,7, creates a new subentry or modifies an region. PtVisible,GDI32.DLL,NM,3, indicates whether the specified point is within the clipping region of existing subentry of a specified phone-book entry. RasValidateEntryName,RASAPI32.DLL,AW,2, validates the format of a connection entry name. a device context. PulseEvent,KERNEL32.DLL,NM,1 provides a single operation that sets (to signaled) the state ReadClassStg,OLE32.DLL,NM,2, reads the CLSID previously written to a storage object with of the specified event object and then resets it (to nonsignaled) after releasing the appropriate the WriteClassStg function. ReadClassStm,OLE32.DLL,NM,2,Reads the CLSID previously written to a stream object with number of waiting threads. PurgeComm,KERNEL32.DLL,NM,2, can discard all characters from the output or input buffer of the WriteClassStm function. ReadConsole,KERNEL32.DLL,AW,5, reads character input from the console input buffer and a specified communications resource. removes it from the buffer. QueryContextAttributes,SECUR32.DLL,AW,3,Enables a transport application to query a ReadConsoleInput,KERNEL32.DLL,AW,4, reads data from a console input file buffer and security package for certain attributes of a security context. QueryCredentialsAttributes,SECUR32.DLL,AW,3, retrieves the attributes of a credential, such removes it from the buffer. ReadConsoleOutput,KERNEL32.DLL,AW,5 reads character and color attribute data from a as the name associated with the credential. The information is valid for any security context rectangular block of character cells in a console screen buffer, and the function writes the data created with the specified credential. QueryDosDevice,KERNEL32.DLL,AW,3, lets an application obtain information about MS-DOS to a rectangular block at a specified location in the destination buffer. ReadConsoleOutputAttribute,KERNEL32.DLL,NM,5 copies a specified number of foreground device names. QueryPathOfRegTypeLib,OLEAUT32.DLL,NM,5,Retrieves the path of a registered type library. and background color attributes from consecutive cells of a console screen buffer, beginning at a specified location. QueryPerformanceCounter,KERNEL32.DLL,NM,1, retrieves the current value of the highReadConsoleOutputCharacter,KERNEL32.DLL,AW,5 copies a number ofcharacters from resolution performance counter, if one exists. consecutive cells of a console screen buffer,beginning at a specified location. QueryPerformanceFrequency,KERNEL32.DLL,NM,1, retrieves the frequency of the highReadEventLog,ADVAPI32.DLL,AW,7, reads a whole number of entries from the specified event resolution performance counter, if one exists. QuerySecurityContextToken,SECUR32.DLL,NM,2,Obtains the access token for a client security log. ReadFile,KERNEL32.DLL,NM,5, reads data from a file, starting at the position indicated by the context and uses it directly. file pointer. QuerySecurityPackageInfo,SECUR32.DLL,AW,2, retrieves information about a specified security package. This information includes the bounds on sizes of authentication information, ReadFileEx,KERNEL32.DLL,NM,5,ERROR_HANDLE_EOF tried to read past the end of the file. credentials, and contexts. ReadFmtUserTypeStg,OLE32.DLL,NM,3, returns the clipboard format and user type previously QueryServiceConfig,ADVAPI32.DLL,AW,4, retrieves the configuration parameters of the saved with the WriteFmtUserTypeStg function. specified service. QueryServiceLockStatus,ADVAPI32.DLL,AW,4 retrieves the lock status of the specified service ReadPrinter,WINMM.DLL,NM,4, retrieves data from the specified printer. ReadProcessMemory,KERNEL32.DLL,NM,5, reads memory in a specified process. control manager database. QueryServiceObjectSecurity,ADVAPI32.DLL,NM,5, retrieves a copy of the security descriptor ReadUrlCacheEntryStream,WININET.DLL,NM,5,Reads the cached data from a stream that has been opened using the RetrieveUrlCacheEntryStream function. associated with a service object. QueryServiceStatus,ADVAPI32.DLL,NM,2, retrieves the current status of the specified service. RealizePalette,GDI32.DLL,NM,1, maps palette entries from the current logical palette to the QueryWorkingSet,PSAPI.DLL,NM,3, retrieves information about the pages currently added to system palette. ReBaseImage,IMAGEHLP.DLL,NM,11, is used to change the load address for the specified the working set of the specified process. QueueUserAPC,KERNEL32.DLL,NM,3, adds a user-mode asynchronous procedure call (APC) image, which reduces the required load time for a DLL. Rectangle,GDI32.DLL,NM,5 draws a rectangle. object to the APC queue of the specified thread. RectInRegion,GDI32.DLL,NM,2, determines whether any part of the specified rectangle is RaiseException,KERNEL32.DLL,NM,4, raises an exception in the calling thread. RasAdminFreeBuffer,RASSAPI.DLL,NM,1, frees memory that was allocated by frees memory within the boundaries of a region. RectVisible,GDI32.DLL,NM,2 determines whether any part of thespecified rectangle lies within that was allocated by RAS on behalf of the caller. the clipping region of a devicecontext. RasAdminGetErrorString,RASSAPI.DLL,NM,3 corresponds to a RAS error code returned by recv,WS2_32.DLL,NM,4,Receives data from a connected or bound socket. one of the RAS serveradministration (RasAdmin) functions. recv,WSOCK32.DLL,NM,4,Receives data from a connected or bound socket. RasAdminGetUserAccountServer,RASSAPI.DLL,NM,3, retrieves the name of the server that recvfrom,WS2_32.DLL,NM,6 receives a datagram and stores the source address. has the user account database. RasAdminPortClearStatistics,RASSAPI.DLL,NM,2 resets the countersrepresenting the various recvfrom,WSOCK32.DLL,NM,6 receives a datagram andstores the source address. RedrawWindow,USER32.DLL,NM,4, updates the specified rectangle or region in a window?s statistics reported by theRasAdminPortGetInfo function in the RAS_PORT_STATISTICS client area. structure. RefreshPolicy,USERENV.DLL,NM,1, causes policy to be applied immediately on the client RasAdminPortDisconnect,RASSAPI.DLL,NM,2, disconnects a port that is currently in use. computer. RasAdminPortEnum,RASSAPI.DLL,NM,3 enumerates all ports on the specifiedRAS server. RegCloseKey,ADVAPI32.DLL,NM,1 releases the handle of the specified key. RasAdminPortGetInfo,RASSAPI.DLL,NM,5, retrieves information about a specified port on a RegConnectRegistry,ADVAPI32.DLL,AW,3, establishes a connection to a predefined registry specified server. handle on another computer. RasAdminServerGetInfo,RASSAPI.DLL,NM,2, gets the server configuration of a RAS server. RegCreateKey,ADVAPI32.DLL,AW,3, creates the specified key. RasAdminUserGetInfo,RASSAPI.DLL,NM,3, gets the RAS permissions and callback phone RegCreateKeyEx,ADVAPI32.DLL,AW,9, creates the specified key. number information for a specified user. RegDeleteKey,ADVAPI32.DLL,AW,2,Windows 95: deletes a subkey and all its descendants. RasAdminUserSetInfo,RASSAPI.DLL,NM,3 sets the RAS permissions and call-back phone RegDeleteValue,ADVAPI32.DLL,AW,2 removes a named value from the specified registry key. number for a specified user. RasConnectionNotification,RASAPI32.DLL,AW,3 specifies an event objectthat the system sets RegEnumKey,ADVAPI32.DLL,AW,4, enumerates subkeys of the specified open registry key. RegEnumKeyEx,ADVAPI32.DLL,AW,8, enumerates subkeys of the specified open registry key. to the signaled state when a RAS connection iscreated or terminated. RegEnumValue,ADVAPI32.DLL,AW,8, enumerates the values for the specified data block for RasCreatePhonebookEntry,RASAPI32.DLL,AW,2, creates a new phone-book entry. the key each time it is called. RasDeleteEntry,RASAPI32.DLL,AW,2, deletes an entry from a phone book. RasDial,RASAPI32.DLL,AW,6, establishes a RAS connection between a RAS client and a RAS RegFlushKey,ADVAPI32.DLL,NM,1, writes all the attributes of the specified open key into the registry. server. RasDialDlg,RASDLG.DLL,AW,4 tries to establish a RAS connection using a specified phone- RegGetKeySecurity,ADVAPI32.DLL,NM,4, retrieves a copy of the security descriptor protecting the specified open registry key. book entry and the credentials of the logged-on user. RegisterActiveObject,OLEAUT32.DLL,NM,4,Registers an object as the active object for its RasEditPhonebookEntry,RASAPI32.DLL,AW,3, edits an existing phone-book entry. class. RasEntryDlg,RASDLG.DLL,AW,3, displays modal property sheets that allow a user to RegisterBindStatusCallback,URLMON.DLL,NM,4, Registers a callback interface with an manipulate phone-book entries. existing bind context. RasEnumAutodialAddresses,RASAPI32.DLL,AW,3 returns a list of all addresses in the RegisterClass,USER32.DLL,AW,1, registers a window class for subsequent use in calls to the AutoDial mapping database. CreateWindow or CreateWindowEx function. RasEnumConnections,RASAPI32.DLL,AW,3, lists all active RAS connections. RegisterClassEx,USER32.DLL,AW,1 registers a window class for subsequent use in calls to RasEnumDevices,RASAPI32.DLL,AW,3, returns the name and type of all available RASthe CreateWindow or CreateWindowEx function. capable devices. RasEnumEntries,RASAPI32.DLL,AW,5, lists all entry names in a remote access phone book. RegisterClipboardFormat,USER32.DLL,AW,1, registers a new clipboard format. RegisterCMM,MSCMS.DLL,AW,3,RegisterCMM associates a specified identification value with RasGetAutodialAddress,RASAPI32.DLL,AW,5 retrieves information about allthe AutoDial the specified color management module dynamic link library (CMM DLL). When this ID appears entries associated with a network address in theAutoDial mapping database. RasGetAutodialEnable,RASAPI32.DLL,AW,2, indicates whether the AutoDial feature is enabled in a color profile, Windows can then locate the corresponding CMM so as to create a transform. RegisterDragDrop,OLE32.DLL,NM,2,Registers the specified window as one that can be the for a specified TAPI dialing location. target of an OLE drag-and-drop operation and specifies the IDropTarget instance to use for RasGetAutodialParam,RASAPI32.DLL,AW,3, retrieves the value of an AutoDial parameter. RasGetConnectStatus,RASAPI32.DLL,AW,2, retrieves information on the current status of the drop operations. RegisterEventSource,ADVAPI32.DLL,AW,2, returns a registered handle to an event log. specified remote access connection. RegisterFormatEnumerator,URLMON.DLL,NM,3, Registers a FORMATETC enumerator object RasGetCountryInfo,RASAPI32.DLL,AW,2, retrieves country-specific dialing information from onto the given bind context. the Windows Telephony list of countries. RegisterGPNotification,USERENV.DLL,NM,2, enables an application to receive notification RasGetCredentials,RASAPI32.DLL,AW,3, retrieves the user credentials associated with a when there is a change in policy. When a policy change occurs, the specified event object is set specified RAS phone-book entry. RasGetEntryDialParams,RASAPI32.DLL,AW,3, retrieves the connection information saved by to the signaled state. the last successful call to the RasDial or RasGetEntryDialParams function for a specified phone RegisterHotKey,USER32.DLL,NM,4, defines a system-wide hot key. RegisterMediaTypeClass,URLMON.DLL,NM,5, Registers a mapping of media types to CLSIDs book entry. to override the default mapping specified in the registry. RasGetEntryProperties,RASAPI32.DLL,AW,6 retrieves the properties of aphone-book entry. 146 RegisterMediaTypes,URLMON.DLL,NM,3, Registers media type strings. RegisterServiceCtrlHandler,ADVAPI32.DLL,AW,2 A Win32-based service calls the RegisterServiceCtrlHandler functionto register a function to handle its service control requests. RegisterWindowMessage,USER32.DLL,AW,1 defines a new window messagethat is guaranteed to be unique throughout the system. RegLoadKey,ADVAPI32.DLL,AW,3 creates a subkey under HKEY_USER orHKEY_LOCAL_MACHINE and stores registration information from aspecified file into that subkey. RegNotifyChangeKeyValue,ADVAPI32.DLL,NM,5, notifies the caller about changes to the attributes or contents of a specified registry key. RegOpenKey,ADVAPI32.DLL,AW,3, opens the specified key. RegOpenKeyEx,ADVAPI32.DLL,AW,5 opens the specified key. RegQueryInfoKey,ADVAPI32.DLL,AW,12, retrieves information about a specified registry key. RegQueryMultipleValues,ADVAPI32.DLL,AW,5, retrieves the type and data for a list of value names associated with an open registry key. RegQueryValue,ADVAPI32.DLL,AW,4, retrieves the value associated with the unnamed value for a specified key in the registry. RegQueryValueEx,ADVAPI32.DLL,AW,6, retrieves the type and data for a specified value name associated with an open registry key. RegReplaceKey,ADVAPI32.DLL,AW,4 replaces the file backing a key and all its subkeys with another file, so that when the system is next started, the key and subkeys will have the values stored in the new file. RegRestoreKey,ADVAPI32.DLL,AW,3 reads the registry information in a specified file and copies it over the specified key. RegSaveKey,ADVAPI32.DLL,AW,3, saves the specified key and all of its subkeys and values to a new file. RegSetKeySecurity,ADVAPI32.DLL,NM,3 sets the security of an open registry key. RegSetValue,ADVAPI32.DLL,AW,5, associates a value with a specified key. RegSetValueEx,ADVAPI32.DLL,AW,6, stores data in the value field of an open registry key. RegUnLoadKey,ADVAPI32.DLL,AW,2, unloads the specified key and subkeys from the registry. ReleaseCapture,USER32.DLL,NM,0 releases the mouse capture from awindow in the current thread and restores normal mouse inputprocessing. ReleaseDC,USER32.DLL,NM,2, releases a device context (DC), freeing it for use by other applications. ReleaseMutex,KERNEL32.DLL,NM,1, fails if the calling thread does not own the mutex object. ReleaseNtmsCleanerSlot,NTMSAPI.DLL,NM,2, removes an existing slot reservation for a cleaning cartridge. The slot can then be used for data cartridges. ReleaseSemaphore,KERNEL32.DLL,NM,3, increases the count of the specified semaphore object by a specified amount. ReleaseStgMedium,OLE32.DLL,NM,1,Frees the specified storage medium. RemoveDirectory,KERNEL32.DLL,AW,1, deletes an existing empty directory. RemoveFontResource,GDI32.DLL,AW,1, removes the fonts in the specified file from the Windows font table. RemoveMenu,USER32.DLL,NM,3, deletes a menu item from the specified menu. RemoveProp,USER32.DLL,AW,2, removes an entry from the property list of the specified window. ReplaceText,COMDLG32.DLL,AW,1 creates a system-defined modeless dialog box that lets the user specify a string to search for and a replacement string, as well as options to control the find and replace operations. ReplyMessage,USER32.DLL,NM,1 is used to reply to a message sentthrough the SendMessage function without returning control to thefunction that called SendMessage. ReportEvent,ADVAPI32.DLL,AW,9, writes an entry at the end of the specified event log. ReserveNtmsCleanerSlot,NTMSAPI.DLL,NM,3, reserves a single slot in a library unit for a drive cleaner cartridge. ResetDC,GDI32.DLL,AW,2, cannot be used to change the driver name, device name, or the output port. ResetEvent,KERNEL32.DLL,NM,1, sets the state of the specified event object to nonsignaled. ResetPrinter,WINMM.DLL,AW,2 lets an application specify the data typeand device mode values that are used for printing documentssubmitted by the StartDocPrinter function. ResizePalette,GDI32.DLL,NM,2, increases or decreases the size of a logical palette based on the specified value. RestoreDC,GDI32.DLL,NM,2, restores a device context (DC) to the specified state. ResumeSuspendedDownload,WININET.DLL,NM,2, resumes a request that is suspended by a user interface dialog box. ResumeThread,KERNEL32.DLL,NM,1, decrements a thread?s suspend count. ResUtilAddUnknownProperties,RESUTILS.DLL,NM,6,The ResUtilAddUnknownProperties utility function retrieves a set of unknown properties from the cluster database and appends them to the end of a property list. ResUtilCreateDirectoryTree,RESUTILS.DLL,NM,1, creates every directory specified in a path, skipping directories that already exist. ResUtilDupParameterBlock,RESUTILS.DLL,NM,3,The ResUtilDupParameterBlock utility function performs a member-wise copy of the data from one parameter block to another. ResUtilDupString,RESUTILS.DLL,NM,1,The ResUtilDupString utility function duplicates a nullterminated Unicode string. ResUtilEnumPrivateProperties,RESUTILS.DLL,NM,5,The ResUtilEnumPrivateProperties utility function retrieves the names of a cluster object's private properties. ResUtilEnumProperties,RESUTILS.DLL,NM,5,The ResUtilEnumProperties utility function enumerates the property names of a cluster object. ResUtilEnumResources,RESUTILS.DLL,NM,4,The ResUtilEnumResources utility function enumerates all of the resources in the local cluster and initiates a user-defined operation for each resource. ResUtilExpandEnvironmentStrings,RESUTILS.DLL,NM,1, expands strings containing unexpanded references to environment variables. ResUtilFindBinaryProperty,RESUTILS.DLL,NM,5,The ResUtilFindBinaryProperty utility function locates a specified binary property in a property list and can also return the value of the property. ResUtilFindDependentDiskResourceDriveLetter,RESUTILS.DLL,NM,4,The ResUtilFindDependentDiskResourceDriveLetter utility function retrieves the drive letter associated with a Physical Disk dependency of a resource. ResUtilFindDwordProperty,RESUTILS.DLL,NM,4,The ResUtilFindDwordProperty utility function locates an unsigned long property value in a property list. ResUtilFindExpandedSzProperty,RESUTILS.DLL,NM,4,The ResUtilFindExpandedSzProperty utility function locates an expanded string property value in a property list. ResUtilFindExpandSzProperty,RESUTILS.DLL,NM,4,The ResUtilFindExpandSzProperty utility function locates an expandable string property in a property list. ResUtilFindLongProperty,RESUTILS.DLL,NM,4,The ResUtilFindLongProperty utility function locates a signed long property value in a property list. ResUtilFindMultiSzProperty,RESUTILS.DLL,NM,5,The ResUtilFindMultiSzProperty utility function locates a multiple string property in a property list. ResUtilFindSzProperty,RESUTILS.DLL,NM,4,The ResUtilFindSzProperty utility function locates a string property in a property list. ResUtilFreeEnvironment,RESUTILS.DLL,NM,1, destroys the environment variable block created with ResUtilGetEnvironmentWithNetName. ResUtilFreeParameterBlock,RESUTILS.DLL,NM,3,The ResUtilFreeParameterBlock utility function deallocates memory that has been allocated for a parameter block by ResUtilDupParameterBlock. ResUtilGetAllProperties,RESUTILS.DLL,NM,6,The ResUtilGetAllProperties utility function returns a property list that includes all of the default and unknown properties for a cluster object. ResUtilGetBinaryProperty,RESUTILS.DLL,NM,7,The ResUtilGetBinaryProperty utility function retrieves a binary property from a property list and advances a pointer to the next property in the list. ResUtilGetBinaryValue,RESUTILS.DLL,NM,4,The ResUtilGetBinaryValue utility function returns a binary value from the cluster database. ResUtilGetDwordProperty,RESUTILS.DLL,NM,7,The ResUtilGetDwordProperty utility function retrieves a DWORD property from a property list and advances a pointer to the next property in the list. ResUtilGetDwordValue,RESUTILS.DLL,NM,4,The ResUtilGetDwordValue utility function returns a numeric value from the cluster database. ResUtilGetEnvironmentWithNetName,RESUTILS.DLL,NM,1, adjusts environment data for a resource so that the resource uses a cluster network name to identify its location. The resource must be dependent on a Network Name resource. ResUtilGetMultiSzProperty,RESUTILS.DLL,NM,7,The ResUtilGetMultiSzProperty utility function retrieves a multiple string property from a property list and advances a pointer to the next property in the list. ResUtilGetPrivateProperties,RESUTILS.DLL,NM,5,The ResUtilGetPrivateProperties utility function returns private properties for a cluster object. ResUtilGetProperties,RESUTILS.DLL,NM,6,The ResUtilGetProperties utility function retrieves properties specified by a property table from the cluster database and returns them in a property list. ResUtilGetPropertiesToParameterBlock,RESUTILS.DLL,NM,5,The ResUtilGetPropertiesToParameterBlock utility function retrieves properties specified by a property table from the cluster database and returns them in a parameter block. ResUtilGetProperty,RESUTILS.DLL,NM,4,The ResUtilGetPropertySize utility function returns the total number of bytes required for a specified property. ResUtilGetPropertySize,RESUTILS.DLL,NM,4,The ResUtilGetPropertySize utility function returns the total number of bytes required for a specified property. ResUtilGetResourceDependency,RESUTILS.DLL,NM,2, enumerates the dependencies of a specified resource and returns a handle to a dependency of a specified type. ResUtilGetResourceDependencyByClass,RESUTILS.DLL,NM,4, enumerates the dependencies of a specified resource in a specified cluster and returns a handle to a dependency that matches a specified resource class. ResUtilGetResourceDependencyByName,RESUTILS.DLL,NM,4, enumerates the dependencies of a specified resource in a specified cluster and returns a handle to a dependency of a specified type. ResUtilGetResourceDependentIPAddressProps,RESUTILS.DLL,NM,7,The ResUtilGetResourceDependentIPAddressProps utility function retrieves the private properties of the first IP Address dependency found for a specified resource. ResUtilGetResourceNameDependency,RESUTILS.DLL,NM,2, enumerates the dependencies of a specified resource in the local cluster and returns a handle to a dependency of a specified resource type. ResUtilGetSzProperty,RESUTILS.DLL,NM,5,The ResUtilGetSzProperty utility function retrieves a string property from a property list and advances a pointer to the next property in the list. ResUtilGetSzValue,RESUTILS.DLL,NM,2,The ResUtilGetSzValue utility function returns a string value from the cluster database. ResUtilIsPathValid,RESUTILS.DLL,NM,1,The ResUtilIsPathValid utility function is used to check whether a path is syntactically valid. ResUtilIsResourceClassEqual,RESUTILS.DLL,NM,2, tests whether the resource class of a specified resource is equal to a specified resource class. ResUtilPropertyListFromParameterBlock,RESUTILS.DLL,NM,6,The ResUtilPropertyListFromParameterBlock utility function constructs a property list from a property table and a parameter block. ResUtilResourcesEqual,RESUTILS.DLL,NM,2,The ResUtilResourcesEqual utility function tests whether two resource handles represent the same resource. ResUtilResourceTypesEqual,RESUTILS.DLL,NM,2,The ResUtilResourceTypesEqual utility function tests whether a resource type matches the resource type name of a specified resource. ResUtilSetBinaryValue,RESUTILS.DLL,NM,6,The ResUtilSetBinaryValue utility function sets a binary value in the cluster database. ResUtilSetDwordValue,RESUTILS.DLL,NM,4,The ResUtilSetDwordValue utility function sets a numeric value in the cluster database. ResUtilSetExpandSzValue,RESUTILS.DLL,NM,4,The ResUtilSetExpandSzValue utility function sets an expandable string value in the cluster database. ResUtilSetMultiSzValue,RESUTILS.DLL,NM,6,The ResUtilSetMultiSzValue utility function sets a multiple string value in the cluster database. ResUtilSetPrivatePropertyList,RESUTILS.DLL,NM,3,The ResUtilSetPrivatePropertyList utility function sets the private properties of a cluster object. ResUtilSetPropertyParameterBlock,RESUTILS.DLL,NM,7,The ResUtilSetPropertyParameterBlock utility function is used to set properties in the cluster database from a parameter block. ResUtilSetPropertyParameterBlockEx,RESUTILS.DLL,NM,8,The ResUtilSetPropertyParameterBlockEx utility function is used to set properties in the cluster database from a parameter block. ResUtilSetPropertyTable,RESUTILS.DLL,NM,7,The ResUtilSetPropertyTable utility function is used to set properties in the cluster database based on a property list from a property table.. ResUtilSetPropertyTableEx,RESUTILS.DLL,NM,8,The ResUtilSetPropertyTableEx utility function is used to set properties in the cluster database based on a property list from a property table. ResUtilSetResourceServiceEnvironment,RESUTILS.DLL,NM,4, adjusts the environment data for a service so that the service uses a cluster network name to identify its location. This function must be called from a resource DLL. ResUtilSetResourceServiceStartParameters,RESUTILS.DLL,NM,5, adjusts the start parameters of a specified service so that it will operate correctly as a cluster resource. It must be called from a resource DLL. ResUtilSetSzValue,RESUTILS.DLL,NM,4,The ResUtilSetSzValue utility function sets a string value in the cluster database. ResUtilSetUnknownProperties,RESUTILS.DLL,NM,4,The ResUtilSetUnknownProperties utility function stores a cluster object's unknown properties in the cluster database. ResUtilStartResourceService,RESUTILS.DLL,NM,2,The ResUtilStartResourceService utility function starts a service. ResUtilStopResourceService,RESUTILS.DLL,NM,1,The ResUtilStopResourceService utility function stops a named service. ResUtilStopService,RESUTILS.DLL,NM,1,The ResUtilStopService utility function stops a service identified by a handle. ResUtilVerifyPrivatePropertyList,RESUTILS.DLL,NM,2,The ResUtilVerifyPrivatePropertyList utility function verifies that a property list is correctly formatted. ResUtilVerifyPropertyTable,RESUTILS.DLL,NM,6,The ResUtilVerifyPropertyTable utility function uses a property table to verify that a property list is correctly formatted. ResUtilVerifyResourceService,RESUTILS.DLL,NM,1,The ResUtilVerifyResourceService utility function verifies that a named service is starting or currently running. ResUtilVerifyService,RESUTILS.DLL,NM,1,The ResUtilVerifyService utility function checks if a service identified by a handle is starting or currently running. RetrieveUrlCacheEntryFile,WININET.DLL,AW,4 Retrieves a cache entry from the cache in the form of a file. RetrieveUrlCacheEntryStream,WININET.DLL,AW,5 Provides the most efficient and implementation-independent way of accessing the cache data. ReuseDDElParam,USER32.DLL,NM,5 allows an application to reuse a packed DDE lParam parameter, rather than allocating a new packed lParam. 147 RpcNsBindingSelect,RPCNS4.DLL,NM,2, returns a binding handle from a list of compatible RevertSecurityContext,SECUR32.DLL,NM,1, allows a security package to discontinue the binding handles. impersonation of the caller and restore its own security context. RpcNsBindingUnexport,RPCNS4.DLL,AW,4 removes the binding handles foran interface and RevertToSelf,ADVAPI32.DLL,NM,0, terminates the impersonation of a client application. objects from an entry in the name-servicedatabase. RevokeActiveObject,OLEAUT32.DLL,NM,2,Ends an object's status as active. RpcNsEntryExpandName,RPCNS4.DLL,AW,3, expands a name-service entry name. RevokeBindStatusCallback,URLMON.DLL,NM,2, Revokes a bind status callback interface RpcNsEntryObjectInqBegin,RPCNS4.DLL,AW,3, creates an inquiry context for a name-service previously registered on a bind context. database entry?s objects. RevokeDragDrop,OLE32.DLL,NM,1,Revokes the registration of the specified application RpcNsEntryObjectInqDone,RPCNS4.DLL,NM,1, deletes the inquiry context for a name-service window as a potential target for OLE drag-and-drop operations. RevokeFormatEnumerator,URLMON.DLL,NM,2, Removes a format enumerator from the given database entry?s objects. RpcNsEntryObjectInqNext,RPCNS4.DLL,NM,2, returns one object at a time from a namebind context. service database entry. RoundRect,GDI32.DLL,NM,7, draws a rectangle with rounded corners. RpcNsGroupDelete,RPCNS4.DLL,AW,2 deletes a group attribute. RpcBindingCopy,RPCRT4.DLL,NM,2, copies binding information and creates a new binding RpcNsGroupMbrAdd,RPCNS4.DLL,AW,4, adds an entry name to a group. handle. RpcNsGroupMbrInqBegin,RPCNS4.DLL,AW,4, creates an inquiry context for viewing group RpcBindingFree,RPCRT4.DLL,NM,1, releases binding-handle resources. members. RpcBindingFromStringBinding,RPCRT4.DLL,AW,2, returns a binding handle from a string RpcNsGroupMbrInqDone,RPCNS4.DLL,NM,1, deletes the inquiry context for a group. representation of a binding handle. RpcNsGroupMbrInqNext,RPCNS4.DLL,AW,2, returns one entry name from a group at a time. RpcBindingInqAuthClient,RPCRT4.DLL,AW,6 A server application calls the RpcNsGroupMbrRemove,RPCNS4.DLL,AW,4, removes an entry name from a group. RpcBindingInqAuthClient routine to obtain the principal name or privilege attributes of the RpcNsMgmtBindingUnexport,RPCNS4.DLL,AW,5, removes multiple binding handles and authenticated client that made the remote procedure call objects from an entry in the name-service database. RpcBindingInqAuthInfo,RPCRT4.DLL,AW,6, returns authentication and authorization RpcNsMgmtEntryCreate,RPCNS4.DLL,AW,2, creates a name-service database entry. information from a binding handle. RpcBindingInqAuthInfoEx,RPCRT4.DLL,AW,8 returns authentication,authorization, and security RpcNsMgmtEntryDelete,RPCNS4.DLL,AW,2, deletes a name-service database entry. RpcNsMgmtEntryInqIfIds,RPCNS4.DLL,AW,3 returns the list of interfaces exported to a namequality-of-service information from abinding handle. service database entry. RpcBindingInqObject,RPCRT4.DLL,NM,2, returns the object UUID from a binding handle. RpcNsMgmtHandleSetExpAge,RPCNS4.DLL,NM,2, sets the expiration age of a name-service RpcBindingInqOption,RPCRT4.DLL,NM,3 RPC client processes use RpcBindingInqOption to handle for local copies of name-service data. determine currentvalues of the binding options that are specific to the ncadg_mqmessageRpcNsMgmtInqExpAge,RPCNS4.DLL,NM,1 returns the global expiration age for local copies of queuing transport. RpcBindingReset,RPCRT4.DLL,NM,1, resets a binding handle so that the host is specified but name-service data. RpcNsMgmtSetExpAge,RPCNS4.DLL,NM,1, modifies the application?s global expiration age the server on that host is unspecified. RpcBindingServerFromClient,RPCRT4.DLL,NM,2, converts a client binding handle to a server for local copies of name-service data. RpcNsProfileDelete,RPCNS4.DLL,AW,2, deletes a profile attribute. binding handle. RpcBindingSetAuthInfo,RPCRT4.DLL,AW,6, sets authentication and authorization information RpcNsProfileEltAdd,RPCNS4.DLL,AW,7, adds an element to a profile. RpcNsProfileEltInqBegin,RPCNS4.DLL,AW,8 creates an inquiry context for viewing the into a binding handle. RpcBindingSetAuthInfoEx,RPCRT4.DLL,AW,7 sets authentication, authorization, and security elements in a profile. RpcNsProfileEltInqDone,RPCNS4.DLL,NM,1, deletes the inquiry context for viewing the quality-of-service information into a binding handle. elements in a profile. RpcBindingSetObject,RPCRT4.DLL,NM,2, sets the object UUID value in a binding handle. RpcNsProfileEltInqNext,RPCNS4.DLL,AW,5, returns one element at a time from a profile. RpcBindingSetOption,RPCRT4.DLL,NM,3 enables client applications to specify messageRpcNsProfileEltRemove,RPCNS4.DLL,AW,5, removes an element from a profile. queuing options on a binding handle. RpcObjectInqType,RPCRT4.DLL,NM,2, returns the type of an object. RpcBindingToStringBinding,RPCRT4.DLL,AW,2, returns a string representation of a binding RpcObjectSetInqFn,RPCRT4.DLL,NM,1, registers an object-inquiry function. handle. RpcBindingVectorFree,RPCRT4.DLL,NM,1, frees the binding handles contained in the vector RpcObjectSetType,RPCRT4.DLL,NM,2, assigns the type of an object. RpcProtseqVectorFree,RPCRT4.DLL,AW,1, frees the protocol sequences contained in the and the vector itself. vector and the vector itself. RpcCancelThread,RPCRT4.DLL,NM,1, cancels a thread. RpcEpRegister,RPCRT4.DLL,AW,4, adds to or replaces server address information in the local RpcRaiseException,RPCRT4.DLL,NM,1 Use the RpcRaiseExceptionto raise an exception. RpcRevertToSelf,RPCRT4.DLL,NM,0 After calling RpcImpersonateClient and completing any endpoint-map database. tasks thatrequire client impersonation, the server calls RpcRevertToSelf toend impersonation RpcEpRegisterNoReplace,RPCRT4.DLL,AW,4, adds server-address information to the local and to reestablish its own security identity. endpoint-map database. RpcRevertToSelfEx,RPCRT4.DLL,NM,1 After calling RpcImpersonateClient and completing RpcEpResolveBinding,RPCRT4.DLL,NM,2, resolves a partially bound server binding handle any tasks thatrequire client impersonation, the server calls RpcRevertToSelfEx toend into a fully bound server binding handle. impersonation and to reestablish its own security identity. RpcEpUnregister,RPCRT4.DLL,NM,3, removes server-address information from the local RpcServerInqBindings,RPCRT4.DLL,NM,1, returns the binding handles over which remote endpoint-map database. procedure calls can be received. RpcIfIdVectorFree,RPCNS4.DLL,NM,1 frees the vector and the interface-identification RpcServerInqDefaultPrincName,RPCRT4.DLL,AW,2, obtains the default principal name from structures contained in the vector. the server. RpcIfIdVectorFree,RPCRT4.DLL,NM,1 frees the vector and the interface-identification RpcServerInqIf,RPCRT4.DLL,NM,3, returns the manager entry-point vector (EPV) registered structures contained in the vector. for an interface. RpcIfInqId,RPCRT4.DLL,NM,2, returns the interface-identification part of an interface RpcServerListen,RPCRT4.DLL,NM,3, tells the RPC run-time library to listen for remote specification. procedure calls. RpcImpersonateClient,RPCRT4.DLL,NM,1 A server thread that is processing client remote RpcServerRegisterAuthInfo,RPCRT4.DLL,AW,4, registers authentication information with the procedure callscan call the RpcImpersonateClientto impersonate theactive client. RPC run-time library. RpcMgmtEnableIdleCleanup,RPCRT4.DLL,NM,0 closes idle resources, suchas network RpcServerRegisterIf,RPCRT4.DLL,NM,3 registers an interface with the RPC run-time library. connections, on the client. RpcServerRegisterIfEx,RPCRT4.DLL,NM,6, registers an interface with the RPC run-time RpcMgmtEpEltInqBegin,RPCRT4.DLL,NM,6 RpcMcreates an inquiry context for viewing the library. elements in an endpoint map. RpcServerUnregisterIf,RPCRT4.DLL,NM,3, unregisters an interface from the RPC run-time RpcMgmtEpEltInqDone,RPCRT4.DLL,NM,1, deletes the inquiry context for viewing the library. elements in an endpoint map. RpcServerUseAllProtseqs,RPCRT4.DLL,NM,2 tells the RPC run-time library to use all RpcMgmtEpEltInqNext,RPCRT4.DLL,AW,5, returns one element from an endpoint map. supported protocol sequences for receiving remote procedure calls. RpcMgmtEpUnregister,RPCRT4.DLL,NM,4 removes server address informationfrom an RpcServerUseAllProtseqsEx,RPCRT4.DLL,NM,3 tells the RPC run-timelibrary to use all endpoint map. supported protocol sequences for receivingremote procedure calls. RpcMgmtInqComTimeout,RPCRT4.DLL,NM,2, returns the binding- communications timeout RpcServerUseAllProtseqsIf,RPCRT4.DLL,NM,3 tells the RPC run-time library to use all the value in a binding handle. RpcMgmtInqDefaultProtectLevel,RPCRT4.DLL,NM,2, returns the default authentication level for specified protocol sequences and endpoints in the interface specification for receiving remote procedure calls. an authentication service. RpcMgmtInqIfIds,RPCRT4.DLL,NM,2 returns a vector containing the identifiers of the interfaces RpcServerUseAllProtseqsIfEx,RPCRT4.DLL,NM,4 tells the RPC run-time library to use all the specified protocol sequences and endpoints in the interface specification for receiving remote offered by the server. procedure calls. RpcMgmtInqServerPrincName,RPCRT4.DLL,AW,3, returns a server?s principal name. RpcServerUseProtseq,RPCRT4.DLL,AW,3 tells the RPC run-time library to use the specified RpcMgmtInqStats,RPCRT4.DLL,NM,2 returns RPC run-time statistics. protocol sequence for receiving remote procedure calls. RpcMgmtIsServerListening,RPCRT4.DLL,NM,1, tells whether a server is listening for remote RpcServerUseProtseqEp,RPCRT4.DLL,AW,4 tells the RPC run-time library to use the specified procedure calls. protocol sequence combined with the specified endpoint for receiving remote procedure calls. . RpcMgmtSetAuthorizationFn,RPCRT4.DLL,NM,1 establishes an authorizationfunction for RpcServerUseProtseqEpEx,RPCRT4.DLL,AW,5 tells the RPC run-time libraryto use the processing remote calls to a server?s managementroutines. specified protocol sequence combined with the specifiedendpoint for receiving remote RpcMgmtSetCancelTimeout,RPCRT4.DLL,NM,1, sets the lower bound on the time to wait procedure calls. before timing out after forwarding a cancel. RpcMgmtSetComTimeout,RPCRT4.DLL,NM,2, sets the binding-communications timeout value RpcServerUseProtseqEx,RPCRT4.DLL,AW,4 tells the RPC run-time libraryto use the specified protocol sequence for receiving remoteprocedure calls. in a binding handle. RpcServerUseProtseqIf,RPCRT4.DLL,AW,4 tells the RPC run-time library to use the specified RpcMgmtSetServerStackSize,RPCRT4.DLL,NM,1, specifies the stack size for each server protocol sequence combined with the endpoints in the interface specification for receiving thread. remote procedure calls. RpcMgmtStatsVectorFree,RPCRT4.DLL,NM,1, frees a statistics vector. RpcServerUseProtseqIfEx,RPCRT4.DLL,AW,5 tells the RPC run-time library to use the RpcMgmtStopServerListening,RPCRT4.DLL,NM,1, tells a server to stop listening for remote specified protocol sequence combined with the endpoints in the interface specification for procedure calls. RpcNetworkInqProtseqs,RPCRT4.DLL,AW,1 returns all protocol sequencessupported by both receiving remote procedure calls. RpcSmAllocate,RPCRT4.DLL,NM,2 allocates memory within the RPC stub memory the RPC run-time library and the operatingsystem. RpcNetworkIsProtseqValid,RPCRT4.DLL,AW,1 tells whether the specified protocol sequence is management function and returns a pointer to the allocated memory or NULL. RpcSmClientFree,RPCRT4.DLL,NM,1, frees memory returned from a client stub. supported by both the RPC run-time library and the operating system. RpcSmDestroyClientContext,RPCRT4.DLL,NM,1, reclaims the client memory resources for a RpcNsBindingExport,RPCNS4.DLL,AW,5 establishes a name-service databaseentry with context handle and makes the context handle NULL. multiple binding handles and multiple objects for aserver. RpcNsBindingImportBegin,RPCNS4.DLL,AW,5, creates an import context for an interface and RpcSmDisableAllocate,RPCRT4.DLL,NM,0, frees resources and memory within the stub memory management environment. an object. RpcSmEnableAllocate,RPCRT4.DLL,NM,0, establishes the stub memory management RpcNsBindingImportDone,RPCNS4.DLL,NM,1 signifies that a client hasfinished looking for a environment. compatible server and deletes the importcontext. RpcNsBindingImportNext,RPCNS4.DLL,NM,2 looks up an interface, and optionally an object, RpcSmFree,RPCRT4.DLL,NM,1, releases memory allocated by RpcSmAllocate. RpcSmGetThreadHandle,RPCRT4.DLL,NM,1, returns a thread handle, or NULL, for the stub from a name-service database and returns a binding handle of a compatible server (if found). memory management environment. RpcNsBindingInqEntryName,RPCRT4.DLL,AW,3, returns the entry name from which the RpcSmSetClientAllocFree,RPCRT4.DLL,NM,2, enables the memory allocation and release binding handle came. RpcNsBindingLookupBegin,RPCNS4.DLL,AW,6, creates a lookup context for an interface and mechanisms used by the client stubs. RpcSmSetThreadHandle,RPCRT4.DLL,NM,1, sets a thread handle for the stub memory an object. management environment. RpcNsBindingLookupDone,RPCNS4.DLL,NM,1 signifies that a client hasfinished looking for RpcSmSwapClientAllocFree,RPCRT4.DLL,NM,4 exchanges the memoryallocation and release compatible servers and deletes the lookupcontext. RpcNsBindingLookupNext,RPCNS4.DLL,NM,2, returns a list of compatible binding handles for mechanisms used by the client stubs with onesupplied by the client. a specified interface and optionally an object. 148 RpcSsAllocate,RPCRT4.DLL,NM,1 allocates memory within the RPC stubmemory management function, and returns a pointer to the allocatedmemory or NULL. RpcSsDestroyClientContext,RPCRT4.DLL,NM,1, destroys a context handle no longer needed by the client without contacting the server. RpcSsDisableAllocate,RPCRT4.DLL,NM,0, frees resources and memory within the stub memory management environment. RpcSsDontSerializeContext,RPCRT4.DLL,NM,0, disables runtime serialization of multiple calls dispatched to server manager routines on the same context handle. RpcSsEnableAllocate,RPCRT4.DLL,NM,0 establishes the stub memory management environment.. RpcSsFree,RPCRT4.DLL,NM,1, releases memory allocated by RpcSsAllocate. RpcSsGetThreadHandle,RPCRT4.DLL,NM,0, returns a thread handle for the stub memory management environment. RpcSsSetClientAllocFree,RPCRT4.DLL,NM,2, enables the memory allocation and release mechanisms used by the client stubs. RpcSsSetThreadHandle,RPCRT4.DLL,NM,1, sets a thread handle for the stub memory management environment. RpcSsSwapClientAllocFree,RPCRT4.DLL,NM,4 exchanges the memoryallocation and release mechanisms used by the client stubs with onesupplied by the client. RpcStringBindingCompose,RPCRT4.DLL,AW,6 combines the components of a string binding into a string binding. RpcStringBindingParse,RPCRT4.DLL,AW,6, returns the object UUID part and the address parts of a string binding as separate strings. RpcStringFree,RPCRT4.DLL,AW,1 frees a character string allocated by the RPC run-time library. RpcTestCancel,RPCRT4.DLL,NM,0, checks for a cancel indication. RTFSync,MAPI32.DLL,NM,3, ensures that the Rich Text Format (RTF) message text matches the plain text version. SafeArrayAccessData,OLEAUT32.DLL,NM,2,Increments the lock count of an array, and retrieves a pointer to the array data. SafeArrayAllocData,OLEAUT32.DLL,NM,1,This function allocates memory for a safearray, based on a descriptor created with SafeArrayAllocDescriptor. SafeArrayAllocDescriptor,OLEAUT32.DLL,NM,2,Allocates memory for a safearray descriptor. SafeArrayCopy,OLEAUT32.DLL,NM,2,Data4.2 SafeArrayCopyData This function copies the source array to the target array after releasing any resources in the target array. This function is SafeArrayCopyData,OLEAUT32.DLL,NM,2,4.2 This function copies the source array to the target array after releasing any resources in the target array. SafeArrayCreate,OLEAUT32.DLL,NM,3,VectorCreates a one-dimensional array whose lower bound is always zero. A safearray created with SafeArrayCreateVector is a fixed size, so the constant FADF_FIXEDSIZE is always set. SafeArrayCreateVector,OLEAUT32.DLL,NM,3,Creates a one-dimensional array whose lower bound is always zero. A safearray created with SafeArrayCreateVector is a fixed size, so the constant FADF_FIXEDSIZE is always set. SafeArrayDestroy,OLEAUT32.DLL,NM,1,Descriptor This function destroys a decriptor of a safe array. SafeArrayDestroyData,OLEAUT32.DLL,NM,1,This function destroys all the data in a safearray. SafeArrayDestroyDescriptor,OLEAUT32.DLL,NM,1, This function destroys a decriptor of a safe array. SafeArrayGetDim,OLEAUT32.DLL,NM,1,Returns the number of dimensions in the array. SafeArrayGetElement,OLEAUT32.DLL,NM,3,Retrieves a single element of the array. SafeArrayGetElemsize,OLEAUT32.DLL,NM,1, retrieves the size (in bytes) of the elements of a safearray. SafeArrayGetLBound,OLEAUT32.DLL,NM,3,4.2 returns the lower bound for any dimension of a safearray. SafeArrayGetUBound,OLEAUT32.DLL,NM,3,Returns the upper bound for any dimension of a safearray. SafeArrayLock,OLEAUT32.DLL,NM,1,This function increments the lock count of an array, and places a pointer to the array data in pvData of the array descriptor. SafeArrayPtrOfIndex,OLEAUT32.DLL,NM,3,Returns a pointer to an array element. SafeArrayPutElement,OLEAUT32.DLL,NM,3,Stores the data element at a given location in the array. SafeArrayRedim,OLEAUT32.DLL,NM,2,Changes the right-most (least significant) bound of a safearray. SafeArrayUnaccessData,OLEAUT32.DLL,NM,1,Decrements the lock count of an array, and invalidates the pointer retrieved by SafeArrayAccessData. SafeArrayUnlock,OLEAUT32.DLL,NM,1,Decrements the lock count of an array so it can be freed or resized. SaslAcceptSecurityContext,SECUR32.DLL,NM,9,Wraps a standard call to the Security Support Provider InterfaceB AcceptSecurityContext (General) function and includes creation of SASL server cookies. SaslEnumerateProfiles,SECUR32.DLL,AW,2,Lists the packages that provide a SASL interface. SaslGetProfilePackage,SECUR32.DLL,AW,2,Returns the package information for the specified package. SaslIdentifyPackage,SECUR32.DLL,AW,2,Returns the negotiate prefix that matches the specified SASL negotiation buffer. SaslInitializeSecurityContext,SECUR32.DLL,AW,12,Wraps a standard call to the Security Support Provider InterfaceB InitializeSecurityContext (General) function and processes SASL server cookies from the server. SatisfyNtmsOperatorRequest,NTMSAPI.DLL,NM,2, completes the specified RSM operator request. SaveDC,GDI32.DLL,NM,1 saves the current state of the specified device context (DC) by copying data describing selected objects and graphic modes (such as the bitmap, brush, palette, font, pen, region, drawing mode, and mapping mode) to a context stack. ScaleViewportExtEx,GDI32.DLL,NM,6 modifies the viewport for a devicecontext (DC) by using the ratios formed by the specifiedmultiplicands and divisors. ScaleWindowExtEx,GDI32.DLL,NM,6 modifies the window for a devicecontext using the ratios formed by the specified multiplicands anddivisors. ScBinFromHexBounded,MAPI32.DLL,NM,3 converts the specified portion of a string representation of a hexadecimal number into a binary number. ScCopyNotifications,MAPI32.DLL,NM,4, copies a group of event notifications to a single block of memory. ScCopyProps,MAPI32.DLL,NM,4, copies the properties defined by an array of SPropValue structures to a new destination. ScCountNotifications,MAPI32.DLL,NM,3 determines the size, in bytes, ofan array of event notifications, and validates the memoryassociated with the array. ScCountProps,MAPI32.DLL,NM,3 determines the size, in bytes, of aproperty value array and validates the memory associated with thearray. ScCreateConversationIndex,MAPI32.DLL,NM,4, indicates where in a message thread a message belongs. ScDupPropset,MAPI32.DLL,NM,4 duplicates a property value array in a single block of MAPI memory combining the operations of the ScCopyProps </native/mapi/src/func2mpf.htm> and ScCountProps functions. ScheduleJob,WINMM.DLL,NM,2, checks for a valid spool file. SchemaPreload,DAPI.DLL,AW,2, is an example of a process terminated by DAPIUninitialize. ScInitMapiUtil,MAPI32.DLL,NM,1, replaces MAPIInitialize when only select utility functions are being used. ScLocalPathFromUNC,MAPI32.DLL,NM,3, locates a local path counterpart to the given universal naming convention (UNC) path. ScreenToClient,USER32.DLL,NM,2, converts the screen coordinates of a specified point on the screen to client coordinates. ScRelocNotifications,MAPI32.DLL,NM,5, adjusts a pointer within a specified event notification array. ScRelocProps,MAPI32.DLL,NM,5 adjusts the pointers in an SPropValue array after the array and its data have been copied or moved to a new location. ScrollConsoleScreenBuffer,KERNEL32.DLL,AW,5, moves a block of data in a screen buffer. ScrollDC,USER32.DLL,NM,7, scrolls a rectangle of bits horizontally and vertically. ScrollWindow,USER32.DLL,NM,5, scrolls the content of the specified window?s client area. ScrollWindowEx,USER32.DLL,NM,8, scrolls the content of the specified window?s client area. ScUNCFromLocalPath,MAPI32.DLL,NM,3, locates a universal naming convention (UNC) path counterpart to the given local path. SealMessage,SECUR32.DLL,NM,4, is already documented under another name. For more information, see SpSealMessage. SearchPath,KERNEL32.DLL,AW,6, searches for the specified file. SearchTreeForFile,IMAGEHLP.DLL,NM,3, searches a directory tree for a specified file. select,WS2_32.DLL,NM,5, is used to determine the status of one or more sockets. select,WSOCK32.DLL,NM,5, is used to determine the status of one or more sockets. SelectClipPath,GDI32.DLL,NM,2, selects the current path as a clipping region for a device context, combining the new region with any existing clipping region by using the specified mode. . SelectClipRgn,GDI32.DLL,NM,2, selects a region as the current clipping region for the specified device context. SelectCMM,MSCMS.DLL,NM,1,SelectCMM allows an application to select the preferred color management module (CMM) to use. SelectObject,GDI32.DLL,NM,2 selects an object into the specified device context. SelectPalette,GDI32.DLL,NM,3, selects the specified logical palette into a device context. send,WS2_32.DLL,NM,4, is used to write outgoing data on a connected socket. send,WSOCK32.DLL,NM,4, is used to write outgoing data on a connected socket. SendDlgItemMessage,USER32.DLL,AW,5, sends a message to the specified control in a dialog box. SendInput,USER32.DLL,NM,3, synthesizes keystrokes, mouse motions, and button clicks. SendMessage,USER32.DLL,AW,4 sends the specified message to a window or windows. SendMessageCallback,USER32.DLL,AW,6, sends the specified message to a window or windows. SendMessageTimeout,USER32.DLL,AW,7, sends the specified message to a window or windows. SendNotifyMessage,USER32.DLL,AW,4, sends the specified message to a window. sendto,WS2_32.DLL,NM,6, is used to write outgoing data on a socket. sendto,WSOCK32.DLL,NM,6, is used to write outgoing data on a socket. SetAbortProc,GDI32.DLL,NM,2, sets the application-defined abort function that allows a print job to be canceled during spooling. SetAclInformation,ADVAPI32.DLL,NM,4, sets information about an access- control list (ACL). SetActiveWindow,USER32.DLL,NM,1, activates a window, but not if the application is in the background. SetArcDirection,GDI32.DLL,NM,2 sets the drawing direction to be used for arc and rectangle functions. SetAttribIMsgOnIStg,MAPI32.DLL,NM,4 sets or alters attributes ofproperties on an IMessage object supplied by the OpenIMsgOnIStgfunction. SetBitmapBits,GDI32.DLL,NM,3, sets the bits of color data for a bitmap to the specified values. SetBitmapDimensionEx,GDI32.DLL,NM,4, assigns preferred dimensions to a bitmap. SetBkColor,GDI32.DLL,NM,2 sets the current background color to thespecified color value, or to the nearest physical color if thedevice cannot represent the specified color value. SetBkMode,GDI32.DLL,NM,2, sets the background mix mode of the specified device context. SetBoundsRect,GDI32.DLL,NM,3 controls the accumulation of bounding rectangle information for the specified device context. SetBrushOrgEx,GDI32.DLL,NM,4 sets the brush origin that GDI assigns to the next brush an application selects into the specified device context. SetCapture,USER32.DLL,NM,1, sets the mouse capture to the specified window belonging to the current thread. SetCaretBlinkTime,USER32.DLL,NM,1, sets the caret blink time to the specified number of milliseconds. SetCaretPos,USER32.DLL,NM,2 moves the caret to the specified coordinates. SetClassLong,USER32.DLL,AW,3 replaces the specified 32-bit (long) value at the specified offset into the extra class memory or the WNDCLASSEX structure for the class to which the specified window belongs. SetClassWord,USER32.DLL,NM,3 replaces the 16-bit (word) value at thespecified offset into the extra class memory for the window classto which the specified window belongs. SetClipboardData,USER32.DLL,NM,2, places data on the clipboard in a specified clipboard format. SetColorAdjustment,GDI32.DLL,NM,2, sets the color adjustment values for a device context using the specified values. SetColorProfileElement,MSCMS.DLL,NM,5, sets the element data for a tagged profile element. SetColorProfileElementReference,MSCMS.DLL,NM,3,SetColorProfileElementReference creates in a specified color profile a new tag which references the same data as an existing tag. SetColorProfileElementSize,MSCMS.DLL,NM,3,SetColorProfileElementSize sets the size of a tagged element. SetColorProfileHeader,MSCMS.DLL,NM,2, sets the header data in a specified color profile. SetCommBreak,KERNEL32.DLL,NM,1 suspends character transmission for aspecified communications device and places the transmission line ina break state until the ClearCommBreak function is called. SetCommConfig,KERNEL32.DLL,NM,3, sets the current configuration of a communications device. SetCommMask,KERNEL32.DLL,NM,2, specifies a set of events to be monitored for a communications device. SetCommState,KERNEL32.DLL,NM,2 configures a communications device according to the specifications in a device-control block SetCommTimeouts,KERNEL32.DLL,NM,2 sets the time-out parameters for all read and write operations on a specified communications device. SetComputerName,KERNEL32.DLL,AW,1, sets the computer name to be used the next time the system is restarted. SetConsoleActiveScreenBuffer,KERNEL32.DLL,NM,1, sets the specified screen buffer to be the currently displayed console screen buffer. SetConsoleCP,KERNEL32.DLL,NM,1, sets the input code page used by the console associated with the calling process. SetConsoleCtrlHandler,KERNEL32.DLL,NM,2 adds or removes an application-defined HandlerRoutine function from the list of handler functions for the calling process. SetConsoleCursorInfo,KERNEL32.DLL,NM,2, sets the size and visibility of the cursor for the specified console screen buffer. SetConsoleCursorPosition,KERNEL32.DLL,NM,2, sets the cursor position in the specified console screen buffer. SetConsoleMode,KERNEL32.DLL,NM,2 sets the input mode of a console?sinput buffer or the output mode of a console screen buffer. SetConsoleOutputCP,KERNEL32.DLL,NM,1, sets the output code page used by the console associated with the calling process. SetConsoleScreenBufferSize,KERNEL32.DLL,NM,2, changes the size of the specified console screen buffer. 149 SetConsoleTextAttribute,KERNEL32.DLL,NM,2 sets the foreground (text) and background color SetPrinter,WINMM.DLL,AW,4, sets the state of the specified printer by pausing printing, attributes of characters written to the screen buffer by the WriteFile or WriteConsole function, resuming printing, or clearing all print jobs. SetPrinterData,WINMM.DLL,AW,5, sets the configuration data for a printer. or echoed by the ReadFile or ReadConsole function. SetConsoleTitle,KERNEL32.DLL,AW,1, sets the title bar string for the current console window. SetPriorityClass,KERNEL32.DLL,NM,2, sets the priority class for the specified process. SetPrivateObjectSecurity,ADVAPI32.DLL,NM,5, modifies a private object?s security descriptor. SetConsoleWindowInfo,KERNEL32.DLL,NM,3 sets the current size and position of a console SetProcessAffinityMask,KERNEL32.DLL,NM,2 sets a processor affinity mask for the threads of screen buffer?s window. a specified process. SetConvertStg,OLE32.DLL,NM,2, sets the convert bit in a storage object to indicate that the object is to be converted to a new class when it is opened. The setting can be retrieved with a SetProcessPriorityBoost,KERNEL32.DLL,NM,2 disables the ability of Windows NT to temporarily boost the priority of the threads of the specified process. call to the GetConvertStg function. SetProcessShutdownParameters,KERNEL32.DLL,NM,2, sets shutdown parameters for the SetCurrentDirectory,KERNEL32.DLL,AW,1 changes the current directory for the current currently calling process. process. SetProcessWindowStation,USER32.DLL,NM,1, assigns a window station to the calling process. SetCursor,USER32.DLL,NM,1, establishes the cursor shape. SetProcessWorkingSetSize,KERNEL32.DLL,NM,3, sets the minimum and maximum working SetCursorPos,USER32.DLL,NM,2, moves the cursor to the specified screen coordinates. set sizes for a specified process. SetDebugErrorLevel,USER32.DLL,NM,1 sets the minimum error level atwhich Windows will SetProp,USER32.DLL,AW,3 adds a new entry or changes an existing entry in the property list generate debugging events and pass them to adebugger. of the specified window. SetDefaultCommConfig,KERNEL32.DLL,AW,3, sets the default configuration for a SetRect,USER32.DLL,NM,5, sets the coordinates of the specified rectangle. communications device. SetRectEmpty,USER32.DLL,NM,1 creates an empty rectangle in which all coordinates are set SetDIBColorTable,GDI32.DLL,NM,4 sets RGB (red, green, blue) color values in a range of entries in the color table of the device-independent bitmap (DIB) that is currently selected into a to zero. SetRectRgn,GDI32.DLL,NM,5, changes a region into a rectangular region with the specified specified device context. coordinates. SetDIBits,GDI32.DLL,NM,7, sets the pixels in a bitmap using the color data found in the SetROP2,GDI32.DLL,NM,2, sets the current foreground mix mode. specified device-independent bitmap (DIB). SetScrollInfo,USER32.DLL,NM,4 sets the parameters of a scroll bar,including the minimum and SetDIBitsToDevice,GDI32.DLL,NM,12 sets the pixels in the specified rectangle on the device maximum scrolling positions, the pagesize, and the position of the scroll box (thumb). that is associated with the destination device context using color data from a deviceSetScrollPos,USER32.DLL,NM,4 sets the position of the scroll box(thumb) in the specified independent bitmap (DIB). scroll bar and, if requested, redraws thescroll bar to reflect the new position of the scroll box. SetDlgItemInt,USER32.DLL,NM,4, sets the text of a control in a dialog box to the string SetScrollRange,USER32.DLL,NM,5, sets the minimum and maximum position values for the representation of a specified integer value. specified scroll bar. SetDlgItemText,USER32.DLL,AW,3, sets the title or text of a control in a dialog box. SetSecurityDescriptorDacl,ADVAPI32.DLL,NM,4, sets information in a discretionary accessSetDoubleClickTime,USER32.DLL,NM,1, sets the double-click time for the mouse. SetEndOfFile,KERNEL32.DLL,NM,1 Sets End-of-file (EOF) position for the specified file to the control list (ACL). SetSecurityDescriptorGroup,ADVAPI32.DLL,NM,3 sets the primary group information of an current position of the file pointer. absolute-format security descriptor, replacing any primary group information already present in SetEnhMetaFileBits,GDI32.DLL,NM,2, creates a memory-based enhanced- format metafile the security descriptor. from the supplied data. SetEntriesInAcl,ADVAPI32.DLL,AW,4 creates a new access-control list(ACL) by merging new SetSecurityDescriptorOwner,ADVAPI32.DLL,NM,3, sets the owner information of an absoluteformat security descriptor. access-control or audit-control informationinto an existing ACL. SetEnvironmentVariable,KERNEL32.DLL,AW,2, sets the value of an environment variable for SetSecurityDescriptorSacl,ADVAPI32.DLL,NM,4, sets information in a system access-control list (ACL). the current process. SetSecurityInfo,ADVAPI32.DLL,NM,7, sets specified security information in the security SetErrorInfo,OLEAUT32.DLL,NM,2, (Visual C++ Concepts)Called by OnWizFinish and descriptor of a specified object. CanUseFileName to provide current error information. SetErrorMode,KERNEL32.DLL,NM,1, controls how the operating system handles several types SetService,MSWSOCK.DLL,AW,6,Important is obsolete. SetService,WSOCK32.DLL,AW,6,Important is obsolete. of serious errors. SetServiceBits,ADVAPI32.DLL,NM,4 registers a service type with the service control manager SetEvent,KERNEL32.DLL,NM,1 sets the state of the specified event object to signaled. SetFileApisToOEM,KERNEL32.DLL,NM,0, causes a set of Win32 file functions to use the OEM and the Server service. SetServiceObjectSecurity,ADVAPI32.DLL,NM,3, sets the security descriptor of a service object. code page. SetServiceStatus,ADVAPI32.DLL,NM,2, updates the service control manager?s status SetFileAttributes,KERNEL32.DLL,AW,2, sets a file?s attributes. information for the calling service. SetFilePointer,KERNEL32.DLL,NM,4, moves the file pointer of an open file. setsockopt,WS2_32.DLL,NM,5, sets a socket option. SetFileSecurity,ADVAPI32.DLL,AW,3 sets the security of a file or directory object. setsockopt,WSOCK32.DLL,NM,5, sets a socket option. SetFileTime,KERNEL32.DLL,NM,4, sets the date and time that a file was created, last SetStandardColorSpaceProfile,MSCMS.DLL,AW,3, registers a specified profile for a given accessed, or last modified. standard color space. SetFocus,USER32.DLL,NM,1 sets the keyboard focus to the specified window. SetForegroundWindow,USER32.DLL,NM,1, puts the thread that created the specified window SetStdHandle,KERNEL32.DLL,NM,2, is used to set the handle for the standard input, standard output, or standard error device. into the foreground and activates the window. SetStretchBltMode,GDI32.DLL,NM,2, sets the bitmap stretching mode in the specified device SetForm,WINMM.DLL,AW,5, sets the form information for the specified printer. context. SetGraphicsMode,GDI32.DLL,NM,2 sets the graphics mode for the specified device context. SetHandleCount,KERNEL32.DLL,NM,1, sets the number of file handles available to a process. SetSysColors,USER32.DLL,NM,3, sets the colors for one or more display elements. SetSystemCursor,USER32.DLL,NM,2 replaces the contents of the system cursor specified by SetHandleInformation,KERNEL32.DLL,NM,3 sets certain properties of an object handle. SetImageConfigInformation,IMAGEHLP.DLL,NM,2, locates and changes the load configuration id with the contents of the cursor specified by hcur, and then destroys hcur. SetSystemPaletteUse,GDI32.DLL,NM,2, allows an application to specify whether the system data of an image. palette contains 2 or 20 static colors. SetJob,WINMM.DLL,AW,5, pauses, resumes, cancels, or restarts a print job on a specified SetSystemPowerState,KERNEL32.DLL,NM,2, suspends the system by shutting power down. printer. SetSystemTime,KERNEL32.DLL,NM,1, sets the current system time and date. SetKernelObjectSecurity,ADVAPI32.DLL,NM,3 sets the security of a kernel object. SetKeyboardState,USER32.DLL,NM,1, copies a 256-byte array of keyboard key states into the SetTapeParameters,KERNEL32.DLL,NM,3, either specifies the block size of a tape or configures the tape device. calling thread?s keyboard-input state table. SetTapePosition,KERNEL32.DLL,NM,6 sets the tape position on the specified device. SetLastError,KERNEL32.DLL,NM,1, sets the last-error code for the calling thread. SetTextAlign,GDI32.DLL,NM,2, sets the text-alignment flags for the specified device context. SetLastErrorEx,USER32.DLL,NM,2, sets the last-error code. SetTextCharacterExtra,GDI32.DLL,NM,2 sets the intercharacter spacing. SetLocaleInfo,KERNEL32.DLL,AW,3, sets an item of locale information. SetTextColor,GDI32.DLL,NM,2, sets the text color for the specified device context to the SetLocalTime,KERNEL32.DLL,NM,1, sets the current local time and date. SetMailslotInfo,KERNEL32.DLL,NM,2, sets the time-out value used by the specified mailslot for specified color. SetTextJustification,GDI32.DLL,NM,3, specifies the amount of space Windows should add to a read operation. the break characters in a string of text. SetMapMode,GDI32.DLL,NM,2, sets the mapping mode of the specified device context. SetThreadAffinityMask,KERNEL32.DLL,NM,2, sets a processor affinity mask for a specified SetMapperFlags,GDI32.DLL,NM,2, alters the algorithm the font mapper uses when it maps thread. logical fonts to physical fonts. SetThreadContext,KERNEL32.DLL,NM,2, sets the context in the specified thread. SetMenu,USER32.DLL,NM,2, assigns a new menu to the specified window. SetThreadDesktop,USER32.DLL,NM,1, assigns a desktop to the calling thread. SetMenuContextHelpId,USER32.DLL,NM,2, associates a help context identifier with a menu. SetThreadIdealProcessor,KERNEL32.DLL,NM,2, is used to specify a preferred processor for a SetMenuDefaultItem,USER32.DLL,NM,3, sets the default menu item for the specified menu. thread. SetMenuItemBitmaps,USER32.DLL,NM,5 associates the specified bitmap with a menu item. SetThreadLocale,KERNEL32.DLL,NM,1, sets the calling thread?s current locale. SetMenuItemInfo,USER32.DLL,AW,4 changes information about a menu item. SetThreadPriority,KERNEL32.DLL,NM,2, sets the priority value for the specified thread. SetMessageExtraInfo,USER32.DLL,NM,1, sets the extra message information for the current SetThreadPriorityBoost,KERNEL32.DLL,NM,2, disables the ability of Windows NT to thread. temporarily boost the priority of a thread. SetMessageQueue,USER32.DLL,NM,1, is obsolete. SetMetaFileBitsEx,GDI32.DLL,NM,2, creates a memory-based Windows- format metafile from SetThreadToken,ADVAPI32.DLL,NM,2, assigns an impersonation token to a thread. SetTimer,USER32.DLL,NM,4, creates a timer with the specified time-out value. the supplied data. SetTimeZoneInformation,KERNEL32.DLL,NM,1 sets the current time-zone parameters. SetMetaRgn,GDI32.DLL,NM,1 intersects the current clipping region for the specified device context with the current metaregion and saves the combined region as the new metaregion for SetTokenInformation,ADVAPI32.DLL,NM,4, sets various types of information for a specified access token. the specified device context. SetUnhandledExceptionFilter,KERNEL32.DLL,NM,1 lets an applicationsupersede the top-level SetMiterLimit,GDI32.DLL,NM,3, sets the limit for the length of miter joins for the specified exception handler that Win32 places at thetop of each thread and process. device context. SetNamedPipeHandleState,KERNEL32.DLL,NM,4, sets the read mode and the blocking mode SetupColorMatching,ICMUI.DLL,AW,1,creates a Color Management dialog box that lets the user choose whether to enable color management, and if so, provides control over the color of the specified named pipe. SetNamedSecurityInfo,ADVAPI32.DLL,AW,7 sets specified security information in the security profiles used and over the rendering intent. SetupComm,KERNEL32.DLL,NM,3, initializes the communications parameters for a specified descriptor of a specified object. communications device. SetNtmsMediaComplete,NTMSAPI.DLL,NM,2, marks a piece of logical media as complete. SetUrlCacheConfigInfo,WININET.DLL,AW,2,4.2 sets cache configuration information. SetNtmsObjectAttribute,NTMSAPI.DLL,AW,6, creates an extended attribute (named private BOOLAPI SetUrlCacheConfigInfoA( LPINTERNET_CACHE_CONFIG_INFOA data) in the specified RSM object. SetUrlCacheEntryGroup,WININET.DLL,AW,7,Adds entries to or removes entries from a cache SetNtmsObjectInformation,NTMSAPI.DLL,AW,3, changes the information structure of the group. specified object. SetUrlCacheEntryInfo,WININET.DLL,AW,3,Sets the specified members of the SetNtmsObjectSecurity,NTMSAPI.DLL,NM,5, writes the security descriptor for the specified INTERNET_CACHE_ENTRY_INFO structure. RSM object. SetUrlCacheGroupAttribute,WININET.DLL,AW,6,Sets the attribute information of the specified SetNtmsRequestOrder,NTMSAPI.DLL,NM,3, sets the order that the specified request will be cache group. processed in the library queue. SetUserObjectInformation,USER32.DLL,AW,4, sets information about a window station or SetPaletteEntries,GDI32.DLL,NM,4, sets RGB (red, green, blue) color values and flags in a desktop object. range of entries in a logical palette. SetUserObjectSecurity,USER32.DLL,NM,3, sets the security of a user object. SetParent,USER32.DLL,NM,2 changes the parent window of the specified child window. SetViewportExtEx,GDI32.DLL,NM,4 sets the horizontal and vertical extents of the viewport for a SetPixel,GDI32.DLL,NM,4, sets the pixel at the specified coordinates to the specified color. device context by using the specified values. SetPixelFormat,GDI32.DLL,NM,3 sets the pixel format of the specified device context to the SetViewportOrgEx,GDI32.DLL,NM,4, sets the viewport origin of a device context by using the format specified by the iPixelFormat index. specified coordinates. SetPixelV,GDI32.DLL,NM,4, sets the pixel at the specified coordinates to the closest SetVolumeLabel,KERNEL32.DLL,AW,2, sets the label of a file system volume. approximation of the specified color. SetWaitableTimer,KERNEL32.DLL,NM,6, activates the specified ?waitable? timer. SetPolyFillMode,GDI32.DLL,NM,2, sets the polygon fill mode for functions that fill polygons. 150 SetWindowContextHelpId,USER32.DLL,NM,2, associates a help context identifier with the specified window. SetWindowExtEx,GDI32.DLL,NM,4 sets the horizontal and vertical extents of the window for a device context by using the specified values. SetWindowLong,USER32.DLL,AW,3 changes an attribute of the specifiedwindow. SetWindowOrgEx,GDI32.DLL,NM,4, sets the window origin of the device context by using the specified coordinates. SetWindowPlacement,USER32.DLL,NM,2 sets the show state and therestored, minimized, and maximized positions of the specifiedwindow. SetWindowPos,USER32.DLL,NM,7 changes the size, position, and Z order of a child, pop-up, or top-level window. SetWindowRgn,USER32.DLL,NM,3, sets the window region of a window. SetWindowsHook,USER32.DLL,AW,2 is obsolete. SetWindowsHookEx,USER32.DLL,AW,4, installs an application-defined hook procedure into a hook chain. SetWindowText,USER32.DLL,AW,2, changes the text of the specified window?s title bar (if it has one). SetWindowWord,USER32.DLL,NM,3, is obsolete. SetWinMetaFileBits,GDI32.DLL,NM,4 converts a metafile from the older Windows format to the new enhanced format and stores the new metafile in memory. SetWorldTransform,GDI32.DLL,NM,2 sets a two-dimensional linear transformation between world space and page space for the specified device context. SHAddToRecentDocs,SHELL32.DLL,NM,2 _hreadAdds a document to the shell?s list of recently used documents orclears all documents from the list. SHAppBarMessage,SHELL32.DLL,NM,2 Sends an appbar message to the system. SHBrowseForFolder,SHELL32.DLL,AW,1 Displays a dialog box that enables the user to select a shellfolder. SHChangeNotify,SHELL32.DLL,NM,4 Notifies the system of an event that an application has performed. ShellAbout,SHELL32.DLL,AW,4, displays a Shell About dialog box. ShellExecute,SHELL32.DLL,AW,6, opens or prints a specified file. ShellExecuteEx,SHELL32.DLL,AW,1, performs an action on a file. Shell_NotifyIcon,SHELL32.DLL,AW,2 Sends a message to the system to add, modify, or delete an iconfrom the taskbar status area. SHFileOperation,SHELL32.DLL,AW,1 Performs a copy, move, rename, or delete operation on a file systemobject. SHFree,SHELL32.DLL,NM,1 Frees the memory allocated by SHAlloc. SHFreeNameMappings,SHELL32.DLL,NM,1 Frees a file name mapping object that was retrieved by the SHFileOperation function. SHGetDataFromIDList,SHELL32.DLL,AW,5 retrieves extended property datafrom a relative IDList. SHGetDesktopFolder,SHELL32.DLL,NM,1 Retrieves the IShellFolder interface for the desktop folder, whichis the root of the shell?s name space. SHGetFileInfo,SHELL32.DLL,AW,5 Retrieves information about an object in the file system, such as afile, a folder, a directory, or a drive root. SHGetInstanceExplorer,SHELL32.DLL,NM,1 Retreives the address of the Explorer?s IUnknown interface. SHGetMalloc,SHELL32.DLL,NM,1 Retrieves a pointer to the shell?s IMalloc interface. SHGetPathFromIDList,SHELL32.DLL,AW,2 Converts an item identifier list to a file system path. SHGetSpecialFolderLocation,SHELL32.DLL,NM,3 Retrieves the location of a special folder. SHLoadInProc,SHELL32.DLL,NM,1 Creates an instance of the specified object class from within thecontext of the shell?s process. ShowCaret,USER32.DLL,NM,1, makes the caret visible on the screen at the caret?s current position. ShowCursor,USER32.DLL,NM,1, displays or hides the cursor. ShowHideMenuCtl,COMCTL32.DLL,NM,3 sets or removes the specified menuitem?s checkmark attribute, and shows or hides the correspondingcontrol. ShowOwnedPopups,USER32.DLL,NM,2, shows or hides all pop-up windows owned by the specified window. ShowScrollBar,USER32.DLL,NM,3 shows or hides the specified scroll bar. ShowWindow,USER32.DLL,NM,2, sets the specified window?s show state. ShowWindowAsync,USER32.DLL,NM,2, sets the show state of a window created by a different thread. shutdown,WS2_32.DLL,NM,2, is used on all types of sockets to disable reception, transmission, or both. shutdown,WSOCK32.DLL,NM,2, is used on all types of sockets to disable reception, transmission, or both. SignalObjectAndWait,KERNEL32.DLL,NM,4, allows the caller to atomically signal an object and wait on another object. SizeofResource,KERNEL32.DLL,NM,2, returns the size, in bytes, of the specified resource. Sleep,KERNEL32.DLL,NM,1, suspends the execution of the current thread for a specified interval. SleepEx,KERNEL32.DLL,NM,2 causes the current thread to enter a wait state An I/O completion callback function is called, An asynchronous procedure call (APC) is queued to the thread., The time-out interval elapses sndPlaySound,WINMM.DLL,AW,2, plays a waveform sound specified either by a filename or by an entry in the registry or the WIN. SnmpMgrClose,MGMTAPI.DLL,NM,1, closes communications sockets and data structures associated with the specified session. SnmpMgrCtl,MGMTAPI.DLL,NM,7,sets an operating parameter associated with an SNMP session. SnmpMgrGetTrap,MGMTAPI.DLL,NM,6, returns outstanding trap data that the caller has not received if trap reception is enabled. SnmpMgrGetTrapEx,MGMTAPI.DLL,NM,8,returns outstanding trap data that the caller has not received if trap reception is enabled. SnmpMgrOidToStr,MGMTAPI.DLL,NM,2 converts an internal object identifier to a string object identifier or object descriptor representation. SnmpMgrOpen,MGMTAPI.DLL,NM,4, initializes communications sockets and data structures, allowing communications with the specified agent. SnmpMgrRequest,MGMTAPI.DLL,NM,5, requests the specified operation be performed with the specified agent. SnmpMgrStrToOid,MGMTAPI.DLL,NM,2, converts an internal object identifier to a string object identifier or object descriptor representation. SnmpMgrTrapListen,MGMTAPI.DLL,NM,1, registers the ability of a manager application to receive SNMP traps. SnmpUtilMemAlloc,SNMPAPI.DLL,NM,1, allocates dynamic memory from the process heap. SnmpUtilMemFree,SNMPAPI.DLL,NM,1, frees the specified memory object. SnmpUtilMemReAlloc,SNMPAPI.DLL,NM,2, changes the size of the specified memory object. SnmpUtilOidAppend,SNMPAPI.DLL,NM,2, appends the source object identifier to the destination object identifier. SnmpUtilOidCmp,SNMPAPI.DLL,NM,2, compares two object identifiers. SnmpUtilOidCpy,SNMPAPI.DLL,NM,2 copies the variable pointed to by theSrcObjId parameter to the DestObjId parameter, allocating anynecessary memory for the destination?s copy. SnmpUtilOidFree,SNMPAPI.DLL,NM,1, frees any allocated data associated with the object identifier. SnmpUtilOidNCmp,SNMPAPI.DLL,NM,3, compares two object identifier variables up to the length specified by the Len parameter. SnmpUtilPrintAsnAny,SNMPAPI.DLL,NM,1, prints the value of the Any parameter to the standard output. SnmpUtilVarBindCpy,SNMPAPI.DLL,NM,2 copies the RFC1157VarBindstructure, and allocates any memory necessary for the destinationstructure. SnmpUtilVarBindFree,SNMPAPI.DLL,NM,1 frees any allocated data associated with an RFC1157VarBind structure. SnmpUtilVarBindListCpy,SNMPAPI.DLL,NM,2 copies the RFC1157VarBindListstructure, and allocates any necessary memory for the destination'scopy. SnmpUtilVarBindListFree,SNMPAPI.DLL,NM,1, frees any allocated data associated with an RFC1157VarBindList structure. socket,WS2_32.DLL,NM,3 creates a socket that is bound to a specific service provider. socket,WSOCK32.DLL,NM,3 creates a socket that is bound to a specific service provider. SplitSymbols,IMAGEHLP.DLL,NM,4, strips symbols from the specified image. SpoolerCopyFileEvent,MSCMS.DLL,NM,3,graphics, GraphicsDrivers, Reference, SpoolerCopyFileEvent SQLAllocConnect,ODBC32.DLL,NM,2 Obsolete SQLAllocEnv,ODBC32.DLL,NM,1 Obsolete SQLAllocHandle,ODBC32.DLL,NM,3 Obtains an environment, connection, statement, or descriptor handle. SQLAllocHandleStd,ODBC32.DLL,NM,3 Default SQLAllocHandle routine SQLAllocStmt,ODBC32.DLL,NM,2 Obsolete SQLBindCol,ODBC32.DLL,NM,6 Assigns storage for a result column and specifies the data type. SQLBindParam,ODBC32.DLL,NM,8 Obsolete SQLBindParameter,ODBC32.DLL,NM,10 Assigns storage for a parameter in an SQL statement. SQLBrowseConnect,ODBC32.DLL,AW,6 Returns successive levels of connection attributes and valid attribute values SQLBulkOperations,ODBC32.DLL,NM,2 Performs bulk insertions and bulk bookmark operations, including update, delete, and fetch by bookmark. SQLCancel,ODBC32.DLL,NM,1 Cancels an SQL statement. SQLCloseCursor,ODBC32.DLL,NM,1 Closes a cursor that has been opened on a statement handle. SQLColAttribute,ODBC32.DLL,AW,7, returns descriptor information for a column in a result set. Descriptor information is returned as a character string, a 32-bit descriptor-dependent value, or an integer value. SQLColAttributes,ODBC32.DLL,AW,7 Obsolete SQLColumnPrivileges,ODBC32.DLL,AW,9 Returns a list of columns and associated privileges for one or more tables. SQLColumns,ODBC32.DLL,AW,9 Returns the list of column names in specified tables. SQLConnect,ODBC32.DLL,AW,7 Connects to a specific driver by data source name, user ID, and password. SQLCopyDesc,ODBC32.DLL,NM,2 copies descriptor information from one descriptor handle to another. SQLDataSources,ODBC32.DLL,AW,8 Returns the list of available data sources. SQLDescribeCol,ODBC32.DLL,AW,9 Describes a column in the result set. SQLDescribeParam,ODBC32.DLL,NM,6 Returns the description for a specific parameter in a statement. SQLDisconnect,ODBC32.DLL,NM,1 Closes the connection. SQLDriverConnect,ODBC32.DLL,AW,8 Connects to a specific driver by connection string or requests that the Driver Manager and driver display connection dialog boxes for the user. SQLDrivers,ODBC32.DLL,AW,8 Returns the list of installed drivers and their attributes. SQLEndTran,ODBC32.DLL,NM,3 Commits or rolls back a transaction. SQLError,ODBC32.DLL,AW,8 Returns error or status information. SQLExecDirect,ODBC32.DLL,AW,3 Executes a statement. SQLExecute,ODBC32.DLL,NM,1 Executes a prepared statement. SQLExtendedFetch,ODBC32.DLL,NM,5 fetches the specified rowset of data from the result set and returns data for all bound columns. SQLFetch,ODBC32.DLL,NM,1 Returns multiple result rows. SQLFetchScroll,ODBC32.DLL,NM,3 fetches the specified rowset of data from the result set and returns data for all bound columns. SQLForeignKeys,ODBC32.DLL,AW,13 Returns a list of column names that make up foreign keys, if they exist for a specified table. SQLFreeConnect,ODBC32.DLL,NM,1 Obsolete SQLFreeEnv,ODBC32.DLL,NM,1 Obsolete SQLFreeHandle,ODBC32.DLL,NM,2 Releases an environment, connection, statement, or descriptor handle. SQLFreeStmt,ODBC32.DLL,NM,2 Ends statement processing, discards pending results, and, optionally, frees all resources associated with the statement handle. SQLGetConnectAttr,ODBC32.DLL,AW,5 Returns the value of a connection attribute. SQLGetConnectOption,ODBC32.DLL,AW,3 Obsolete SQLGetCursorName,ODBC32.DLL,AW,4 Returns the cursor name associated with a statement handle. SQLGetData,ODBC32.DLL,NM,6 Returns part or all of one column of one row of a result set SQLGetDescField,ODBC32.DLL,AW,6 Returns the value of a single descriptor field. SQLGetDescRec,ODBC32.DLL,AW,11 Returns the values of multiple descriptor fields. SQLGetDiagField,ODBC32.DLL,AW,7 Returns additional diagnostic information SQLGetDiagRec,ODBC32.DLL,AW,8 Returns additional diagnostic information SQLGetEnvAttr,ODBC32.DLL,NM,5 Returns the value of an environment attribute. SQLGetFunctions,ODBC32.DLL,NM,3 Returns supported driver functions SQLGetInfo,ODBC32.DLL,AW,5 Returns information about a specific driver and data source. SQLGetStmtAttr,ODBC32.DLL,AW,5 Returns the value of a statement attribute. SQLGetStmtOption,ODBC32.DLL,NM,3 Obsolete SQLGetTypeInfo,ODBC32.DLL,AW,2 Returns information about supported data types. SQLMoreResults,ODBC32.DLL,NM,1 Determines whether there are more result sets available and, if so, initializes processing for the next result set. SQLNativeSql,ODBC32.DLL,AW,6 Returns the text of an SQL statement as translated by the driver. SQLNumParams,ODBC32.DLL,NM,2 Returns the number of parameters in a statement. SQLNumResultCols,ODBC32.DLL,NM,2 Returns the number of columns in the result set. SQLParamData,ODBC32.DLL,NM,2 Used in conjunction with SQLPutData to supply parameter data at execution time. SQLParamOptions,ODBC32.DLL,NM,3 Obsolete SQLPrepare,ODBC32.DLL,AW,3 Prepares an SQL statement for later execution. SQLPrimaryKeys,ODBC32.DLL,AW,7 Returns the list of column names that make up the primary key for a table. SQLProcedureColumns,ODBC32.DLL,AW,9 Returns the list of input and output parameters, as well as the columns that make up the result set for the specified procedures. SQLProcedures,ODBC32.DLL,AW,7 Returns the list of procedure names stored in a specific data source. SQLPutData,ODBC32.DLL,NM,3 Sends part or all of a data value for a parameter. SQLRowCount,ODBC32.DLL,NM,2 Returns the number of rows affected by an insert, update, or delete request. SQLSetConnectAttr,ODBC32.DLL,AW,4 Sets a connection attribute. SQLSetConnectOption,ODBC32.DLL,AW,3 Obsolete SQLSetCursorName,ODBC32.DLL,AW,3 Specifies a cursor name. SQLSetDescField,ODBC32.DLL,AW,5 sets the value of a single field of a descriptor record. SQLSetEnvAttr,ODBC32.DLL,NM,4 Sets an environment attribute. SQLSetParam,ODBC32.DLL,NM,8 Obsolete SQLSetPos,ODBC32.DLL,NM,4 Positions a cursor within a fetched block of data, and allows an application to refresh data in the rowset, or update or delete data in the result set. 151 SQLSetScrollOptions,ODBC32.DLL,NM,4 Sets options that control cursor behavior. SQLSetStmtAttr,ODBC32.DLL,AW,4 Sets a statement attribute. SQLSetStmtOption,ODBC32.DLL,NM,3 Obsolete SQLSpecialColumns,ODBC32.DLL,AW,10 Returns information about the optimal set of columns that uniquely identifies a row in a specified table, or the columns that are automatically updated when any value in the row is updated by a transaction. SQLStatistics,ODBC32.DLL,AW,9 Returns statistics about a single table and the list of indexes associated with the table. SQLTablePrivileges,ODBC32.DLL,AW,7 Returns a list of tables and the privileges associated with each table. SQLTables,ODBC32.DLL,AW,9 Returns the list of table names stored in a specific data source. SQLTransact,ODBC32.DLL,NM,3 Obsolete StackWalk,IMAGEHLP.DLL,NM,9,The StackWalk64 function provides a portable method for obtaining a stack trace. StartCAP,CAP.DLL,NM,0,Clear profiling data and start profiling. StartDoc,GDI32.DLL,AW,2, starts a print job. StartDocPrinter,WINMM.DLL,AW,3, informs the print spooler that a document is to be spooled for printing. StartPage,GDI32.DLL,NM,1, prepares the printer driver to accept data. StartPagePrinter,WINMM.DLL,NM,1, informs the spooler that a page is about to be printed on the specified printer. StartService,ADVAPI32.DLL,AW,3, starts a service. StartServiceCtrlDispatcher,ADVAPI32.DLL,AW,1 StgCreateDocfile,OLE32.DLL,NM,4, creates a new compound file storage object using the COM-provided compound file implementation for the IStorage interface. StgCreateDocfileOnILockBytes,OLE32.DLL,NM,4,Creates and opens a new compound file storage object on top of a byte-array object provided by the caller. StgCreatePropSetStg,IPROP.DLL,NM,3,Creates a property set storage object from a specified storage object. StgCreatePropStg,IPROP.DLL,NM,6,Creates and opens a property set in a specified storage or stream object. StgGetIFillLockBytesOnFile,OLE32.DLL,NM,2,Opens a wrapper object on a temporary file. StgGetIFillLockBytesOnILockBytes,OLE32.DLL,NM,2,Creates a new wrapper object on a byte array object provided by the caller. StgIsStorageFile,OLE32.DLL,NM,1, indicates whether a particular disk file contains a storage object. StgIsStorageILockBytes,OLE32.DLL,NM,1, indicates whether the specified byte array contains a storage object. StgOpenAsyncDocfileOnIFillLockBytes,OLE32.DLL,NM,4,Opens an existing root asynchronous storage object on a byte-array wrapper object provided by the caller. StgOpenLayoutDocfile,DFLAYOUT.DLL,NM,4,Opens a compound file on an ILockBytes implementation that is capable of monitoring sector data. StgOpenPropStg,IPROP.DLL,NM,5,Opens a specified property set in a specified storage or stream object. StgOpenStorage,OLE32.DLL,NM,6, opens an existing root storage object in the file system. StgOpenStorageOnILockBytes,OLE32.DLL,NM,6, opens an existing storage object that does not reside in a disk file, but instead has an underlying byte array provided by the caller. StgSetTimes,OLE32.DLL,NM,4, sets the creation, access, and modification times of the indicated file, if supported by the underlying file system. StopCAP,CAP.DLL,NM,0,Stop profiling. StretchBlt,GDI32.DLL,NM,11 copies a bitmap from a source rectangle into a destination rectangle, stretching or compressing the bitmap to fit the dimensions of the destination rectangle, if necessary. StretchDIBits,GDI32.DLL,NM,13 copies the color data for a rectangle of pixels in a deviceindependent bitmap (DIB) to the specified destination rectangle. StringFromCLSID,OLE32.DLL,NM,2,Converts a CLSID into a string of printable characters. Different CLSIDs always convert to different strings. StringFromGUID2,OLE32.DLL,NM,3,Converts a globally unique identifier (GUID) into a string of printable characters. StringFromIID,OLE32.DLL,NM,2, Interface identifier to be converted. StrokeAndFillPath,GDI32.DLL,NM,1 closes any open figures in a path,strokes the outline of the path by using the current pen, and fillsits interior by using the current brush. StrokePath,GDI32.DLL,NM,1 renders the specified path by using the current pen. SubmitNtmsOperatorRequest,NTMSAPI.DLL,AW,6, submits an RSM operator request. SubtractRect,USER32.DLL,NM,3, obtains the coordinates of a rectangle determined by subtracting one rectangle from another. SuspendThread,KERNEL32.DLL,NM,1, suspends the specified thread. SwapBuffers,GDI32.DLL,NM,1 exchanges the front and back buffers ifthe current pixel format for the window referenced by the specifieddevice context includes a back buffer. SwapNtmsMedia,NTMSAPI.DLL,NM,3, swaps the sides associated with the two specified LMIDs. The specified LMIDs must be in the same media pool. SwitchDesktop,USER32.DLL,NM,1, makes a desktop visible and activates it. SwitchToFiber,KERNEL32.DLL,NM,1, schedules a fiber. SwitchToThread,KERNEL32.DLL,NM,0 causes the calling thread to yieldexecution to another thread that is ready to run on the currentprocessor. SymCleanup,IMAGEHLP.DLL,NM,1, deallocates all resources associated with the process handle. SymEnumerateModules,IMAGEHLP.DLL,NM,3,The SymEnumerateModules64 function enumerates all modules that have been loaded for the process by the SymLoadModule64 or SymLoadModuleEx function. SymEnumerateSymbols,IMAGEHLP.DLL,NM,4,The SymEnumerateSymbols64 function enumerates all the symbols for a specified module. SymFunctionTableAccess,IMAGEHLP.DLL,NM,2,The SymFunctionTableAccess64 function retrieves the function table entry for the specified address. SymGetModuleBase,IMAGEHLP.DLL,NM,2,The SymGetModuleBase64 function retrieves the base address of the module that contains the specified address. SymGetModuleInfo,IMAGEHLP.DLL,NM,3,The SymGetModuleInfo64 function retrieves the module information of the specified module. SymGetOptions,IMAGEHLP.DLL,NM,0, retrieves the current options mask. SymGetSearchPath,IMAGEHLP.DLL,NM,3, retrieves the symbol search path for the specified process. SymGetSymFromAddr,IMAGEHLP.DLL,NM,4,The SymGetSymFromAddr64 function locates the symbol for the specified address. SymGetSymFromName,IMAGEHLP.DLL,NM,3,The SymGetSymFromName64 function locates a symbol for the specified name. SymGetSymNext,IMAGEHLP.DLL,NM,2,The SymGetSymNext64 function retrieves the symbol information of the next symbol. SymGetSymPrev,IMAGEHLP.DLL,NM,2,The SymGetSymPrev64 function retrieves the symbol information of the previous symbol. SymInitialize,IMAGEHLP.DLL,NM,3, initializes the symbol handler for a process. SymLoadModule,IMAGEHLP.DLL,NM,6,The SymLoadModule64 function loads the symbol table. SymRegisterCallback,IMAGEHLP.DLL,NM,4,The SymRegisterCallback64 function lets an application register a callback function for use by the symbol handler. SymSetOptions,IMAGEHLP.DLL,NM,1, sets the options mask. SymSetSearchPath,IMAGEHLP.DLL,NM,2, sets the search path for the specified process. SysAllocString,OLEAUT32.DLL,NM,1,LenAllocates a new string, copies cch characters from the passed string into it, and then appends a null character. SysAllocStringByteLen,OLEAUT32.DLL,NM,2,Takes an ANSI string as input, and returns a BSTR that contains an ANSI string. Does not perform any ANSI-to-Unicode translation. SysAllocStringLen,OLEAUT32.DLL,NM,2,Allocates a new string, copies cch characters from the passed string into it, and then appends a null character. SysFreeString,OLEAUT32.DLL,NM,1,Deallocates a string allocated previously by SysAllocString, SysAllocStringByteLen, SysReAllocString, SysAllocStringLen, or SysReAllocString,OLEAUT32.DLL,NM,2,Len This function creates a new BSTR that contains a specified number of characters from an old BSTR, and frees the old BSTR. SysReAllocStringLen,OLEAUT32.DLL,NM,3, This function creates a new BSTR that contains a specified number of characters from an old BSTR, and frees the old BSTR. SysStringByteLen,OLEAUT32.DLL,NM,1,Returns the length (in bytes) of a BSTR. Valid for 32bit systems only. SysStringLen,OLEAUT32.DLL,NM,1,Returns the length of a BSTR. SystemParametersInfo,USER32.DLL,AW,4, queries or sets systemwide parameters. SystemTimeToFileTime,KERNEL32.DLL,NM,2, converts a system time to a file time. SystemTimeToTzSpecificLocalTime,KERNEL32.DLL,NM,3 converts a Coordinated Universal Time (UTC) to a specified time zone?s corresponding local time. SystemTimeToVariantTime,OLEAUT32.DLL,NM,2,Converts a system time to a variant representation. SzFindCh,MAPI32.DLL,NM,2, searches for an exact match only; it is sensitive to case and diacritical differences. SzFindLastCh,MAPI32.DLL,NM,2, searches for an exact match only; it is sensitive to case and diacritical differences. SzFindSz,MAPI32.DLL,NM,2, searches for an exact match only; it is sensitive to case and diacritical differences. TabbedTextOut,USER32.DLL,AW,8 writes a character string at a specifiedlocation, expanding tabs to the values specified in an array oftab-stop positions. tapiGetLocationInfo,TAPI32.DLL,AW,2 returns the country code and city(area) code that the user has set in the current locationparameters in the Telephony Control Panel. tapiRequestDrop,TAPI32.DLL,NM,2 is nonfunctional in Win32 -basedapplications and obsolete for all classes of Windows-basedapplications. tapiRequestMakeCall,TAPI32.DLL,AW,4, requests the establishment of a voice call. tapiRequestMediaCall,TAPI32.DLL,AW,10 is nonfunctional in Win32-basedapplications and obsolete for all classes of Windows-basedapplications. TerminateProcess,KERNEL32.DLL,NM,2, terminates the specified process and all of its threads. TerminateThread,KERNEL32.DLL,NM,2, terminates a thread. TextOut,GDI32.DLL,AW,5 writes a character string at the specified location, using the currently selected font. Thread32First,TOOLHELP.DLL,NM,2, retrieves information about the first thread of any process encountered in a system snapshot. Thread32Next,TOOLHELP.DLL,NM,2, retrieves information about the next thread of any process encountered in the system memory snapshot. TileWindows,USER32.DLL,NM,5, tiles the specified windows, or the child windows of the specified parent window. timeBeginPeriod,WINMM.DLL,NM,1, sets the minimum timer resolution for an application or device driver. timeEndPeriod,WINMM.DLL,NM,1, clears a previously set minimum timer resolution. timeGetDevCaps,WINMM.DLL,NM,2, queries the timer device to determine its resolution. timeGetSystemTime,WINMM.DLL,NM,2, retrieves the system time, in milliseconds. timeGetTime,WINMM.DLL,NM,0, retrieves the system time, in milliseconds. timeKillEvent,WINMM.DLL,NM,1, cancels a specified timer event. timeSetEvent,WINMM.DLL,NM,5, starts a specified timer event. TlsAlloc,KERNEL32.DLL,NM,0, allocates a thread local storage (TLS) index. TlsFree,KERNEL32.DLL,NM,1, releases a thread local storage (TLS) index, making it available for reuse. TlsGetValue,KERNEL32.DLL,NM,1, retrieves the value in the calling thread? s thread local storage (TLS) slot for a specified TLS index. TlsSetValue,KERNEL32.DLL,NM,2, stores a value in the calling thread?s thread local storage (TLS) slot for a specified TLS index. ToAscii,USER32.DLL,NM,5 translates the specified virtual-key code and keyboard state to the corresponding Windows character or characters. ToAsciiEx,USER32.DLL,NM,6 translates the specified virtual-key codeand keyboard state to the corresponding Windows character orcharacters. Toolhelp32ReadProcessMemory,TOOLHELP.DLL,NM,5, copies memory allocated to another process into an application-supplied buffer. ToUnicode,USER32.DLL,NM,6 translates the specified virtual-key codeand keyboard state to the corresponding Unicode character orcharacters. ToUnicodeEx,USER32.DLL,NM,7 translates the specified virtual-key codeand keyboard state to the corresponding Unicode character orcharacters. TrackMouseEvent,COMCTL32.DLL,NM,1 posts messages when the mouse pointer leaves a window or hovers over a window for a specified amount of time. TrackMouseEvent,USER32.DLL,NM,1 posts messages when the mouse pointer leaves a window or hovers over a window for a specified amount of time. TrackPopupMenu,USER32.DLL,NM,7, displays a shortcut menu at the specified location and tracks the selection of items on the menu. TrackPopupMenuEx,USER32.DLL,NM,6 displays a shortcut menu at the specified location and tracks the selection of items on the menu. TransactNamedPipe,KERNEL32.DLL,NM,7 combines into a single networkoperation the functions that write a message to and read a messagefrom the specified named pipe. TranslateAccelerator,USER32.DLL,AW,3 function processes accelerator keys for menu commands. TranslateBitmapBits,MSCMS.DLL,NM,11, translates the colors of a bitmap having a defined format so as to produce another bitmap in a requested format. TranslateColors,MSCMS.DLL,NM,6, translates an array of colors from the source color space to the destination color space as defined by a color TranslateMDISysAccel,USER32.DLL,NM,2 processes accelerator keystrokes for window menu commands of the multiple document interface (MDI) child windows associated with the specified MDI client window. TranslateMessage,USER32.DLL,NM,1, translates virtual-key messages into character messages. TranslateName,SECUR32.DLL,AW,5, converts a directory service object name from one format to another. TranslateURL,URL.DLL,AW,3,Applies common translations to a given URL string, creating a new URL string. TransmitCommChar,KERNEL32.DLL,NM,2 transmits a specified character aheadof any pending data in the output buffer of the specifiedcommunications device. TryEnterCriticalSection,KERNEL32.DLL,NM,1 attempts to enter a critical section without blocking. UFromSz,MAPI32.DLL,NM,1, stops converting when it reaches the first character in the string that is not a decimal digit. UlAddRef,MAPI32.DLL,NM,1, provides an alternative way to invoke the OLE method IUnknown::AddRef. UlFromSzHex,MAPI32.DLL,NM,1, converts a null-terminated string of hexadecimal digits into an unsigned long integer. UlPropSize,MAPI32.DLL,NM,1, obtains the size of a single property value. UlRelease,MAPI32.DLL,NM,1, provides an alternative way to invoke the OLE method IUnknown::Release. UnDecorateSymbolName,IMAGEHLP.DLL,NM,4, undecorates decorated C++ symbol names. 152 VarBstrFromR8,OLEAUT32.DLL,NM,5,Converts a variant of type double to BSTR. UnhandledExceptionFilter,KERNEL32.DLL,NM,1, passes unhandled exceptions to the VarBstrFromUI1,OLEAUT32.DLL,NM,4,Converts a variant of type unsigned char to BSTR. debugger, if the process is being debugged. UnhookWindowsHook,USER32.DLL,NM,2, is obsolete, but is provided for compatibility with 16- VarBstrFromUI2,OLEAUT32.DLL,NM,4,Converts a variant of type unsigned short to BSTR. VarBstrFromUI4,OLEAUT32.DLL,NM,4,Converts a variant of type unsigned long to BSTR. bit versions of Windows. VarCyFromBool,OLEAUT32.DLL,NM,2,Converts a variant of type bool to curency. UnhookWindowsHookEx,USER32.DLL,NM,1, removes a hook procedure installed in a hook VarCyFromDate,OLEAUT32.DLL,NM,3,Converts a variant of type date to curency. chain by the SetWindowsHookEx function. VarCyFromDec,OLEAUT32.DLL,NM,2,Converts a variant of type decimal to curency. UninitializeFlatSB,COMCTL32.DLL,NM,1,Uninitializes flat scroll bars for a particular window. UninstallColorProfile,MSCMS.DLL,AW,3,UninstallColorProfile removes a specified color profile VarCyFromDisp,OLEAUT32.DLL,NM,3,This function converts variant data types to CURRENCY from IDispatch. from a specified computer. Associated files are optionally deleted from the system. VarCyFromI1,OLEAUT32.DLL,NM,2,Converts a variant of type char to currency. UnionRect,USER32.DLL,NM,3, creates the union of two rectangles. VarCyFromI2,OLEAUT32.DLL,NM,2,Converts a variant of type short to curency. UnloadKeyboardLayout,USER32.DLL,NM,1, removes a keyboard layout. VarCyFromI4,OLEAUT32.DLL,NM,2,Converts a variant of type long to curency. UnloadPerfCounterTextStrings,LOADPERF.DLL,AW,2,unloads performance objects and VarCyFromR4,OLEAUT32.DLL,NM,2,Converts a variant of type float to curency. counters from the system that are identified by the specified application name. VarCyFromR8,OLEAUT32.DLL,NM,3,Converts a variant of type double to curency. UnloadUserProfile,USERENV.DLL,NM,2, unloads a user's profile that was loaded by the LoadUserProfile function. The caller must have administrative privileges on the computer. For VarCyFromStr,OLEAUT32.DLL,NM,4,This function converts variant data types to from OLECHAR. more information, see the Remarks section of the LoadUserProfile function. VarCyFromUI1,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned char to curency. UnlockFile,KERNEL32.DLL,NM,5, unlocks a file region locked by LockFile. VarCyFromUI2,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned short to currency. UnlockFileEx,KERNEL32.DLL,NM,5, unlocks a previously locked byte range in an open file. UnlockServiceDatabase,ADVAPI32.DLL,NM,1, unlocks a service control manager database by VarCyFromUI4,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned long to currency. VarDateFromBool,OLEAUT32.DLL,NM,2,converts variant data types to DATE from BOOL. releasing the specified lock. UnlockUrlCacheEntryFile,WININET.DLL,AW,2,Unlocks the cache entry that was locked while VarDateFromCy,OLEAUT32.DLL,NM,3,converts variant data types to DATE from currency VarDateFromDec,OLEAUT32.DLL,NM,2, converts variant data types to DATE from decimal the file was retrieved for use from the cache. VarDateFromDisp,OLEAUT32.DLL,NM,3,Converts a variant of type IDispatch to date. UnlockUrlCacheEntryStream,WININET.DLL,NM,2,Closes the stream that has been retrieved VarDateFromI1,OLEAUT32.DLL,NM,2,Converts a variant of type char to date. using the RetrieveUrlCacheEntryStream function. UnMapAndLoad,IMAGEHLP.DLL,NM,1, is used to deallocate all resources that are allocated by VarDateFromI2,OLEAUT32.DLL,NM,2,converts variant data types to DATE from short VarDateFromI4,OLEAUT32.DLL,NM,2,This function converts variant data types to DATE from a previous call to the MapAndLoad function. long. UnmapDebugInformation,IMAGEHLP.DLL,NM,1, deallocates the memory and resources VarDateFromR4,OLEAUT32.DLL,NM,2,Converts a variant of type float to date. allocated by a call to the MapDebugInformation function. VarDateFromR8,OLEAUT32.DLL,NM,3,This function converts variant data types to DATE from UnmapViewOfFile,KERNEL32.DLL,NM,1, unmaps a mapped view of a file from the calling double. process?s address space. UnpackDDElParam,USER32.DLL,NM,4, unpacks a DDE lParam value received from a posted VarDateFromStr,OLEAUT32.DLL,NM,4,Converts a variant of type OLECHAR* to date. VarDateFromUdate,OLEAUT32.DLL,NM,3,Converts a time and date converted from MS-DOS DDE message. format to variant format. UnrealizeObject,GDI32.DLL,NM,1, resets a logical palette. UnregisterClass,USER32.DLL,AW,2, removes a window class, freeing the memory required for VarDateFromUI1,OLEAUT32.DLL,NM,2,converts variant data types to DATE from unsigned char. the class. VarDateFromUI2,OLEAUT32.DLL,NM,2,This function converts variant data types to DATE from UnregisterCMM,MSCMS.DLL,AW,2, dissociates a specified ID value from a given color unsigned short. management module dynamic-link library (CMM DLL). VarDateFromUI4,OLEAUT32.DLL,NM,2,This function converts variant data types to DATE from UnregisterGPNotification,USERENV.DLL,NM,1, unregisters the specified policy-notification unsigned long. handle from receiving policy change notifications. VarDecFromBool,OLEAUT32.DLL,NM,2,Converts a variant of type bool to decimal. UnregisterHotKey,USER32.DLL,NM,2, frees a hot key previously registered by the calling VarDecFromCy,OLEAUT32.DLL,NM,3,Converts a variant of type currency to decimal. thread. UnsealMessage,SECUR32.DLL,NM,4, is already documented under another name. For more VarDecFromDate,OLEAUT32.DLL,NM,3,Converts a variant of type date to decimal. VarDecFromDisp,OLEAUT32.DLL,NM,3,This function converts variant data types to DECIMAL information, see SpUnsealMessage. from IDispatch. UpdateColors,GDI32.DLL,NM,1 updates the client area of the specifieddevice context by VarDecFromI1,OLEAUT32.DLL,NM,2,Converts a variant of type char to decimal. remapping the current colors in the client areato the currently realized logical palette. UpdateDCOMSettings,OLE32.DLL,NM,0, This function updates the DCOM configuration after VarDecFromI2,OLEAUT32.DLL,NM,2,Converts a variant of type short to decimal. VarDecFromI4,OLEAUT32.DLL,NM,2,Converts a variant of type long to decimal. modifying the registry settings. void UpdateDCOMSettings(void); Parameters None. VarDecFromR4,OLEAUT32.DLL,NM,2,Converts a variant of type float to decimal. Return Values None. Remarks None. VarDecFromR8,OLEAUT32.DLL,NM,3,Converts a variant of type double to decimal. UpdateDebugInfoFile,IMAGEHLP.DLL,NM,4, uses the specified information to update the VarDecFromStr,OLEAUT32.DLL,NM,4,Converts a variant of type OLECHAR* to decimal. corresponding fields in the symbol file. VarDecFromUI1,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned char to decimal. UpdateDebugInfoFileEx,IMAGEHLP.DLL,NM,5, uses the specified information to update the VarDecFromUI2,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned short to decimal. corresponding fields in the symbol file. UpdateNtmsOmidInfo,NTMSAPI.DLL,NM,5, updates the RSM database with label information VarDecFromUI4,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned long to decimal. VarI1FromBool,OLEAUT32.DLL,NM,2,Converts a variant of type BOOL to char. immediately after writing to the newly allocated medium. UpdateResource,KERNEL32.DLL,AW,6, adds, deletes, or replaces a resource in an executable VarI1FromCy,OLEAUT32.DLL,NM,3,Converts a variant of type currency to char. VarI1FromDate,OLEAUT32.DLL,NM,3,Converts a variant of type date to char. file. UpdateWindow,USER32.DLL,NM,1 updates the client area of the specified window by sending VarI1FromDec,OLEAUT32.DLL,NM,2,Converts a variant of type decimal to char. VarI1FromDisp,OLEAUT32.DLL,NM,3,This function converts variant data types to char from a WM_PAINT message to the window if the window?s update region is not empty. URLAssociationDialog,URL.DLL,AW,6,Invokes the unregistered URL protocol dialog box. This IDispatch. VarI1FromI2,OLEAUT32.DLL,NM,2,Converts a variant of type short to char. dialog box allows the user to select an application to associate with a previously unknown VarI1FromI4,OLEAUT32.DLL,NM,2,Converts a variant of type long to char. protocol URLDownload,URLMON.DLL,AW,5,ToFile Downloads bits from the Internet and saves them to VarI1FromR4,OLEAUT32.DLL,NM,2,Converts a variant of type float to char. VarI1FromR8,OLEAUT32.DLL,NM,3,Converts a variant of type double to char. a file. URLDownloadToCacheFile,URLMON.DLL,AW,6, Downloads data into the Internet cache and VarI1FromStr,OLEAUT32.DLL,NM,4,Converts a variant of type OLECHAR* to char. VarI1FromUI1,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned char to char. returns the file name of the cache location for retrieving the bits. URLDownloadToFile,URLMON.DLL,AW,5, Downloads bits from the Internet and saves them to VarI1FromUI2,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned short to char. VarI1FromUI4,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned long to char. a file. VarI2FromBool,OLEAUT32.DLL,NM,2,Converts a variant of type bool to short. UrlMkSetSessionOption,URLMON.DLL,NM,4, Sets options for the current Internet session. URLOpenBlockingStream,URLMON.DLL,AW,5, Creates a blocking type stream object from a VarI2FromCy,OLEAUT32.DLL,NM,3,Converts a variant of type currency to short. VarI2FromDate,OLEAUT32.DLL,NM,3,Converts a variant of type date to short. URL and downloads the data from the Internet. When the data is downloaded, the client VarI2FromDec,OLEAUT32.DLL,NM,2,Converts a variant of type decimal to short. application or control can read it using the IStream::Read method. VarI2FromDisp,OLEAUT32.DLL,NM,3,This function converts variant data types to short from URLOpenPullStream,URLMON.DLL,AW,4, Creates a pull type stream object from a URL. IDispatch. URLOpenStream,URLMON.DLL,AW,4, Creates a push type stream object from a URL. VarI2FromI1,OLEAUT32.DLL,NM,2,Converts a variant of type char to short. UuidCompare,RPCRT4.DLL,NM,3, compares two UUIDs. VarI2FromI4,OLEAUT32.DLL,NM,2,Converts a variant of type long to short. UuidCreate,RPCRT4.DLL,NM,1, creates a new UUID. VarI2FromR4,OLEAUT32.DLL,NM,2,Converts a variant of type float to short. UuidCreateNil,RPCRT4.DLL,NM,1, creates a nil-valued UUID. VarI2FromR8,OLEAUT32.DLL,NM,3,Converts a variant of type double to short. UuidEqual,RPCRT4.DLL,NM,3, determines if two UUIDs are equal. VarI2FromStr,OLEAUT32.DLL,NM,4,Converts a variant of type string to short. UuidFromString,RPCRT4.DLL,AW,2, converts a string to a UUID. VarI2FromUI1,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned char to short. UuidHash,RPCRT4.DLL,NM,2 creates a hash value for a UUID. VarI2FromUI2,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned short to short. UuidIsNil,RPCRT4.DLL,NM,2 determines if a UUID is a nil-valued UUID. VarI2FromUI4,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned long to short. UuidToString,RPCRT4.DLL,AW,2, converts a UUID to a string. VarI4FromBool,OLEAUT32.DLL,NM,2,Converts a variant of type bool to long. ValidateRect,USER32.DLL,NM,2 validates the client area within a rectangle by removing the VarI4FromCy,OLEAUT32.DLL,NM,3,Converts a variant of type currency to long. rectangle from the update region of the specified window. ValidateRgn,USER32.DLL,NM,2 validates the client area within a region by removing the region VarI4FromDate,OLEAUT32.DLL,NM,3,Converts a variant of type date to long. VarI4FromDec,OLEAUT32.DLL,NM,2,Converts a variant of type decimal to long. from the current update region of the specified window. VarI4FromDisp,OLEAUT32.DLL,NM,3,This function converts variant data types to long from VarBoolFromCy,OLEAUT32.DLL,NM,3,Converts a variant of type currency to bool. IDispatch. VarBoolFromDate,OLEAUT32.DLL,NM,3,Converts a variant of type date to bool. VarI4FromI1,OLEAUT32.DLL,NM,2,Converts a variant of type char to long. VarBoolFromDec,OLEAUT32.DLL,NM,2,Converts a variant of type decimal to bool. VarI4FromI2,OLEAUT32.DLL,NM,2,Converts a variant of type short to long. VarBoolFromDisp,OLEAUT32.DLL,NM,3,This function converts variant data types to BOOL VarI4FromR4,OLEAUT32.DLL,NM,2,Converts a variant of type float to long. from IDispatch. VarI4FromR8,OLEAUT32.DLL,NM,3,Converts a variant of type double to long. VarBoolFromI1,OLEAUT32.DLL,NM,2,Converts a variant of type char to bool. VarI4FromStr,OLEAUT32.DLL,NM,4, Converts a variant of type string to long. VarBoolFromI2,OLEAUT32.DLL,NM,2,Converts a variant of type short to bool. VarI4FromUI1,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned char to long. VarBoolFromI4,OLEAUT32.DLL,NM,2,Converts a variant of type long to bool. VarI4FromUI2,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned short to long. VarBoolFromR4,OLEAUT32.DLL,NM,2,Converts a variant of type float to bool. VarI4FromUI4,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned long to long. VarBoolFromR8,OLEAUT32.DLL,NM,3,Converts a variant of type double to bool. VariantChangeType,OLEAUT32.DLL,NM,4, This function converts a variant from one type to VarBoolFromStr,OLEAUT32.DLL,NM,4,Converts a variant of type string to bool. another VarBoolFromUI1,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned char to bool. VariantChangeTypeEx,OLEAUT32.DLL,NM,5,This function converts a variant from one type to VarBoolFromUI2,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned short to bool. another VarBoolFromUI4,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned long to bool. VariantClear,OLEAUT32.DLL,NM,1,Clears a variant. VarBstrFromBool,OLEAUT32.DLL,NM,4,Converts a variant of type bool to BSTR. VariantCopy,OLEAUT32.DLL,NM,2, Frees the destination variant and makes a copy of the VarBstrFromCy,OLEAUT32.DLL,NM,5,Converts a variant of type currency to BSTR. source variant. VarBstrFromDate,OLEAUT32.DLL,NM,5,Converts a variant of type date to BSTR. VariantCopyInd,OLEAUT32.DLL,NM,2,Frees the destination variant and makes a copy of the VarBstrFromDec,OLEAUT32.DLL,NM,4, Converts a variant of type decimal to BSTR. source VARIANTARG, performing the necessary indirection if the source is specified to be VarBstrFromDisp,OLEAUT32.DLL,NM,4,Converts a variant of type IDispatch to BSTR. VT_BYREF. VarBstrFromI1,OLEAUT32.DLL,NM,4,Converts a variant of type char to BSTR. VarBstrFromI2,OLEAUT32.DLL,NM,4,This function converts variant data types to BSTR from VariantInit,OLEAUT32.DLL,NM,1,Initializes a variant. VariantTimeToDosDateTime,OLEAUT32.DLL,NM,4,Converts the variant representation of a short. date and time to MS-DOS date and time values. VarBstrFromI4,OLEAUT32.DLL,NM,4,Converts a variant of type long to BSTR. VarBstrFromR4,OLEAUT32.DLL,NM,4,Converts a variant of type float to BSTR. 153 VariantTimeToSystemTime,OLEAUT32.DLL,NM,3,Converts the variant representation of time VirtualProtect,KERNEL32.DLL,NM,4 changes the access protection on aregion of committed pages in the virtual address space of thecalling process. to system time values. VarNumFromParseNum,OLEAUT32.DLL,NM,4,Once the number is parsed, the caller can call VirtualProtectEx,KERNEL32.DLL,NM,5 changes the access protection on a region of committed pages in the virtual address space of a specified process. VarNumFromParseNum to convert the parse results to a number. VarParseNumFromStr,OLEAUT32.DLL,NM,5,Parses a string, and creates a type-independent VirtualQuery,KERNEL32.DLL,NM,3, provides information about a range of pages in the virtual address space of the calling process. description of the number it represents. VirtualQueryEx,KERNEL32.DLL,NM,4, provides information about a range of pages within the VarR4FromBool,OLEAUT32.DLL,NM,2,Converts a variant of type bool to float. virtual address space of a specified process. VarR4FromCy,OLEAUT32.DLL,NM,3,Converts a variant of type currency to float. VirtualUnlock,KERNEL32.DLL,NM,2 unlocks a specified range of pages inthe virtual address VarR4FromDate,OLEAUT32.DLL,NM,3,Converts a variant of type date to float. space of a process, enabling the system to swapthe pages out to the paging file if necessary. VarR4FromDec,OLEAUT32.DLL,NM,2,Converts a variant of type decimal to float. VarR4FromDisp,OLEAUT32.DLL,NM,3, This function converts variant data types to float from VkKeyScan,USER32.DLL,AW,1 translates a character to the corresponding virtual-key code and shift state for the current keyboard. IDispatch. VkKeyScanEx,USER32.DLL,AW,2, translates a character to the corresponding virtual-key code VarR4FromI1,OLEAUT32.DLL,NM,2,Converts a variant of type char to float. and shift state. VarR4FromI2,OLEAUT32.DLL,NM,2,Converts a variant of type short to float. WaitCommEvent,KERNEL32.DLL,NM,3, waits for an event to occur for a specified VarR4FromI4,OLEAUT32.DLL,NM,2,Converts a variant of type long to float. communications device. VarR4FromR8,OLEAUT32.DLL,NM,3,Converts a variant of type double to float. WaitForDebugEvent,KERNEL32.DLL,NM,2, waits for a debugging event to occur in a process VarR4FromStr,OLEAUT32.DLL,NM,4,This function converts variant data types to float from being debugged. OLECHAR. WaitForInputIdle,USER32.DLL,NM,2 waits until the given process is waiting for user input with VarR4FromUI1,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned char to float. no input pending, or until the time-out interval has elapsed. VarR4FromUI2,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned short to float. WaitForMultipleObjects,KERNEL32.DLL,NM,4 function returns when any one or all of the VarR4FromUI4,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned long to float. specified objects are in the signaled state or the time-out interval elapses. VarR8FromBool,OLEAUT32.DLL,NM,2,Converts a variant of type bool to double. WaitForMultipleObjectsEx,KERNEL32.DLL,NM,5 function returns when any one or all of the VarR8FromCy,OLEAUT32.DLL,NM,3,Converts a variant of type currency to double. specified objects are in the signaled state or the time-out interval elapses or an I/O completion VarR8FromDate,OLEAUT32.DLL,NM,3,Converts a variant of type date to double. routine or asynchronous procedure call (APC) is queued to the thread. VarR8FromDec,OLEAUT32.DLL,NM,2,Converts a variant of type decimal to double. WaitForNtmsNotification,NTMSAPI.DLL,NM,3, waits for the next object change notification. VarR8FromDisp,OLEAUT32.DLL,NM,3,Converts a variant of type IDispatch to double. WaitForNtmsOperatorRequest,NTMSAPI.DLL,NM,3, waits for the specified RSM operator VarR8FromI1,OLEAUT32.DLL,NM,2,Converts a variant of type char to double. request. VarR8FromI2,OLEAUT32.DLL,NM,2,Converts a variant of type short to double. WaitForSingleObject,KERNEL32.DLL,NM,2 returns when the specified object is in the signaled VarR8FromI4,OLEAUT32.DLL,NM,2,Converts a variant of type long to double. state or the time-out interval elapses. VarR8FromR4,OLEAUT32.DLL,NM,2,Converts a variant of type float to double. WaitForSingleObjectEx,KERNEL32.DLL,NM,3, returns when The specified object is in the VarR8FromStr,OLEAUT32.DLL,NM,4,Converts a variant of type OLECHAR* to double. signaled state. or The time-out interval elapses. VarR8FromUI1,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned char to double. WaitMessage,USER32.DLL,NM,0, yields control to other threads when a thread has no other VarR8FromUI2,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned short to double. messages in its message queue. VarR8FromUI4,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned long to double. WaitNamedPipe,KERNEL32.DLL,AW,2 waits until either a time-out interval elapses or an VarUdateFromDate,OLEAUT32.DLL,NM,4,Converts a time and date converted from variant instance of the specified named pipe is available to be connected to format to MS-DOS format. VarUI1FromBool,OLEAUT32.DLL,NM,2,Converts a variant of type BOOL to an unsigned char waveInAddBuffer,WINMM.DLL,NM,3, sends an input buffer to the given waveform-audio input device. type. VarUI1FromCy,OLEAUT32.DLL,NM,3,Converts a variant of type currency to an unsigned char waveInClose,WINMM.DLL,NM,1, closes the given waveform-audio input device. waveInGetDevCaps,WINMM.DLL,AW,3, retrieves the capabilities of a given waveform-audio type. input device. VarUI1FromDate,OLEAUT32.DLL,NM,3,Converts a variant of type date to an unsigned char waveInGetErrorText,WINMM.DLL,AW,3, retrieves a textual description of the error identified by type. VarUI1FromDec,OLEAUT32.DLL,NM,2,Converts a variant of type decimal to an unsigned char the given error number. waveInGetID,WINMM.DLL,NM,2, gets the device identifier for the given waveform-audio input type. device. VarUI1FromDisp,OLEAUT32.DLL,NM,3, converts variant data types to BYTE from waveInGetNumDevs,WINMM.DLL,NM,0 returns the number of waveform-audio input devices VarUI1FromI1,OLEAUT32.DLL,NM,2,Converts a variant of type char to unsigned char. VarUI1FromI2,OLEAUT32.DLL,NM,2,Converts a variant of type short to an unsigned char type. present in the system. VarUI1FromI4,OLEAUT32.DLL,NM,2,Converts a variant of type long to an unsigned char type. waveInGetPosition,WINMM.DLL,NM,3, retrieves the current input position of the given VarUI1FromR4,OLEAUT32.DLL,NM,2,Converts a variant of type float to an unsigned char type. waveform-audio input device. waveInMessage,WINMM.DLL,NM,4 sends messages to the waveform-audio, Waveform VarUI1FromR8,OLEAUT32.DLL,NM,3,Converts a variant of type double to an unsigned char Functionsinput device drivers. type. waveInOpen,WINMM.DLL,NM,6 opens the given waveformfor recording. VarUI1FromStr,OLEAUT32.DLL,NM,4, converts variant data types to BYTE from BSTR. waveInPrepareHeader,WINMM.DLL,NM,3, prepares a buffer for waveform- audio input. VarUI1FromUI2,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned short to unsigned waveInReset,WINMM.DLL,NM,1 stops input on the given waveform-audio input device and char. resets the current position to zero. VarUI1FromUI4,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned long to unsigned waveInStart,WINMM.DLL,NM,1, starts input on the given waveform-audio input device. char. waveInStop,WINMM.DLL,NM,1, stops waveform-audio input. VarUI2FromBool,OLEAUT32.DLL,NM,2,Converts a variant of type bool to unsigned short. waveInUnprepareHeader,WINMM.DLL,NM,3, cleans up the preparation performed by the VarUI2FromCy,OLEAUT32.DLL,NM,3,Converts a variant of type currency to unsigned short. waveInPrepareHeader function. VarUI2FromDate,OLEAUT32.DLL,NM,3,Converts a variant of type date to unsigned short. waveOutBreakLoop,WINMM.DLL,NM,1 breaks a loop on the given waveform-audio output VarUI2FromDec,OLEAUT32.DLL,NM,2,Converts a variant of type decimal to unsigned short. VarUI2FromDisp,OLEAUT32.DLL,NM,3,Converts a variant of type IDispatch* to unsigned short. device and allows playback to continue with the nextblock in the driver list. waveOutClose,WINMM.DLL,NM,1 closes the given waveform-audio output device. VarUI2FromI1,OLEAUT32.DLL,NM,2,Converts a variant of type char to unsigned short. waveOutGetDevCaps,WINMM.DLL,AW,3, retrieves the capabilities of a given waveform-audio VarUI2FromI2,OLEAUT32.DLL,NM,2,Converts a variant of type short to unsigned short. output device. VarUI2FromI4,OLEAUT32.DLL,NM,2,Converts a variant of type long to unsigned short. waveOutGetErrorText,WINMM.DLL,AW,3, retrieves a textual description of the error identified VarUI2FromR4,OLEAUT32.DLL,NM,2,Converts a variant of type float to unsigned short. by the given error number. VarUI2FromR8,OLEAUT32.DLL,NM,3,Converts a variant of type double to unsigned short. waveOutGetID,WINMM.DLL,NM,2, retrieves the device identifier for the given waveform-audio VarUI2FromStr,OLEAUT32.DLL,NM,4,Converts a variant of type string to unsigned short. output device. VarUI2FromUI1,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned char to unsigned waveOutGetNumDevs,WINMM.DLL,NM,0, retrieves the number of waveform- audio output short. devices present in the system. VarUI2FromUI4,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned long to unsigned waveOutGetPitch,WINMM.DLL,NM,2 retrieves the current pitch setting for the specified short. waveform-audio output device. VarUI4FromBool,OLEAUT32.DLL,NM,2,Converts a variant of type bool to unsigned long. waveOutGetPlaybackRate,WINMM.DLL,NM,2, retrieves the current playback rate for the VarUI4FromCy,OLEAUT32.DLL,NM,3,Converts a variant of type currency to unsigned long. specified waveform-audio output device. VarUI4FromDate,OLEAUT32.DLL,NM,3,Converts a variant of type date to unsigned long. waveOutGetPosition,WINMM.DLL,NM,3 retrieves the current playback,position of the given VarUI4FromDec,OLEAUT32.DLL,NM,2,Converts a variant of type decimal to unsigned long. VarUI4FromDisp,OLEAUT32.DLL,NM,3,Converts a variant of type IDispatch* to unsigned long. waveform-audio output device. waveOutGetVolume,WINMM.DLL,NM,2, retrieves the current volume level of the specified VarUI4FromI1,OLEAUT32.DLL,NM,2,Converts a variant of type char to unsigned long. waveform-audio output device. VarUI4FromI2,OLEAUT32.DLL,NM,2,Converts a variant of type short to unsigned long. waveOutMessage,WINMM.DLL,NM,4, sends messages to the waveform-audio output device VarUI4FromI4,OLEAUT32.DLL,NM,2,Converts a variant of type long to unsigned long. drivers. VarUI4FromR4,OLEAUT32.DLL,NM,2,Converts a variant of type float to unsigned long. waveOutOpen,WINMM.DLL,NM,6, opens the given waveform-audio output device for playback. VarUI4FromR8,OLEAUT32.DLL,NM,3,Converts a variant of type double to unsigned long. waveOutPause,WINMM.DLL,NM,1, pauses playback on the given waveform- audio output VarUI4FromStr,OLEAUT32.DLL,NM,4,This function converts variant data types to unsigned device. long from string. waveOutPrepareHeader,WINMM.DLL,NM,3 prepares a waveform-audio data block for VarUI4FromUI1,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned char to unsigned playback. long. waveOutReset,WINMM.DLL,NM,1, stops playback on the given waveform- audio output device VarUI4FromUI2,OLEAUT32.DLL,NM,2,Converts a variant of type unsigned short to unsigned and resets the current position to zero. long. VectorFromBstr,OLEAUT32.DLL,NM,2,Returns a vector, assigning each character in the BSTR waveOutRestart,WINMM.DLL,NM,1, resumes playback on a paused waveform- audio output device. to an element of the vector. VerFindFile,VERSION.DLL,AW,8, determines where to install a file based on whether it locates waveOutSetPitch,WINMM.DLL,NM,2, sets the pitch for the specified waveform-audio output device. another version of the file in the system. waveOutSetPlaybackRate,WINMM.DLL,NM,2, sets the playback rate for the specified VerifySignature,SECUR32.DLL,NM,4, Verifies the signature. waveform-audio output device. VerInstallFile,VERSION.DLL,AW,8 function attempts to install the specified file based on waveOutSetVolume,WINMM.DLL,NM,2, sets the volume level of the specified waveform-audio information returned from the VerFindFile function. output device. VerLanguageName,KERNEL32.DLL,AW,3 retrieves a description string for the language waveOutUnprepareHeader,WINMM.DLL,NM,3, cleans up the preparation performed by the associated with a specified binary Microsoft language identifier. waveOutPrepareHeader function. VerQueryValue,VERSION.DLL,AW,4, returns selected version information from the specified waveOutWrite,WINMM.DLL,NM,3, sends a data block to the given waveform- audio output version-information resource. VirtualAlloc,KERNEL32.DLL,NM,4, reserves or commits a region of pages in the virtual address device. wglCopyContext,OPENGL.DLL,NM,3, copies selected groups of rendering states from one space of the calling process. VirtualAllocEx,KERNEL32.DLL,NM,5, reserves, commits, or both, a region of memory within the OpenGL rendering context to another. wglCopyContext,OPENGL32.DLL,NM,3, copies selected groups of rendering states from one virtual address space of a specified process. VirtualFree,KERNEL32.DLL,NM,3, releases or decommits (or both) a region of pages within the OpenGL rendering context to another. wglCreateContext,OPENGL.DLL,NM,1 creates a new OpenGL renderingcontext, which is virtual address space of the calling process. VirtualFreeEx,KERNEL32.DLL,NM,4, releases, decommits, or both, a region of memory within suitable for drawing on the device referenced byhdc. wglCreateContext,OPENGL32.DLL,NM,1 creates a new OpenGL renderingcontext, which is the virtual address space of a specified process. suitable for drawing on the device referenced byhdc. VirtualLock,KERNEL32.DLL,NM,2 locks the specified region of the process?s virtual address wglCreateLayerContext,OPENGL.DLL,NM,2, creates a new OpenGL rendering context for space into memory, ensuring that subsequentaccess to the region will not incur a page fault. drawing to a specified layer plane on a device context. 154 wglCreateLayerContext,OPENGL32.DLL,NM,2, creates a new OpenGL rendering context for drawing to a specified layer plane on a device context. wglDeleteContext,OPENGL.DLL,NM,1, deletes a specified OpenGL rendering context. wglDeleteContext,OPENGL32.DLL,NM,1, deletes a specified OpenGL rendering context. wglDescribeLayerPlane,OPENGL.DLL,NM,5, obtains information about the layer planes of a given pixel format. wglDescribeLayerPlane,OPENGL32.DLL,NM,5, obtains information about the layer planes of a given pixel format. wglGetCurrentContext,OPENGL.DLL,NM,0, obtains a handle to the current OpenGL rendering context of the calling thread. wglGetCurrentContext,OPENGL32.DLL,NM,0, obtains a handle to the current OpenGL rendering context of the calling thread. wglGetCurrentDC,OPENGL.DLL,NM,0 obtains a handle to the device contextthat is associated with the current OpenGL rendering context of thecalling thread. wglGetCurrentDC,OPENGL32.DLL,NM,0 obtains a handle to the device contextthat is associated with the current OpenGL rendering context of thecalling thread. wglGetLayerPaletteEntries,OPENGL.DLL,NM,5 retrieves the paletteentries from a given colorindex layer plane for a specified devicecontext. wglGetLayerPaletteEntries,OPENGL32.DLL,NM,5 retrieves the paletteentries from a given color-index layer plane for a specified devicecontext. wglGetProcAddress,OPENGL.DLL,NM,1 returns the address of an OpenGLextension function for use with the current OpenGL renderingcontext. wglGetProcAddress,OPENGL32.DLL,NM,1 returns the address of an OpenGLextension function for use with the current OpenGL renderingcontext. wglMakeCurrent,OPENGL.DLL,NM,2, makes a specified OpenGL rendering context the calling thread?s current rendering context. wglMakeCurrent,OPENGL32.DLL,NM,2, makes a specified OpenGL rendering context the calling thread?s current rendering context. wglRealizeLayerPalette,OPENGL.DLL,NM,3 maps palette entries from agiven color-index layer plane into the physical palette orinitializes the palette of an RGBA layer plane. wglRealizeLayerPalette,OPENGL32.DLL,NM,3 maps palette entries from agiven color-index layer plane into the physical palette orinitializes the palette of an RGBA layer plane. wglSetLayerPaletteEntries,OPENGL.DLL,NM,5, sets the palette entries in a given color-index layer plane for a specified device context. wglSetLayerPaletteEntries,OPENGL32.DLL,NM,5, sets the palette entries in a given colorindex layer plane for a specified device context. wglShareLists,OPENGL.DLL,NM,2, enables multiple OpenGL rendering contexts to share a single display-list space. wglShareLists,OPENGL32.DLL,NM,2, enables multiple OpenGL rendering contexts to share a single display-list space. wglSwapLayerBuffers,OPENGL.DLL,NM,2, swaps the front and back buffers in the overlay, underlay, and main planes of the window referenced by a specified device context. wglSwapLayerBuffers,OPENGL32.DLL,NM,2, swaps the front and back buffers in the overlay, underlay, and main planes of the window referenced by a specified device context. wglUseFontBitmaps,OPENGL.DLL,AW,4 wglUseFontBitmapscreates a set of bitmap displaylists for use in the current OpenGL rendering context. wglUseFontBitmaps,OPENGL32.DLL,AW,4 wglUseFontBitmapscreates a set of bitmap displaylists for use in the current OpenGL rendering context. wglUseFontOutlines,OPENGL.DLL,AW,8 creates three-dimensional (3-D) characters based on a TrueType font for use in OpenGL-rendered scenes. wglUseFontOutlines,OPENGL32.DLL,AW,8 creates three-dimensional (3-D) characters based on a TrueType font for use in OpenGL rendered scenes. WideCharToMultiByte,KERNEL32.DLL,NM,8 maps a wide character string to anew character string. WidenPath,GDI32.DLL,NM,1 redefines the current path as the area that would be painted if the path were stroked using the pen currently selected into the given device context. WindowFromDC,USER32.DLL,NM,1, returns the handle of the window associated with the given display device context (DC). WindowFromPoint,USER32.DLL,NM,2, retrieves the handle of the window that contains the specified point. WinExec,KERNEL32.DLL,NM,2, runs the specified application. WinHelp,USER32.DLL,AW,4, starts Windows Help (WINHELP. WinLoadTrustProvider,WINTRUST.DLL,NM,1, loads a trust provider DLL into the address space of the calling process. WinSubmitCertificate,WINTRUST.DLL,NM,1 passes a WIN_CERTIFICATEstructure to all trust providers registered with the WinTrustservice. WinVerifyTrust,WINTRUST.DLL,NM,3, performs a specified verification action on a specified subject. WNetAddConnection,MPR.DLL,AW,3, enables the calling application to connect a local device to a network resource. WNetAddConnection2,MPR.DLL,AW,4, makes a connection to a network resource. WNetAddConnection3,MPR.DLL,AW,5, makes a connection to a network resource. WNetCancelConnection,MPR.DLL,AW,2, breaks an existing network connection. WNetCancelConnection2,MPR.DLL,AW,3, breaks an existing network connection. WNetCloseEnum,MPR.DLL,NM,1, ends a network resource enumeration started by the WNetOpenEnum function. WNetConnectionDialog,MPR.DLL,NM,2, starts a general browsing dialog box for connecting to network resources. WNetConnectionDialog1,MPR.DLL,AW,1, brings up a general browsing dialog for connecting to network resources. WNetDisconnectDialog,MPR.DLL,NM,2, starts a general browsing dialog box for disconnecting from network resources. WNetDisconnectDialog1,MPR.DLL,AW,1, attempts to disconnect from a network resource. WNetEnumResource,MPR.DLL,AW,4, continues a network-resource enumeration started by the WNetOpenEnum function. WNetGetConnection,MPR.DLL,AW,3, retrieves the name of the network resource associated with a local device. WNetGetLastError,MPR.DLL,AW,5, retrieves the most recent extended error code set by a Windows network function. WNetGetNetworkInformation,MPR.DLL,AW,2 returns extended informationabout a specific network whose name was returned by a previousnetwork enumeration. WNetGetProviderName,MPR.DLL,AW,3, obtains the provider name for a specific type of network. WNetGetUniversalName,MPR.DLL,AW,4 takes a drive-based path for a network resource and obtains a data structure that contains a more universal form of the name. WNetGetUser,MPR.DLL,AW,3, retrieves the current default user name or the user name used to establish a network connection. WNetOpenEnum,MPR.DLL,AW,5, starts an enumeration of network resources or existing connections. WNetUseConnection,MPR.DLL,AW,8, makes a connection to a network resource. WPUCompleteOverlappedRequest,WS2_32.DLL,NM,5, performs overlapped I/O completion notification for overlapped I/O operations. WrapCompressedRTFStream,MAPI32.DLL,NM,3 creates a text stream in uncompressed Rich Text Format (RTF) from the compressed format used in the PR_RTF_COMPRESSED property. WrapStoreEntryID,MAPI32.DLL,NM,6 converts a message store?s internalentry identifier to an entry identifier more usable by themessaging system. WriteClassStg,OLE32.DLL,NM,2, stores the specified class identifier (CLSID) in a storage object. WriteClassStm,OLE32.DLL,NM,2, stores the specified CLSID in the stream. WriteConsole,KERNEL32.DLL,AW,5, writes a character string to a console screen buffer beginning at the current cursor location. WriteConsoleInput,KERNEL32.DLL,AW,4, writes data directly to the console input buffer. WriteConsoleOutput,KERNEL32.DLL,AW,5 writes character and colorattribute data to a specified rectangular block of character cellsin a console screen buffer. WriteConsoleOutputAttribute,KERNEL32.DLL,NM,5 copies a number of foreground and background color attributes to consecutive cells of a console screen buffer, beginning at a specified location. WriteConsoleOutputCharacter,KERNEL32.DLL,AW,5 copies a number of characters to consecutive cells of a console screen buffer, beginning at a specified location. WriteFile,KERNEL32.DLL,NM,5, writes data to a file and is designed for both synchronous and asynchronous operation. WriteFileEx,KERNEL32.DLL,NM,5, writes data to a file. WriteFmtUserTypeStg,OLE32.DLL,NM,3, writes a clipboard format and user type to the storage object. WritePrinter,WINMM.DLL,NM,4, informs the print spooler that data should be written to the specified printer. WritePrivateProfileSection,KERNEL32.DLL,AW,3, replaces the keys and values under the specified section in an initialization file. WritePrivateProfileString,KERNEL32.DLL,AW,4, copies a string into the specified section of the specified initialization file. WritePrivateProfileStruct,KERNEL32.DLL,AW,5, copies data into the to the end of the data. WriteProcessMemory,KERNEL32.DLL,NM,5, writes memory in a specified process. WriteProfileSection,KERNEL32.DLL,AW,2, replaces the contents of the specified section in the WIN. WriteProfileString,KERNEL32.DLL,AW,3, copies a string into the specified section of the WIN. WriteTapemark,KERNEL32.DLL,NM,4, writes a specified number of filemarks, setmarks, short filemarks, or long filemarks to a tape device. WSAAccept,WS2_32.DLL,NM,5 accepts a connection based on the return value of a condition function, andoptionally creates or joins a socket group. WSAAddressToString,WS2_32.DLL,AW,5 converts all components of a SOCKADDR structure into a human-readable stringrepresentation of the address. WSAAsyncGetHostByAddr,WS2_32.DLL,NM,7, asynchronously retrieves host information that corresponds to an address. WSAAsyncGetHostByAddr,WSOCK32.DLL,NM,7, is an asynchronous version of gethostbyaddr. WSAAsyncGetHostByName,WS2_32.DLL,NM,5 cancels an incomplete asynchronous operation. WSAAsyncGetHostByName,WSOCK32.DLL,NM,5 processing a callback function. WSAAsyncGetProtoByName,WS2_32.DLL,NM,5, asynchronously retrieves protocol information that corresponds to a protocol name. WSAAsyncGetProtoByName,WSOCK32.DLL,NM,5, asynchronously retrieves protocol information that corresponds to a protocol name. WSAAsyncGetProtoByNumber,WS2_32.DLL,NM,5 asynchronously retrieves protocol information corresponding to aprotocol number. WSAAsyncGetProtoByNumber,WSOCK32.DLL,NM,5 asynchronously retrieves protocol information corresponding to aprotocol number. WSAAsyncGetServByName,WS2_32.DLL,NM,6 asynchronously retrieves service information corresponding to a service name andport. WSAAsyncGetServByName,WSOCK32.DLL,NM,6 asynchronously retrieves service information corresponding to a service name andport. WSAAsyncGetServByPort,WS2_32.DLL,NM,6 gets serviceinformation corresponding to a port and protocol asynchronously. WSAAsyncGetServByPort,WSOCK32.DLL,NM,6 gets service information corresponding to a port and protocol asynchronously. WSAAsyncSelect,WS2_32.DLL,NM,4, is used to request that WS2_32. WSAAsyncSelect,WSOCK32.DLL,NM,4, is used to request that WS2_32. WSACancelAsyncRequest,WS2_32.DLL,NM,1 cancels an incomplete asynchronous operation. WSACancelAsyncRequest,WSOCK32.DLL,NM,1 cancels an incomplete asynchronous operation. WSACancelBlockingCall,WS2_32.DLL,NM,0 closes an existing socket. WSACancelBlockingCall,WSOCK32.DLL,NM,0 closes an existing socket. WSACleanup,WS2_32.DLL,NM,0 terminates use of theWS2_32. WSACleanup,WSOCK32.DLL,NM,0 terminates use of theWS2_32. WSACloseEvent,WS2_32.DLL,NM,1 closes an open eventobject handle. WSAConnect,WS2_32.DLL,NM,7 establishes a connection to another socket application, exchanges connect data, and specifies needed quality of service based on the supplied FLOWSPEC structure. WSACreateEvent,WS2_32.DLL,NM,0 creates a new event object. WSADuplicateSocket,WS2_32.DLL,AW,3, is used to enable socket sharing between processes. WSAEnumNameSpaceProviders,WS2_32.DLL,AW,2, retrieves information about available namespaces. WSAEnumNetworkEvents,WS2_32.DLL,NM,3 discovers occurrences of network events for the indicated socket. WSAEnumProtocols,WS2_32.DLL,AW,3, provides equivalent functionality in Windows Sockets 2. WSAEventSelect,WS2_32.DLL,NM,3 specifies an event object to be associated with the supplied set of FD_XXX network events. WSAGetLastError,WS2_32.DLL,NM,0, returns the error status for the last operation that failed. WSAGetLastError,WSOCK32.DLL,NM,0, returns the error status for the last operation that failed. WSAGetOverlappedResult,WS2_32.DLL,NM,5 returns theresults of an overlapped operation on the specified socket. WSAGetQOSByName,WS2_32.DLL,NM,3 initializes a QUALITYOFSERVICE structure based on a named template. WSAGetServiceClassInfo,WS2_32.DLL,AW,4 retrieves all of the class information (schema) pertaining to a specified serviceclass from a specified name space provider. WSAGetServiceClassNameByClassId,WS2_32.DLL,AW,3, retrieves the name of the service associated with the specified type. This name is the generic service name, like FTP or SNA, and not the name of a specific instance of that service. WSAHtonl,WS2_32.DLL,NM,3 converts a u_long from hostbyte order to network byte order. WSAHtons,WS2_32.DLL,NM,3 converts a u_short from hostbyte order to network byte order. WSAInstallServiceClass,WS2_32.DLL,AW,1 registers a service class schema within a name space. WSAIoctl,WS2_32.DLL,NM,9 controls the mode of a socket. WSAIsBlocking,WS2_32.DLL,NM,0 This has been removed in compliance with the WindowsSockets 2 specification, revision 2. WSAIsBlocking,WSOCK32.DLL,NM,0 This has been removed in compliance with the WindowsSockets 2 specification, revision 2. WSAJoinLeaf,WS2_32.DLL,NM,8 joins a leaf node into a multipoint session, exchanges connect data, and specifies needed quality of service based on the supplied FLOWSPEC structures. WSALookupServiceBegin,WS2_32.DLL,AW,3 ininitiates a client query that is constrained by the information containedwithin a WSAQUERYSET structure. WSALookupServiceEnd,WS2_32.DLL,NM,1 called to free the handle after previous calls to WSALookupServiceBegin and WSALookupServiceNext . 155 WSALookupServiceNext,WS2_32.DLL,AW,4 called after obtaining a handle from a previous call to WSALookupServiceBegin in order to retrieve the requested service information. WSANtohl,WS2_32.DLL,NM,3 converts a u_long from network byte order to host byte order. WSANtohs,WS2_32.DLL,NM,3 WSANtohsconverts a u_short fromnetwork byte order to host byte order. WSAProviderConfigChange,WS2_32.DLL,NM,3, notifies the application when the provider configuration is changed. WSARecv,WS2_32.DLL,NM,7 WSARecvreceives data from a socket. WSARecvDisconnect,WS2_32.DLL,NM,2 terminates receptionon a socket, and retrieves the disconnect data if the socket isconnection oriented. WSARecvEx,MSWSOCK.DLL,NM,4 The Windows Sockets WSARecvEx function is identical to the recv function, except the flags parameter is an in-out parameter. WSARecvEx,WSOCK32.DLL,NM,4 The Windows Sockets WSARecvEx function is identical to the recv function, except the flags parameter is an in-out parameter. WSARecvFrom,WS2_32.DLL,NM,9 receives a datagram andstores the source address. WSARemoveServiceClass,WS2_32.DLL,NM,1 permanently unregisters service class schema. WSAResetEvent,WS2_32.DLL,NM,1, is used to set the state of the event object to nonsignaled. WSASend,WS2_32.DLL,NM,7 sends data on a connectedsocket. WSASendDisconnect,WS2_32.DLL,NM,2 initiates termination of the connection for the socket and sends disconnectdata. WSASendTo,WS2_32.DLL,NM,9 sends data to a specificdestination, using overlapped I/O where applicable. WSASetBlockingHook,WS2_32.DLL,NM,1 This has been removed in compliance with the WindowsSockets 2 specification, revision 2. WSASetBlockingHook,WSOCK32.DLL,NM,1 This has been removed in compliance with the WindowsSockets 2 specification, revision 2. WSASetEvent,WS2_32.DLL,NM,1, sets the state of the event object to be signaled. WSASetLastError,WS2_32.DLL,NM,1 sets the error code that can be retrieved through the WSAGetLastError function. WSASetLastError,WSOCK32.DLL,NM,1 sets the error code that can be retrieved through the WSAGetLastError function. WSASetService,WS2_32.DLL,AW,3 registers or deregisters a service instance within one or more name spaces. WSASocket,WS2_32.DLL,AW,6 creates a socket that is bound to a specific transport service provider, and optionally creates and/or joins a socket group. WSAStartup,WS2_32.DLL,NM,2, initiates use of WS2_32.DLL by a process. WSAStartup,WSOCK32.DLL,NM,2, initiates use of WS2_32.DLL by a process. WSAStringToAddress,WS2_32.DLL,AW,5, converts a numeric string to a sockaddr structure, suitable for passing to Windows Sockets routines that take such a structure. WSAUnhookBlockingHook,WS2_32.DLL,NM,0 This has been removed in compliance with the WindowsSockets 2 specification, revision 2. WSAUnhookBlockingHook,WSOCK32.DLL,NM,0 Thishas been removed in compliance with the WindowsSockets 2 specification, revision 2. WSAWaitForMultipleEvents,WS2_32.DLL,NM,5 returns either when one or all of the specified event objects are in the signaled state, or when the time-out interval expires. WSCDeinstallProvider,WS2_32.DLL,NM,2, removes the specified transport provider from the system configuration database. WSCEnableNSProvider,WS2_32.DLL,NM,2, changes the state of a given name-space provider. It is intended to give the end user the ability to change the state of the name-space providers through Control Panel. WSCEnumProtocols,WS2_32.DLL,NM,4, retrieves information about available transport protocols. WSCGetProviderPath,WS2_32.DLL,NM,4, retrieves the DLL path for the specified provider. WSCInstallNameSpace,WS2_32.DLL,NM,5, installs a name-space provider. For providers that are able to support multiple names spaces, this function must be called once for every namespace supported, and a unique provider identifier must be supplied each time. WSCInstallProvider,WS2_32.DLL,NM,5, installs the specified transport provider into the system configuration database. WSCUnInstallNameSpace,WS2_32.DLL,NM,1, uninstalls the indicated name-space provider. WSCWriteProviderOrder,WS2_32.DLL,NM,2, is used to reorder the available transport providers. The order of the protocols determines the priority of a protocol when being enumerated or selected for use. wvsprintf,USER32.DLL,AW,3, formats and stores a series of characters and values in a buffer. _hread,KERNEL32.DLL,NM,3, reads data from the specified file. _hwrite,KERNEL32.DLL,NM,3, writes data to the specified file. _lclose,KERNEL32.DLL,NM,1, closes the specified file so that it is no longer available for reading or writing. _lcreat,KERNEL32.DLL,NM,2, creates or opens a specified file. _llseek,KERNEL32.DLL,NM,3 repositions the file pointer in a previously opened file. _lopen,KERNEL32.DLL,NM,2, opens an existing file and sets the file pointer to the beginning of the file. _lread,KERNEL32.DLL,NM,3, reads data from the specified file. _lwrite,KERNEL32.DLL,NM,3, writes data to the specified file. __WSAFDIsSet,WS2_32.DLL,NM,2, specifies whether a socket is included in a set of socket descriptors. __WSAFDIsSet,WSOCK32.DLL,NM,2, specifies whether a socket is included in a set of socket descriptors. . Sve ove funkcije se pozivaju StdCall pravilima, a funkcije koje se pozivaju po Ccall pravilima (uglavnom funkcije iz Microsoft C runtime biblioteka) nisu navedene u ovoj tabeli. Dato je oko 4800 funkcija. Pored ovoga oko 1000 funkcija sa spiska ima ASCII i Unicode verzije. Ali, ni to nije sve, postoji još oko 3000 nedokumentovanih funkcija i oko 2000 funkcija čija imena i način poziva nisu kompatibilni sa FILDZAN-32 (ali se mogu pozvati Inline asemblerom), te ogroman broj COM/OLE i .NET objekata i metoda, kao i struktura i Windows poruka. 16.4. Portiranje Windows API funkcije Prilikom upotrebe API funkcije u jeziku koji smo razvili, potrebno je učiniti nekoliko koraka. • Dobavljanje dokumentacije za API funkcije Dokumentacija za sve API funkcije navedene u listi se može naći na Internetu (najčešće uz pomoć stranica msdn.microsoft.com ili www.google.com) ili na dokumentacijskim CD-ovima Microsoft Developer Network Library, ali je obično ograničena na programski jezik C. Neka je cilj, na primjer, portirati funkciju CopyFile. Dokumentacija za ovu funkciju izgleda ovako: CopyFile The CopyFile function copies an existing file to a new file. BOOL CopyFile( LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfExists ); Parameters lpExistingFileName [in] Pointer to a null-terminated string that specifies the name of an existing file. In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. For more information, see Naming a File. Windows Me/98/95: This string must not exceed MAX_PATH characters. If lpExistingFileName does not exist, CopyFile fails, and GetLastError returns ERROR_FILE_NOT_FOUND. lpNewFileName [in] Pointer to a null-terminated string that specifies the name of the new file. In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. For more information, see Naming a File. Windows Me/98/95: This string must not exceed MAX_PATH characters. 156 bFailIfExists [in] If this parameter is TRUE and the new file specified by lpNewFileName already exists, the function fails. If this parameter is FALSE and the new file already exists, the function overwrites the existing file and succeeds. Return Values If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. Remarks Security attributes for the existing file are not copied to the new file. To copy security attributes, use the SHFileOperation function. File attributes for the existing file are copied to the new file. For example, if an existing file has the FILE_ATTRIBUTE_READONLY file attribute, a copy created through a call to CopyFile will also have the FILE_ATTRIBUTE_READONLY file attribute. For more information, see Retrieving and Changing File Attributes. This function fails with ERROR_ACCESS_DENIED if the destination file already exists and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_READONLY attribute set. When CopyFile is used to copy an encrypted file, it attempts to encrypt the destination file with the keys used in the encryption of the source file. If this cannot be done, this function attempts to encrypt the destination file with default keys, as in Windows 2000. If neither of these methods can be done, CopyFile fails with an ERROR_ENCRYPTION_FAILED error code. Windows 2000: When CopyFile is used to copy an encrypted file, the function attempts to encrypt the destination file with the default keys. No attempt is made to encrypt the destination file with the keys used in the encryption of the source file. If it cannot be encrypted, CopyFile completes the copy operation without encrypting the destination file. Example Code For an example, see Retrieving and Changing File Attributes. Requirements Client Requires Windows "Longhorn", Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95. Server Requires Windows Server "Longhorn", Windows Server 2003, Windows 2000 Server, or Windows NT Server. Header Declared in Winbase.h; include Windows.h. Library Link to Kernel32.lib. DLL Requires Kernel32.dll. Unicode Implemented as CopyFileW (Unicode) and CopyFileA (ANSI). Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode. See Also • Konverzija imena, tipova argumenata i konstanti Kako u tabeli funkcija uz ovu funkciju stoji oznaka AW, ime funkcije će biti CopyFileA, jer u FILDZAN-32 se radi sa ASCII stringovima. Tipovi argumenata se najčešće portiraju u cijele brojeve i pointere. Windows koristi predefinisane tipove koji se obično mogu naći na web stranici http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/windows_data_types.asp Na ovoj stranici je nađeno da su dva tipa koji se koriste u CopyFile funkciji LPCTSTR i BOOL, deklarisana kao typedef __nullterminated CONST CHAR *LPCSTR; #ifdef UNICODE typedef LPCWSTR LPCTSTR; #else typedef LPCSTR LPCTSTR; #endif typedef int BOOL; Iz ovog se vidi da se tip “BOOL” transformiše u tip “cijeli” a tip “LPCTSTR” u tip “karakter *”. U dokumentaciji se spominju i neke konstante, kao što su FILE_ATTRIBUTE_HIDDEN , FILE_ATTRIBUTE_READONLY,ERROR_ENCRYPTION_FAILED,ERROR_FILE_NOT_FOUND,ERROR_ACCESS_D ENIED, MAX_PATH. Ako će se ove konstante koristiti, treba portirati i njihove vrijednosti. Vrijednosti je najlakše naći ako na Internet pretraživaču, npr. www.google.com unesemo #define sa imenom konstante, npr. #define ERROR_FILE_NOT_FOUND Mrežni pretraživač će vratiti da ova konstanta ima vrijednost jednaku 2. • Pravljenje deklaracije Sada se može napisati deklaracija funkcije i pripadnih konstanti. Tipovi u C se zamijene ekvivalentnim tipovima u FILDZAN-32 i redoslijed argumenata se izvrne, zbog razlike u Pascal Call i StdCall. 157 #definiraj ERROR_FILE_NOT_FOUND 2 cijeli funkcija CopyFileA( cijeli bFailIfExists karakter * lpNewFileName, karakter * lpExistingFileName, ); • Upotreba funkcije U istom listingu u kome je deklaracija može se pozvati funkcija. Evo kao primjer cijelog programa: #definiraj ERROR_FILE_NOT_FOUND 2 cijeli funkcija CopyFileA( cijeli bFailIfExists karakter * lpNewFileName, karakter * lpExistingFileName, ); { CopyFileA(0,”KopijaPodaci.Txt”,”Podaci.txt”); } Primjer se prevede i asemblira kao i ostali primjeri. Prilikom linkovanja mora se paziti da imamo ekvivalentnu MASM biblioteku sa ekstenzijom LIB datoteci sa ekstenzijom DLL u kojoj je definisana funkcija. Funkcija CopyFile je definisana u kernel32.dll, pa se pripaja kernel32.lib. link /defaultlib:kernel32.lib /subsystem:console primjer.obj 16.5. Rezime poglavlja Windows API ima veliki broj funkcija koje se mogu koristiti u raznim programskim jezicima. One su obično definisane za programski jezik C. Kod novih programskih jezika obično je potrebno, ali i moguće, prilagoditi pozive iz ovih biblioteka osobinama programskog jezika. To je posao lakši od pravljenja novih biblioteka. U slučaju FILDZAN-32, treba prilagoditi ime funkcije, nazive tipova, konstante te redoslijed argumenata. 158 17. ASEMBLER Kompajler koji je razvijen u okviru ovog kursa generiše asemblerski listing, a ne prirodni mašinski kod. Za prevođenje iz asemblerskog jezika u mašinski jezik iskorišten je Microsoftov Macro asembler. Sada slijedi razvoj asemblera, programa koji treba da prevede iz asemblerskog listinga u mašinski jezik. Prvo je potrebno navesti spisak svih instrukcija koje ovaj procesor poznaje 17.1. Instrukcijski set Pentiuma II Tipična instrukcija mikroprocesora Pentium II izgleda kao na slici Sl. 17.1.1: Instruction Format +-----------+-----------+-----------+-----------+-----------+-----------+ | | | | | | | | Prefixes | Opcode | ModR/M | SIB | Disp | immediate | | | | | | | | +-----------+-----------+-----------+-----------+-----------+-----------+ Sl. 17.1.1. Format instrukcija Prefixes : Nula do četiri prefiksa velika po jedan bajt: (LOCK | REP | REPE | REPZ | REPNE | REPZ) (CS | SS | DS | ES | FS | GS) (66) (67) Opcode: 1 ili 2 bajtni operacioni kod ModR/M: Biti 7..6 predstavljaju Mode, biti 2..0 sadrže kod registra ili memorijskog režima koji je indiciran modom, biti 5..3 su rezervno polje SIB Biti 7..6 su faktor skaliranja, 5..3 je Index, 2..0 je Baza Disp: Opcioni adresni pomak od 1, 2, ili 4 bajta Immediate Opcionalna konstantna vrijednost od 1, 2 ili 4 bajta Sve instrukcije ovog procesora opisane su u tabeli na strani 161. Slijedi objašnjenje tabele: 17.2. Operacioni kodovi, opis Heksadekadni broj, na primjer 9F, predstavlja sam taj broj. Heksadekadni broj praćen oznakom +r, npr C8+r znači da se broj koji predstavlja registarski operand treba dodati tom broju. Npr., EDX je predstavljen brojem 2, pa će to generisati heksadekadni bajt CA. Brojevi koji predstavljaju registarski operand 0 AL AX EAX ES ST0 MM0 xmmr0 1 CL CX ECX CS ST1 MM1 xmmr1 2 DL DX EDX SS ST2 MM2 xmmr2 3 BL BX EBX DS ST3 MM3 xmmr3 4 AH SP ESP FS ST4 MM4 xmmr4 5 CH BP EBP GS ST5 MM5 xmmr5 6 DH SI ESI ST6 MM6 xmmr6 7 BH DI EDI ST7 MM7 xmmr7 CR0 CR2 CR3 CR4 DR0 DR1 DR2 DR3 DR6 DR7 TR3 TR4 TR5 TR6 TR7 Sl. 17.2.1. Brojevi koji predstavljaju registarski operand Jednocifreni broj iza kose crte (npr /3) znači da se taj broj smješta u rezervno polje ModRM bajta.. Simbol /r znači da broj koji predstavlja registarski operand se smješta u rezervno polje ModRM bajta. Simboli ib, iw i id predstavljaju konstantnu vrijednost koja može biti bajt, riječ ili dupla riječ. Ovi podaci se smještaju u little endian formatu. Simboli rb, rw i rd znače da je jedan od operanada konstantna vrijednost i da se razlika između te vrijednosti i adrese kraja instrukcije treba kodirati kao bajt, riječ ili dupla riječ respektivno. Simbol r? predstavlja da se treba koristiti rw ili rd zavisno od toga da li se asembliranje vrši u 16-bitnom ili 32-bitnom režimu. Simboli ow , od i o? znače da je jedan od operanada predstavljen apsolutnom adresom. Simboli o16 i o32 znače da je veličina operanada 16 ili 32 bita. Intelovi procesori koriste prefiks 66 da promijene podrazumijevanu veličinu operanada. Stoga o16 znači da će ta instrukcija imati prefiks 66 ako se asembliranje vrši u 32 bitnom režimu a neće imati prefiks ako se asembliranje vrši u 16 bitnom režimu. Analogno, o32 znači da će ta instrukcija imati prefiks 66 ako se asembliranje vrši u 16 bitnom režimu a neće imati prefiks ako se asembliranje vrši u 32 bitnom režimu. 159 Kodovi a16 i a32 slično kodovima o16 i o32 označavaju adresnu veličinu navedene forme instrukcije. Ako se ona ne slaže sa podrazumijevanom veličinom, ubacuje se prefiks 67. Ovaj se prefiks ubacuje i kada nema kodova a16 i a32, a navedeni adresni način ne postoji u 16 bitnom odnosno 32 bitnom režimu (npr., ako u 32 bitnom režimu se prevodi instrukcija MOV EAX,[BX] treba generisati prefiks 67, jer je [BX] šesnaestobitni adresni način.) 17.3. Operandi U tabeli instrukcija operandi su označeni sljedećim kodovima: reg8 8-bitni registar opšte namjene rg16 16-bitni registar opšte namjene rg32 32-bitni registar opšte namjene fpur Jedan od 8 FPU registara mmxr Jedan od 8 MMX (64 bitnih) registara segr Jedan od segmentnih registara immg Neki konstantni operand ime8 8-bitni konstantni operand im16 16- bitni konstantni operand im32 32- bitni konstantni operand memg Memorijska adresa mem8 8-bitna memorijska adresa mm16 16-bit memorijska adresa Sl. 17.3.1. 17.4. mm32 32-bitna memorijska adresa mm64 64-bitna memorijska adresa mm80 80-bitna memorijska adresa rgm8 skraćenica za reg8/mem8 rm16 skraćenica za rg16/mm16 rm32 skraćenica za rg32/mm32 rm64 skraćenica za mmxr/mm64 abs8 apsolutna adresa 8 bitnih podataka ab16 apsolutna adresa 16 bitnih podataka ab32 apsolutna adresa 32 bitnih podataka creg kontrolni registar dreg Debug registar treg Task registar Tablica vrsta operanada Kodiranje adrese: ModR/M i SIB bajtovi Adresni operand je kodiran iz tri dijela (1) MOD/RM bajt, (2) opcionalni SIB bajt i (3) opcionalni bajt, riječ ili dupla riječ pomaka. ModR/M se sastoji od tri polja, mod polje u bitima 7..6, r/m polje u bitima 2..0 i rezervno polje u bitima 5..3Rezervno polje nije relevantno za adresu koja se kodira. R/M znači registar ili memorija, što znači da se može kodirati direktna referenca na registar umjesto memorijskog pristupa. To se radi postavljanjem mod polja na 3 i r/m polja na broj koji predstavlja registarski operand. U tom slučaju nema ni SIB bajta ni pomaka. U 16 bitnom režimu SIB bajt se nikada ne koristi. Mod predstavlja veličinu pomaka (0, 1, 2 bajta) ili 3 ako je u pitanju registar. Polja 2..0 dopuštaju nekoliko kombinacija registara za adresiranje, pri čemu [bp] se mora kodirati kao [bp+0] r/m | mod=00 mod=01 mod=10 mod=11 ----+---------------------------------------------------------------000 | [bx+si] [bx+si+disp8] [bx+si+disp16] al/ax/eax/mm0/xmmr0 001 | [bx+di] [bx+di+disp8] [bx+di+disp16] cl/cx/ecx/mm1/xmmr1 010 | [bp+si] [bp+si+disp8] [bp+si+disp16] dl/dx/edx/mm2/xmmr2 011 | [bp+di] [bp+di+disp8] [bp+di+disp16] bl/bx/ebx/mm3/xmmr3 100 | [si] [si+disp8] [si+disp16] ah/sp/esp/mm4/xmmr4 101 | [di] [di+disp8] [di+disp16] ch/bp/ebp/mm5/xmmr5 110 | [disp16] [bp+disp8] [bp+disp16] dh/si/esi/mm6/xmmr6 111 | [bx] [bx+disp8] [bx+disp16] bh/di/edi/mm7/xmmr7 Sl. 17.4.1. Kodiranje MOD/Rm bajta, 16 bitno U 32 bitnom režimu mod polje predstavlja dužinu dijela pomaka, 0 znači da nema pomaka, 1 znači jedan bajt, 2 predstavlja 4 bajta. Ako se pomaku pridodaje samo jedan registar i on nije ESP, tada r/m polje sadrži vrijednost koja predstavlja taj registar i nema polja SIB. Ako je r/m polje jednako 4 , postoji SIB polje. Također, [ebp] se mora kodirati kao [ebp+0]. r/m | mod=00 mod=01 mod=10 mod=11 ----+----------------------------------------------------------000 | [eax] [eax+disp8] [eax+disp32] al/ax/eax/mm0/xmmr0 001 | [ecx] [ecx+disp8] [ecx+disp32] cl/cx/ecx/mm1/xmmr1 010 | [edx] [edx+disp8] [edx+disp32] dl/dx/edx/mm2/xmmr2 011 | [ebx] [ebx+disp8] [ebx+disp32] bl/bx/ebx/mm3/xmmr3 100 | SIB SIB+disp8 SIB+disp32 ah/sp/esp/mm4/xmmr4 101 | [disp32] [ebp+disp8] [ebp+disp32] ch/bp/ebp/mm5/xmmr5 110 | [esi] [esi+disp8] [esi+disp32] dh/si/esi/mm6/xmmr6 111 | [edi] [edi+disp8] [edi+disp32] bh/di/edi/mm7/xmmr7 Sl. 17.4.2. Kodiranje ModRm , 32 bitno 160 SIB bajt ima tri polja: Faktor skaliranja u bitima 7..6 koji predstavljaju 1, 2, 4 ili 8, indeksni registar u bitima 5..3 i bazni registar u bitima 2..0. Ideja je da se generiše [BASE + SCALE*INDEX], koji se onda dodaju eventualnom pomaku navedenom u ModR/M bajtu. Na primjer, kod D3 (11010011) ima skalu 11 (znači 8), indeksni registar 010 (znači EDX) i bazni registar 011 (znači EBX) pa se kodira kao [ebx+edx*8]. Ipak, ESP se ne može koristiti kao indeksni registar, pa ako indeksno polje sadrži 4, to znači da nema indeksnog registra. Takođe, ako bazno polje sadrži 5, a mod biti su 00, adresa nije [ebp+scale*index] nego [scale*index+disp32] (nema baznog registra). Primjeri: ecx [ecx] [ecx+12345678H] [ecx+esi*2] [ecx+esi*2+12345678H] [esi*2] [esi*2+12345678H] [12345678H] [ebp] [ebp+12345678H] [ebp+eax*4] [ebp+eax*4+12345678H] [esp] [esp+12345678H] 17.5. 11xxx001 00xxx001 10xxx001 78 00xxx100 71 10xxx100 71 00xxx100 75 10xxx100 75 00xxx101 78 01xxx101 00 10xxx101 78 01xxx100 85 10xxx100 85 00xxx100 24 10xxx100 24 56 34 12 78 56 34 12 78 56 34 12 56 34 12 56 34 12 00 78 56 34 12 78 56 34 12 Primjeri kodiranja kompletnih instrukcija MOV ECX,[EDX+150h] Prvi operand je 32bitni registar opšte namjene, a drugi 32 bitna memorijska lokacija. U tablici se nalazi MOV rg32,rm32 o32 8B /r Ako je režim rada 32-bitni (tj. generiše se kod za 32 bitne operativne sisteme), o32 nema značenja. Operacioni kod instrukcije je 8B. [EDX+150h] spada u kategoriju [EDX+Disp32] koja u polju r/m ima vrijednost 010 binarno, a u polju mod vrijednost 10 binarno. Ovaj adresni režim ne zahtijeva SIB bajt, ali ima pomak. Rezervno polje ModRM bajta je broj registra ECX koji iznosi 1, odnosno binarno 001. Stoga je ModRM bajt 10 001 010, što u heksadekadnom sistemu iznosi 8A. Pomak napisan 32 bitno iznosi 00000150, što napisano little endian formatom predstavlja 50 01 00 00. Dakle, ova instrukcija se kodira kao 8B 8A 50 01 00 00 U 16 bitnom režimu rada vidimo da je adresa 32 bitna, pa je neophodan prefiks 67. Takođe, o32 znači da treba dodati i prefiks 66, pa se ova instrukcija piše kao 66 67 8B 8A 50 01 00 00 XOR BX,1500h Prvi operand je 16 bitni registar, drugi operand 16 bitna konstanta. U tabeli je takav slučaj naveden kao XOR rm16,im16 o16 81 /6 iw U šesnaestobitnom režimu nije potreban prefiks, a u 32 bitnom simbol o16 predstavlja da je tu potreban prefiks 66. Pošto se nigdje ne spominje adresa, nema prefiksa 67. Operacioni kod je 81. Pošto je operand tipa registar (neposredna vrijednost nije u tabeli ModRm), mod=11, r/m=011. Oznaka /6 znači da se u rezervno polje upisuje vrijednost 6, tj. 110. Stoga je bajt ModRm jednak 11 110 011, ili heksadekadno F3. Pomak 1500h u little endian se piše kao 00 15. Prema tome, u 16 bitnom režimu ova instrukcija se kodira kao 81 F3 15 00 ,a u 32 bitnom kao 66 81 F3 15 00. 161 AAA AAD AAM AAS ADC AL,ime8 ADC AX,im16 ADC EAX,im32 ADC reg8,rgm8 ADC rgm8,ime8 ADC rgm8,reg8 ADC rg16,rm16 ADC rg32,rm32 ADC rm16,ime8 ADC rm16,im16 ADC rm16,rg16 ADC rm32,ime8 ADC rm32,im32 ADC rm32,rg32 ADD AL,ime8 ADD AX,im16 ADD EAX,im32 ADD reg8,rgm8 ADD rgm8,ime8 ADD rgm8,reg8 ADD rg16,rm16 ADD rg32,rm32 ADD rm16,ime8 ADD rm16,im16 ADD rm16,rg16 ADD rm32,ime8 ADD rm32,im32 ADD rm32,rg32 AND AL,ime8 AND AX,im16 AND EAX,im32 AND reg8,rgm8 AND rgm8,ime8 AND rgm8,reg8 AND rg16,rm16 AND rg32,rm32 AND rm16,ime8 AND rm16,im16 AND rm16,rg16 AND rm32,ime8 AND rm32,im32 AND rm32,rg32 ARPL rm16,rg16 BOUND rg16,mm16:16 BOUND rg32,mm32:32 BSF rg16,rm16 BSF rg32,rm32 BSR rg16,rm16 BSR rg32,rm32 BSWAP rg32 BTC rm16,ime8 BTC rm16,rg16 BTC rm32,ime8 BTC rm32,rg32 BTR rm16,ime8 BTR rm16,rg16 BTR rm32,ime8 BTR rm32,rg32 BTS rm16,immg BTS rm16,rg16 BTS rm32,immg BTS rm32,rg32 BT rm16,ime8 BT rm16,rg16 BT rm32,ime8 BT rm32,rg32 CALL_FAR mm16 CALL_FAR mm32 CALL immg CALL immg:im16 CALL immg:im32 CALL rm16 CALL rm32 CBW CDQ CLC CLD CLI CLTS CMC CMOVO rg16,rm16 CMOVO rg32,rm32 CMOVNO rg16,rm16 CMOVNO rg32,rm32 CMOVC rg16,rm16 CMOVC rg32,rm32 CMOVB rg16,rm16 CMOVB rg32,rm32 CMOVNC rg16,rm16 CMOVNC rg32,rm32 CMOVAE rg16,rm16 CMOVAE rg32,rm32 CMOVE rg16,rm16 CMOVE rg32,rm32 CMOVZ rg16,rm16 CMOVZ rg32,rm32 CMOVNE rg16,rm16 CMOVNE rg32,rm32 CMOVNZ rg16,rm16 CMOVNZ rg32,rm32 CMOVBE rg16,rm16 CMOVBE rg32,rm32 CMOVA rg16,rm16 CMOVA rg32,rm32 CMOVS rg16,rm16 CMOVS rg32,rm32 37 D5 D4 3F 14 o16 o32 12 80 10 o16 o32 o16 o16 o16 o32 o32 o32 04 o16 o32 02 80 00 o16 o32 o16 o16 o16 o32 o32 o32 24 o16 o32 22 80 20 o16 o32 o16 o16 o16 o32 o32 o32 63 o16 o32 o16 o32 o16 o32 o32 o16 o16 o32 o32 o16 o16 o32 o32 o16 o16 o32 o32 o16 o16 o32 o32 o16 o32 E8 o16 o32 o16 o32 o16 o32 F8 FC FA 0F F5 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 0A 0A ib 15 15 /r /2 /r 13 13 83 81 11 83 81 11 ib 05 05 /r /0 /r 03 03 83 81 01 83 81 01 ib 25 25 /r /4 /r 23 23 83 81 21 83 81 21 /r 62 62 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F FF FF r? 9A 9A FF FF 98 99 iw id ib /r /r /2 /2 /r /2 /2 /r ib iw ib id iw id ib /r /r /0 /0 /r /0 /0 /r ib iw ib id iw id ib /r /r /4 /4 /r /4 /4 /r ib iw ib id /r /r BC /r BC /r BD /r BD /r C8+rg BA /7 BB /r BA /7 BB /r BA /6 B3 /r BA /6 B3 /r BA /5 AB /r BA /5 AB /r BA /4 A3 /r BA /4 A3 /r /3 /3 iw iw id iw /2 /2 06 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 40 40 41 41 42 42 42 42 43 43 43 43 44 44 44 44 45 45 45 45 46 46 47 47 48 48 /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r ib ib ib ib ib ib ib ib CMOVNS rg16,rm16 CMOVNS rg32,rm32 CMOVP rg16,rm16 CMOVP rg32,rm32 CMOVPE rg16,rm16 CMOVPE rg32,rm32 CMOVNP rg16,rm16 CMOVNP rg32,rm32 CMOVPO rg16,rm16 CMOVPO rg32,rm32 CMOVL rg16,rm16 CMOVL rg32,rm32 CMOVGE rg16,rm16 CMOVGE rg32,rm32 CMOVNL rg16,rm16 CMOVNL rg32,rm32 CMOVLE rg16,rm16 CMOVLE rg32,rm32 CMOVG rg16,rm16 CMOVG rg32,rm32 CMPSB CMPSD CMPSW CMPXCHG8B mm64 CMPXCHG rgm8,reg8 CMPXCHG rm16,rg16 CMPXCHG rm32,rg32 CMP AL,ime8 CMP AX,im16 CMP EAX,im32 CMP reg8,rgm8 CMP rgm8,ime8 CMP rgm8,reg8 CMP rg16,rm16 CMP rg32,rm32 CMP rm16,ime8 CMP rm16,im16 CMP rm16,rg16 CMP rm32,ime8 CMP rm32,im32 CMP rm32,rg32 CPUID CWDE CWD DAA DAS DEC rgm8 DEC rg16 DEC rg32 DEC rm16 DEC rm32 DIV rgm8 DIV rm16 DIV rm32 EMMS ENTER immg,immg FABS FADDP fpur FADDP fpur,ST0 FADD FADD fpur FADD fpur,ST0 FADD mm32 FADD mm64 FADD ST0,fpur FBLD mm80 FBSTP mm80 FCHS FCLEX FCMOVBE fpur FCMOVBE ST0,fpur FCMOVB fpur FCMOVB ST0,fpur FCMOVE fpur FCMOVE ST0,fpur FCMOVNBE fpur FCMOVNBE ST0,fpur FCMOVNB fpur FCMOVNB ST0,fpur FCMOVNE fpur FCMOVNE ST0,fpur FCMOVNU fpur FCMOVNU ST0,fpur FCMOVU fpur FCMOVU ST0,fpur FCOMIP fpur FCOMIP ST0,fpur FCOMI fpur FCOMI ST0,fpur FCOMPP FCOMP fpur FCOMP mm32 FCOMP mm64 FCOMP ST0,fpur FCOM fpur FCOM mm32 FCOM mm64 FCOM ST0,fpur FCOS FDECSTP FDISI FDIVP fpur FDIVP fpur,ST0 FDIVRP fpur FDIVRP fpur,ST0 FDIVR FDIVR fpur FDIVR fpur,ST0 FDIVR mm32 FDIVR mm64 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 o16 o32 A6 o32 o16 0F 0F o16 o32 3C o16 o32 3A 80 38 o16 o32 o16 o16 o16 o32 o32 o32 0F o32 o16 27 2F FE o16 o32 o16 o32 F6 o16 o32 0F C8 D9 DE DE DE D8 DC D8 DC D8 DF DF D9 9B DA DA DA DA DA DA DB DB DB DB DB DB DB DB DA DA DF DF DB DB DE D8 D8 DC D8 D8 D8 DC D8 D9 D9 9B DE DE DE DE DE D8 DC D8 DC 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F A7 A7 C7 B0 0F 0F ib 3D 3D /r /0 /r 3B 3B 83 81 39 83 81 39 A2 98 99 49 49 4A 4A 4A 4A 4B 4B 4B 4B 4C 4C 4D 4D 4D 4D 4E 4E 4F 4F /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /1 /r B1 /r B1 /r iw id ib /r /r /0 /0 /r /0 /0 /r /1 48+rg 48+rg FF /1 FF /1 /6 F7 /6 F7 /6 77 iw ib E1 C0+rg C0+rg C1 C0+rg C0+rg /0 /0 C0+rg /4 /6 E0 DB E2 D0+rg D0+rg C0+rg C0+rg C8+rg C8+rg D0+rg D0+rg C0+rg C0+rg C8+rg C8+rg D8+rg D8+rg D8+rg D8+rg F0+rg F0+rg F0+rg F0+rg D9 D8+rg /3 /3 D8+rg D0+rg /2 /2 D0+rg FF F6 DB E1 F8+rg F8+rg F0+rg F0+rg F1 F8+rg F0+rg /0 /0 ib iw ib id FDIVR ST0,fpur FDIV fpur FDIV fpur,ST0 FDIV mm32 FDIV mm64 FDIV ST0,fpur FENI FFREEP fpur FFREE fpur FIADD mm16 FIADD mm32 FICOMP mm16 FICOMP mm32 FICOM mm16 FICOM mm32 FIDIVR mm16 FIDIVR mm32 FIDIV mm16 FIDIV mm32 FILD mm16 FILD mm32 FILD mm64 FIMUL mm16 FIMUL mm32 FINCSTP FINIT FISTP mm16 FISTP mm32 FISTP mm64 FIST mm16 FIST mm32 FISUBR mm16 FISUBR mm32 FISUB mm16 FISUB mm32 FLDCW mm16 FLDENV memg FLDLG2 FLDLN2 FLDL2E FLDL2T FLDPI FLDZ FLD1 FLD fpur FLD mm32 FLD mm64 FLD mm80 FMULP fpur FMULP fpur,ST0 FMUL FMUL fpur FMUL fpur,ST0 FMUL mm32 FMUL mm64 FMUL ST0,fpur FNCLEX FNDISI FNENI FNINIT FNOP FNSAVE memg FNSTCW mm16 FNSTENV memg FNSTSW AX FNSTSW mm16 FPATAN FPREM1 FPREM FPTAN FRNDINT FRSTOR memg FSAVE memg FSCALE FSETPM FSINCOS FSIN FSQRT FSTCW mm16 FSTENV memg FSTP fpur FSTP mm32 FSTP mm64 FSTP mm80 FSTSW AX FSTSW mm16 FST fpur FST mm32 FST mm64 FSUBP fpur FSUBP fpur,ST0 FSUBRP fpur FSUBRP fpur,ST0 FSUBR FSUBR fpur FSUBR fpur,ST0 FSUBR mm32 FSUBR mm64 FSUBR ST0,fpur FSUB fpur FSUB fpur,ST0 FSUB mm32 FSUB mm64 FSUB ST0,fpur FTST FUCOMIP fpur FUCOMIP ST0,fpur FUCOMI fpur FUCOMI ST0,fpur FUCOMPP D8 D8 DC D8 DC D8 9B DF DD DE DA DE DA DE DA DE DA DE DA DF DB DF DE DA D9 9B DF DB DF DF DB DE DA DE DA D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 DD DB DE DE DE D8 DC D8 DC D8 DB DB DB DB D9 DD D9 D9 DF DD D9 D9 D9 D9 D9 DD 9B D9 DB D9 D9 D9 9B 9B DD D9 DD DB 9B 9B DD D9 DD DE DE DE DE DE D8 DC D8 DC D8 D8 DC D8 DC D8 D9 DF DF DB DB DA F8+rg F0+rg F8+rg /6 /6 F0+rg DB E0 C0+rg C0+rg /0 /0 /3 /3 /2 /2 /0 /0 /6 /6 /0 /0 /5 /1 /1 F7 DB E3 /3 /3 /0 /2 /2 /5 /5 /4 /4 /5 /4 EC ED EA E9 EB EE E8 C0+rg /0 /0 /5 C8+rg C8+rg C9 C8+rg C8+rg /1 /1 C8+rg E2 E1 E0 E3 D0 /6 /0 /6 E0 /0 F3 F5 F8 F2 FC /4 DD /6 FD E4 FB FE FA D9 /0 D9 /6 D8+rg /3 /3 /0 DF E0 DD /0 D0+rg /2 /2 E8+rg E8+rg E0+rg E0+rg E1 E8+rg E0+rg /5 /5 E8+rg E0+rg E8+rg /4 /4 E0+rg E4 E8+rg E8+rg E8+rg E8+rg E9 FUCOMP fpur FUCOMP ST0,fpur FUCOM fpur FUCOM ST0,fpur FWAIT FXAM FXCH fpur FXCH fpur,ST0 FXCH ST0,fpur FXCH FXTRACT FYL2XP1 FYL2X F2XM1 HLT IBTS rm16,rg16 IBTS rm32,rg32 ICEBP IDIV rgm8 IDIV rm16 IDIV rm32 IMUL rgm8 IMUL rg16,ime8 IMUL rg16,im16 IMUL rg16,rm16 IMUL rg16,rm16,ime8 IMUL rg16,rm16,im16 IMUL rg32,ime8 IMUL rg32,im32 IMUL rg32,rm32 IMUL rg32,rm32,ime8 IMUL rg32,rm32,im32 IMUL rm16 IMUL rm32 INC rgm8 INC rg16 INC rg32 INC rm16 INC rm32 INSB INSD INSW INTO INT1 INT3 INT ime8 INVD INVLPG memg IN AL,DX IN AL,ime8 IN AX,DX IN AX,ime8 IN EAX,DX IN EAX,ime8 IRETD IRETW IRET JO immg JO_NEAR immg JNO immg JNO_NEAR immg JC immg JC_NEAR immg JB immg JB_NEAR immg JNAE immg JNAE_NEAR immg JNC immg JNC_NEAR immg JNB immg JNB_NEAR immg JAE immg JAE_NEAR immg JE immg JE_NEAR immg JZ immg JZ_NEAR immg JNE immg JNE_NEAR immg JNZ immg JNZ_NEAR immg JBE immg JBE_NEAR immg JNA immg JNA_NEAR immg JA immg JA_NEAR immg JNBE immg JNBE_NEAR immg JS immg JS_NEAR immg JNS immg JNS_NEAR immg JP immg JP_NEAR immg JPE immg JPE_NEAR immg JNP immg JNP_NEAR immg JPO immg JPO_NEAR immg JL immg JL_NEAR immg JNGE immg JNGE_NEAR immg JGE immg JGE_NEAR immg JNL immg JNL_NEAR immg JLE immg DD DD DD DD 9B D9 D9 D9 D9 D9 D9 D9 D9 D9 F4 o16 o32 F1 F6 o16 o32 F6 o16 o16 o16 o16 o16 o32 o32 o32 o32 o32 o16 o32 FE o16 o32 o16 o32 6C o32 o16 CE F1 CC CD 0F 0F EC E4 o16 o16 o32 o32 o32 o16 CF 70 0F 71 0F 72 0F 72 0F 72 0F 73 0F 73 0F 73 0F 74 0F 74 0F 75 0F 75 0F 76 0F 76 0F 77 0F 77 0F 78 0F 79 0F 7A 0F 7A 0F 7B 0F 7B 0F 7C 0F 7C 0F 7D 0F 7D 0F 7E E8+rg E8+rg E0+rg E0+rg E5 C8+rg C8+rg C8+rg C9 F4 F9 F1 F0 0F A7 /r 0F A7 /r /7 F7 /7 F7 /7 /5 6B /r 69 /r 0F AF 6B /r 69 /r 6B /r 69 /r 0F AF 6B /r 69 /r F7 /5 F7 /5 /0 40+rg 40+rg FF /0 FF /0 6D 6D ib 08 01 /0 ib ED E5 ib ED E5 ib CF CF rb 80 rb 81 rb 82 rb 82 rb 82 rb 83 rb 83 rb 83 rb 84 rb 84 rb 85 rb 85 rb 86 rb 86 rb 87 rb 87 rb 88 rb 89 rb 8A rb 8A rb 8B rb 8B rb 8C rb 8C rb 8D rb 8D rb r? r? r? r? r? r? r? r? r? r? r? r? r? r? r? r? r? r? r? r? r? r? r? r? r? r? ib iw /r ib iw ib id /r ib id 162 JLE_NEAR immg JNG immg JNG_NEAR immg JG immg JG_NEAR immg JNLE immg JNLE_NEAR immg JCXZ immg JECXZ immg JMP_FAR memg JMP_FAR memg JMP immg JMP immg:im16 JMP immg:im32 JMP rm16 JMP rm32 JMP_SHORT immg LAHF LAR rg16,rm16 LAR rg32,rm32 LDS rg16,memg LDS rg32,memg LEAVE LEA rg16,memg LEA rg32,memg LES rg16,memg LES rg32,memg LFS rg16,memg LFS rg32,memg LGDT memg LGS rg16,memg LGS rg32,memg LIDT memg LLDT rm16 LMSW rm16 LOADALL286 LOADALL LODSB LODSD LODSW LOOPE immg LOOPE immg,CX LOOPE immg,ECX LOOPNE immg LOOPNE immg,CX LOOPNE immg,ECX LOOPNZ immg LOOPNZ immg,CX LOOPNZ immg,ECX LOOPZ immg LOOPZ immg,CX LOOPZ immg,ECX LOOP immg LOOP immg,CX LOOP immg,ECX LSL rg16,rm16 LSL rg32,rm32 LSS rg16,memg LSS rg32,memg LTR rm16 MOVD mmxr,rm32 MOVD rm32,mmxr MOVQ mmxr,rm64 MOVQ rm64,mmxr MOVSB MOVSD MOVSW MOVSX rg16,rgm8 MOVSX rg32,rgm8 MOVSX rg32,rm16 MOVZX rg16,rgm8 MOVZX rg32,rgm8 MOVZX rg32,rm16 MOV abs8,AL MOV ab16,AX MOV ab32,EAX MOV AL,abs8 MOV AX,ab16 MOV creg,rg32 MOV dreg,rg32 MOV EAX,ab32 MOV reg8,ime8 MOV reg8,rgm8 MOV rgm8,ime8 MOV rgm8,reg8 MOV rg16,im16 MOV rg16,rm16 MOV rg32,creg MOV rg32,dreg MOV rg32,im32 MOV rg32,rm32 MOV rg32,treg MOV rm16,im16 MOV rm16,rg16 MOV rm16,segr MOV rm32,im32 MOV rm32,rg32 MOV rm32,segr MOV segr,rm16 MOV segr,rm32 MOV treg,rg32 MUL rgm8 MUL rm16 MUL rm32 NEG rgm8 NEG rm16 NEG rm32 NOP NOT rgm8 NOT rm16 0F 8E r? 7E rb 0F 8E r? 7F rb 0F 8F r? 7F rb 0F 8F r? o16 E3 rb o32 E3 rb o16 FF /5 o32 FF /5 E9 r? o16 EA iw o32 EA id o16 FF /4 o32 FF /4 EB rb 9F o16 0F 02 o32 0F 02 o16 C5 /r o32 C5 /r C9 o16 8D /r o32 8D /r o16 C4 /r o32 C4 /r o16 0F B4 o32 0F B4 0F 01 /2 o16 0F B5 o32 0F B5 0F 01 /3 0F 00 /2 0F 01 /6 0F 05 0F 07 AC o32 AD o16 AD E1 rb a16 E1 rb a32 E1 rb E0 rb a16 E0 rb a32 E0 rb E0 rb a16 E0 rb a32 E0 rb E1 rb a16 E1 rb a32 E1 rb E2 rb a16 E2 rb a32 E2 rb o16 0F 03 o32 0F 03 o16 0F B2 o32 0F B2 0F 00 /3 0F 6E /r 0F 7E /r 0F 6F /r 0F 7F /r A4 o32 A5 o16 A5 o16 0F BE o32 0F BE o32 0F BF o16 0F B6 o32 0F B6 o32 0F B7 A2 o? o16 A3 o? o32 A3 o? A0 o? o16 A1 o? 0F 22 /r 0F 23 /r o32 A1 o? B0+rg ib 8A /r C6 /0 ib 88 /r o16 B8+rg o16 8B /r 0F 20 /r 0F 21 /r o32 B8+rg o32 8B /r 0F 24 /r o16 C7 /0 o16 89 /r o16 8C /r o32 C7 /0 o32 89 /r o32 8C /r o16 8E /r o32 8E /r 0F 26 /r F6 /4 o16 F7 /4 o32 F7 /4 F6 /3 o16 F7 /3 o32 F7 /3 90 F6 /2 o16 F7 /2 iw iw /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r iw id iw id NOT rm32 OR AL,ime8 OR AX,im16 OR EAX,im32 OR reg8,rgm8 OR rgm8,ime8 OR rgm8,reg8 OR rg16,rm16 OR rg32,rm32 OR rm16,ime8 OR rm16,im16 OR rm16,rg16 OR rm32,ime8 OR rm32,im32 OR rm32,rg32 OUTSB OUTSD OUTSW OUT DX,AL OUT DX,AX OUT DX,EAX OUT ime8,AL OUT ime8,AX OUT ime8,EAX PACKSSDW mmxr,rm64 PACKSSWB mmxr,rm64 PACKUSWB mmxr,rm64 PADDB mmxr,rm64 PADDD mmxr,rm64 PADDQ mmxr,rm64 PADDSB mmxr,rm64 PADDSW mmxr,rm64 PADDUSB mmxr,rm64 PADDUSW mmxr,rm64 PADDW mmxr,rm64 PANDN mmxr,rm64 PAND mmxr,rm64 PCMPEQB mmxr,rm64 PCMPEQD mmxr,rm64 PCMPEQW mmxr,rm64 PCMPGTB mmxr,rm64 PCMPGTD mmxr,rm64 PCMPGTW mmxr,rm64 PMADDWD mmxr,rm64 PMULHW mmxr,rm64 PMULLW mmxr,rm64 POPAD POPAW POPA POPFD POPFW POPF POP DS POP ES POP FS POP GS POP rg16 POP rg32 POP rm16 POP rm32 POP SS POR mmxr,rm64 PSLLD mmxr,ime8 PSLLD mmxr,rm64 PSLLQ mmxr,ime8 PSLLQ mmxr,rm64 PSLLW mmxr,ime8 PSLLW mmxr,rm64 PSRAD mmxr,ime8 PSRAD mmxr,rm64 PSRAW mmxr,ime8 PSRAW mmxr,rm64 PSRLD mmxr,ime8 PSRLD mmxr,rm64 PSRLQ mmxr,ime8 PSRLQ mmxr,rm64 PSRLW mmxr,ime8 PSRLW mmxr,rm64 PSUBB mmxr,rm64 PSUBD mmxr,rm64 PSUBSB mmxr,rm64 PSUBSW mmxr,rm64 PSUBUSB mmxr,rm64 PSUBUSW mmxr,rm64 PSUBW mmxr,rm64 PUNPCKHBW mmxr,rm64 PUNPCKHDQ mmxr,rm64 PUNPCKHWD mmxr,rm64 PUNPCKLBW mmxr,rm64 PUNPCKLDQ mmxr,rm64 PUNPCKLWD mmxr,rm64 PUSHAD PUSHAW PUSHA PUSHFD PUSHFW PUSHF PUSH CS PUSH DS PUSH ES PUSH FS PUSH GS PUSH ime8 PUSH im16 PUSH im32 PUSH rg16 PUSH rg32 PUSH rm16 PUSH rm32 PUSH SS o32 0C o16 o32 0A 80 08 o16 o32 o16 o16 o16 o32 o32 o32 6E o32 o16 EE o16 o32 E6 o16 o32 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F o32 o16 61 o32 o16 9D 1F 07 0F 0F o16 o32 o16 o32 17 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F o32 o16 60 o32 o16 9C 0E 1E 06 0F 0F 6A o16 o32 o16 o32 o16 o32 16 F7 ib 0D 0D /r /1 /r 0B 0B 83 81 09 83 81 09 /2 iw id ib /r /r /1 /1 /r /1 /1 /r ib iw ib id 6F 6F EF EF ib E7 E7 6B 63 67 FC FE D4 EC ED DC DD FD DF DB 74 76 75 64 66 65 F5 E5 D5 61 61 ib ib /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r /r 9D 9D A1 A9 58+rg 58+rg 8F /0 8F /0 EB 72 F2 73 F3 71 F1 72 E2 71 E1 72 D2 73 D3 71 D1 F8 FA E8 E9 D8 D9 F9 68 6A 69 60 62 61 60 60 /r /6 /r /6 /r /6 /r /4 /r /4 /r /2 /r /2 /r /2 /r /r /r /r /r /r /r /r /r /r /r /r /r /r 9C 9C A0 A8 ib 68 iw 68 id 50+rg 50+rg FF /6 FF /6 ib ib ib ib ib ib ib ib PXOR mmxr,rm64 RCL rgm8,CL RCL rgm8,ime8 RCL rgm8,1 RCL rm16,CL RCL rm16,ime8 RCL rm16,1 RCL rm32,CL RCL rm32,ime8 RCL rm32,1 RCR rgm8,CL RCR rgm8,ime8 RCR rgm8,1 RCR rm16,CL RCR rm16,ime8 RCR rm16,1 RCR rm32,CL RCR rm32,ime8 RCR rm32,1 RDMSR RDPMC RDTSC RETF im16 RETF RETN im16 RETN RET im16 RET ROL rgm8,CL ROL rgm8,ime8 ROL rgm8,1 ROL rm16,CL ROL rm16,ime8 ROL rm16,1 ROL rm32,CL ROL rm32,ime8 ROL rm32,1 ROR rgm8,CL ROR rgm8,ime8 ROR rgm8,1 ROR rm16,CL ROR rm16,ime8 ROR rm16,1 ROR rm32,CL ROR rm32,ime8 ROR rm32,1 RSM SAHF SALC SAL rgm8,CL SAL rgm8,ime8 SAL rgm8,1 SAL rm16,CL SAL rm16,ime8 SAL rm16,1 SAL rm32,CL SAL rm32,ime8 SAL rm32,1 SAR rgm8,CL SAR rgm8,ime8 SAR rgm8,1 SAR rm16,CL SAR rm16,ime8 SAR rm16,1 SAR rm32,CL SAR rm32,ime8 SAR rm32,1 SBB AL,ime8 SBB AX,im16 SBB EAX,im32 SBB reg8,rgm8 SBB rgm8,ime8 SBB rgm8,reg8 SBB rg16,rm16 SBB rg32,rm32 SBB rm16,ime8 SBB rm16,im16 SBB rm16,rg16 SBB rm32,ime8 SBB rm32,im32 SBB rm32,rg32 SCASB SCASD SCASW SETO rgm8 SETNO rgm8 SETC rgm8 SETB rgm8 SETNAE rgm8 SETNC rgm8 SETNB rgm8 SETAE rgm8 SETE rgm8 SETZ rgm8 SETNE rgm8 SETNZ rgm8 SETBE rgm8 SETNA rgm8 SETA rgm8 SETNBE rgm8 SETS rgm8 SETNS rgm8 SETP rgm8 SETPE rgm8 SETNP rgm8 SETPO rgm8 SETL rgm8 SETNGE rgm8 SETGE rgm8 SETNL rgm8 0F D2 C0 D0 o16 o16 o16 o32 o32 o32 D2 C0 D0 o16 o16 o16 o32 o32 o32 0F 0F 0F CA CB C2 C3 C2 C3 D2 C0 D0 o16 o16 o16 o32 o32 o32 D2 C0 D0 o16 o16 o16 o32 o32 o32 0F 9E D6 D2 C0 D0 o16 o16 o16 o32 o32 o32 D2 C0 D0 o16 o16 o16 o32 o32 o32 1C o16 o32 1A 80 18 o16 o32 o16 o16 o16 o32 o32 o32 AE o32 o16 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F EF /2 /2 /2 D3 C1 D1 D3 C1 D1 /3 /3 /3 D3 C1 D1 D3 C1 D1 32 33 31 iw /r ib /2 /2 ib /2 /2 /2 ib /2 ib /3 /3 ib /3 /3 /3 ib /3 iw iw /0 /0 /0 D3 C1 D1 D3 C1 D1 /1 /1 /1 D3 C1 D1 D3 C1 D1 AA /4 /4 /4 D3 C1 D1 D3 C1 D1 /0 /0 /0 D3 C1 D1 D3 C1 D1 ib 1D 1D /r /3 /r 1B 1B 83 81 19 83 81 19 AF AF 90 91 92 92 92 93 93 93 94 94 95 95 96 96 97 97 98 99 9A 9A 9B 9B 9C 9C 9D 9D ib /0 /0 ib /0 /0 /0 ib /0 ib /1 /1 ib /1 /1 /1 ib /1 ib /4 /4 ib /4 /4 /4 ib /4 ib /0 /0 ib /0 /0 /0 ib /0 iw id ib /r /r /3 /3 /r /3 /3 /r /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 /2 ib iw ib id SETLE rgm8 SETNG rgm8 SETG rgm8 SETNLE rgm8 SGDT memg SHLD rm16,rg16,CL SHLD rm16,rg16,ime8 SHLD rm32,rg32,CL SHLD rm32,rg32,ime8 SHL rgm8,CL SHL rgm8,ime8 SHL rgm8,1 SHL rm16,CL SHL rm16,ime8 SHL rm16,1 SHL rm32,CL SHL rm32,ime8 SHL rm32,1 SHRD rm16,rg16,CL SHRD rm16,rg16,ime8 SHRD rm32,rg32,CL SHRD rm32,rg32,ime8 SHR rgm8,CL SHR rgm8,ime8 SHR rgm8,1 SHR rm16,CL SHR rm16,ime8 SHR rm16,1 SHR rm32,CL SHR rm32,ime8 SHR rm32,1 SIDT memg SLDT rm16 SMI SMSW rm16 STC STD STI STOSB STOSD STOSW STR rm16 SUB AL,ime8 SUB AX,im16 SUB EAX,im32 SUB reg8,rgm8 SUB rgm8,ime8 SUB rgm8,reg8 SUB rg16,rm16 SUB rg32,rm32 SUB rm16,ime8 SUB rm16,im16 SUB rm16,rg16 SUB rm32,ime8 SUB rm32,im32 SUB rm32,rg32 SYSENTER SYSEXIT TEST AL,ime8 TEST AX,im16 TEST EAX,im32 TEST rgm8,ime8 TEST rgm8,reg8 TEST rm16,im16 TEST rm16,rg16 TEST rm32,im32 TEST rm32,rg32 UD1 UD2 UMOV reg8,rgm8 UMOV rgm8,reg8 UMOV rg16,rm16 UMOV rg32,rm32 UMOV rm16,rg16 UMOV rm32,rg32 VERR rm16 VERW rm16 WAIT WBINVD WRMSR XADD rgm8,reg8 XADD rm16,rg16 XADD rm32,rg32 XBTS rg16,rm16 XBTS rg32,rm32 XCHG AX,rg16 XCHG EAX,rg32 XCHG reg8,rgm8 XCHG rgm8,reg8 XCHG rg16,AX XCHG rg16,rgm8 XCHG rg32,EAX XCHG rg32,rm32 XCHG rm16,rg16 XCHG rm32,rg32 XLATB XOR AL,ime8 XOR EAX,im32 XOR AX,im16 XOR reg8,rgm8 XOR rgm8,ime8 XOR rgm8,reg8 XOR rg16,rm16 XOR rg32,rm32 XOR rm16,ime8 XOR rm16,im16 XOR rm16,rg16 XOR rm32,ime8 XOR rm32,im32 XOR rm32,rg32 0F 0F 0F 0F 0F o16 o16 o32 o32 D2 C0 D0 o16 o16 o16 o32 o32 o32 o16 o16 o32 o32 D2 C0 D0 o16 o16 o16 o32 o32 o32 0F 0F F1 0F F9 FD FB AA o32 o16 0F 2C o16 o32 2A 80 28 o16 o32 o16 o16 o16 o32 o32 o32 0F 0F A8 o16 o32 F6 84 o16 o16 o32 o32 0F 0F 0F 0F o16 o32 o16 o32 0F 0F 9B 0F 0F 0F o16 o32 o16 o32 o16 o32 86 86 o16 o16 o32 o32 o16 o32 D7 34 o32 o16 32 80 30 o16 o32 o16 o16 o16 o32 o32 o32 9E 9E 9F 9F 01 0F 0F 0F 0F /4 /4 /4 D3 C1 D1 D3 C1 D1 0F 0F 0F 0F /5 /5 /5 D3 C1 D1 D3 C1 D1 01 00 /2 /2 /2 /2 /0 A5 A4 A5 A4 /r /r ib /r /r ib ib /4 /4 /4 /4 /4 /4 AD AC AD AC ib ib /r /r ib /r /r ib ib /5 /5 ib /5 /5 /5 ib /5 /1 /0 01 /4 AB AB 00 ib 2D 2D /r /5 /r 2B 2B 83 81 29 83 81 29 34 36 ib A9 A9 /7 /r F7 85 F7 85 B9 0B 12 10 0F 0F 0F 0F 00 00 /1 iw id ib /r /r /5 /5 /r /5 /5 /r ib id iw id ib /7 iw /r /7 id /r /r /r 13 13 11 11 /4 /5 09 30 C0 /r 0F C1 0F C1 0F A6 0F A6 90+rg 90+rg /r /r 90+rg 87 /r 90+rg 87 /r 87 /r 87 /r ib 35 35 /r /6 /r 33 33 83 81 31 83 81 31 ib iw /r /r /r /r /r /r /r /r id iw ib /r /r /6 /6 /r /6 /6 /r ib iw ib id 163 17.6. Parsiranje instrukcije Tipična instrukcija u asemblerskom jeziku je oblika LABELA: OPCODE ARG1,ARG2,ARG3 ; KOMENTAR pri čemu se često argumenti mogu izostaviti. Početni dio najvažnije funkcije u asembleru GenerateHexInstruction, koja prevodi liniju u mašinski kod u heksadecimalnom formatu izdvaja ove elemente u posebne varijable. Pored toga, unutar instrukcije se mogu nalaziti prefiksi za segmente i modifikatori kao što su NEAR i FAR. Ove prefikse i modifikatore treba izdvojiti iz instrukcije. Izdvajanje dijelova asemblerske instrukcije u posebne varijable se može raditi sintaksnom analizom ili, što je ovdje primijenjeno jer je struktura asemblerskih instrukcija jednostavna korištenjem funkcije pos za traženje stringa na željenoj poziciji. To radi funkcija Izdvoji, čiji je prvi argument varijabla u koju će se smjestiti željeni dio stringa nakon parsiranja, a drugi je znak do kojeg se vrši izdvajanje. Treba još obraditi nekoliko specijalnih slučajeva, jer se labela kod instrukcija db, dw i dq ne završava dvotačkom, pa pogrešno biva prepoznata kao operacioni kod. Ti specijalni slučajevi se rješavaju naknadnim promjenama i zamjenama varijabli. Pronađene labele se smještaju u posebnu tabelu koja se zove labele. Tu se smješta ime labele i njena vrijednost, te vrsta. Nakon svake generisane instrukcije uvećava se trenutna pozicija i ova pozicija predstavlja vrijednost aktuelne labele. Ukupno postoje tri takve pozicije za code, data i stack segment. 17.7. Prepoznavanje adresnih režima Izdvajanjem argumenata potrebno je prepoznati njegov adresni režim. Pentium II, kako se vidjelo u opisu tabele ima dosta različitih adresnih režima. Da stvar bude složenija, oni se razlikuju zavisno od toga da li asembler generiše prevedeni kod u 16 bitnom ili 32-bitnom režimu. Prepoznavanje, unutar funkcije ParseOp, se može obaviti pravljenjem sintaksnog dijagrama i zatim odgovarajućih procedura, ali je u cilju smanjenja veličine samog asemblera primijenjen malo drugačiji pristup. Provjerava se da li pojedini pripada jednom od navedenih uzoraka na slici. [A*B+C+D] -> tip:=13 [A+B*C+D] -> tip:=14 [A+B+C*D] -> tip:=15 [A*B+C-D] -> tip:=16 [A+B*C-D] -> tip:=17 [A-B+C*D] -> tip:=18 [A*B-C+D] -> tip:=19 [A*B+C] -> tip:=11 [A+B+C] -> tip:=10 [A*B-C] -> tip:=20 [A+B-C] -> tip:=21 [A-B+C] -> tip:=22 [A+B*C] -> tip:=12 [A*B] -> tip:=9 [A+B] -> tip:=8 [A-B] -> tip:=23 A[B*C+D] -> tip:=5 A[B*C-D] -> tip:=24 A[B+C*D] -> tip:=6 A[B*C] -> tip:=4 A[B+C] -> tip:=3 A[B-C] -> tip:=25 A[B] -> tip:=2 [A] -> tip:=7 A -> tip:=1 ; Sl. 17.7.1. Uzorci argumenata Tako na primjer, argument koji glasi [EAX*4+EBX-15] je tipa 16. Ovo prepoznavanje je takođe urađeno pomoću pos naredbe, a moglo se i sintaksnom analizom. Funkcija uzorak provjerava da li se string slaže sa navedenim uzorkom i puni varijable A, B, C i D odgovarajućim stringovima. Tako na primjer Uzorak('[A*B+C-D]','[EAX*4+EBX-15]') će vratiti true i napuniti varijablu A vrijednošću EAX, varijablu B vrijednošću 4, varijablu C vrijednošću EBX i varijablu D vrijednošću 15. Broj mogućih slučajeva je još uvijek preveliki pa je sada potrebno praviti ekvivalentne. Tako na primjer tipovi 5 i 18 se mogu svesti na tip 13 zamjenom odgovarajućih varijabli. Svi se tipovi argumenata na kraju svedu na jedan od mogućih tipova: 1, 7, 8, 10, 11 i 13. No i ovo je još uvijek mnogo. Naime, argument [EAX*4+EBX+15] (tip 13) se može pisati na četiri načina: [EAX*4+EBX+15] ili [4*EAX+EBX+15] ili [EAX*4+15+EBX] ili [4*EAX+15+EBX] Stoga, treba sortirati registre i konstante tako da se vrijednosti koje nisu registri stave na kraj argumenta. Prilikom ovog sortiranja se pored ovoga adresiranja koja uključuju zbir registara BX/BP sa SI/DI takođe sortiraju da registri BX, odnosno BP dođu na početak argumenta. Postoje još dva specijalna slučaja: kada navedena labela zapravo predstavlja čitanje s memorijske lokacije (sintaksa MOV AX,VRIJEDNOST zapravo se treba shvatiti kao MOV AX,[VRIJEDNOST]), te kada se slučaj [A+B] svodi na slučaj [A] ukoliko su A i B konstante. 17.8. Proračun modrm , SIB i deplasmana Prepoznati tip argumenta sada treba prevesti u njegovo značenje. Za svaki od navedenih tipova postoje procedure koje se zovu Obrada1, Obrada7, Obrada8, Obrada10, Obrada11 i Obrada13. U okviru ovih procedura se gleda da li je pojedini od dijelova argumenta registar ili konstanta. Registar se prepoznaje funkcijom Regcode. Kada su prepoznati svi elementi , tada se u slog tipa Toperand upiše izračunata vrijednost bajta ModRM i bajta SIB. 164 Ukoliko je argument labela mora se pretražiti i u tabeli labela i naći njena vrijednost, čime se dalje ponaša kao da je u pitanju konstanta. Vrijednosti dijelova argumenata koji predstavljaju konstante, deplasmane ili memorijske adrese smještaju se u polja disp8, disp16 ili disp32 zavisno od njihove veličine. 17.9. Punjenje i pretraživanje tabele instrukcija Tabela instrukcija se prije početka asembliranja kompletna učita u memoriju i sortira. Unutar funkcije GenerateHexInstruction se zatim poziva funkcija MakeOps unutar koje se poziva funkcija ParseOp. Zavisno od vrste argumenta zaključi se da li je riječ o osmobitnom registru (reg8), šesnaestbitnom registru (reg16), itd. kako je navedeno u tabeli u poglavlju 17.3. Argument može da se posmatra u više različitih konteksta. Tako na primjer kod instrukcije MOV EAX,[EBX] za prvi argument važe konteksti: EAX rg32 rm32 a za drugi argument važe konteksti: memg mem8 mm16 mm32 mm64 mm80 rgm8 rm16 rm32 rm64 Sada je moguće pripremiti sve kombinacije argumenata, kao što su MOV EAX,memg MOV EAX,mem8 .... MOV EAX,rm34 MOV rg32,memg MOV rg32,mem8 ... MOV rm32,rm64 Nakon pripreme svih kombinacija operacionog koda i argumenata, slijedi binarno pretraživanje kroz tabelu. U tabeli se pronalazi kao regularna kombinacija MOV rg32,rm32 o32 8B /r 17.10. Generisanje heksadekadnog koda Nakon pronalaska vrijednosti u tabeli generiše se heksadekadni kod prema uputama iz tabele. U primjeru o32 8B /r se najprije generišu bajtovi 67 i 66 zavisno od oblika operanada. Nakon toga se generiše prosto bajt 8B. Oznaka /r znači da se mora prethodno zaključiti od kojeg argumenta se uzima ModRm, a od kojeg kod registra( u primjeru MOV EAX,[EBX] argument EAX predstavlja registar, a argument [EBX] definiše ModRM). Tako se kreira konačni ModRm, čime je instrukcija prevedena u heksadekadni oblik 17.11. Numeričke konstante Prilikom generisanja heksadekadnog koda instrukcije, dio argumenata su numeričke konstante ili labele. Ako se utvrdi da je riječ o labeli, vrši se pretraga kroz tabelu labela i uzima njena vrijednost, čime se problem svodi na evaluaciju numeričkih konstanti. Dvije su vrste numeričkih konstanti, cjelobrojne i realne. Tehnika prevođenja cjelobrojnih konstanti je već izučena u poglavljima kompajlera, što se izvodi uzastopnim množenjem sa 10. Jedina specifičnost je što asemblerski programi koriste i heksadekadni i binarni brojni sistem. Stoga se u funkciji EvaluirajBroj provjerava da li se na kraju ASCII reprezentacije broja nalazi oznaka ‘b’ odnosno ‘h’, čime se konstanta kojom se uzastopno množi mijenja u 2, odnosno 16. U šestoj verziji kompajlera FILDZAN-32 pretvaranje realnog broja u binarni format prepušteno je asembleru. To znači da se sada mora pozabaviti konverzijom realnog broja iz ASCII reprezentacije u četvorobajtni, osmobajtni ili desetobajtni IEEE format. To je realizovano funkcijom StrToFloat2. Format realnog broja je prilično mašinski ovisan. Za razliku od dekadnih brojeva, pored uzastopnog množenja sa 10 za svaku cifru, broj se mora normalizovati ponovnim množenjem ili dijeljenjem mantise sa 10 i uvećavanjem, odnosno umanjivanjem eksponenta. Pored svega toga, potrebno je prevesti ga u binarni format, i zatim spakovati iznose, kako Intel zahtijeva. Realizovati ovo potpuno u višem programskom jeziku rezultuje velikim numeričkim greškama. U cilju skraćenja asemblera (a po cijenu smanjenja njegove portabilnosti, ali da li je ona bitna za asembler?) množenje sa 10 i konverzija u binarni format (u suštini prosta FSTP instrukcija) realizovana je ugniježđenim asemblerom. 17.12. Pseudoinstrukcije, prefiksi i modifikatori Određene instrukcije se ne nalaze u tabeli. To su instrukcije DD, DW, DB, DQ, DT, END, PUBLIC, .486 itd. To su standardne asemblerske pseudoinstrukcije. Ovaj asembler je po izboru standardnih instrukcija bogat, jer pokriva cijeli skup Pentiuma II, dok mnogi PC asembleri završavaju sa procesorom 486. Međutim, nije implementirano mnogo pseudoinstrukcija (nedostaju makroinstrukcije, pa čak i obična ORG instrukcija). Ove se istrukcije prepoznaju funkcijom IsPseudo, a generisanje koda za njih procedurom DoPseudo. 165 Prilikom prepoznavanja instrukcije se provjeri da li ona sadrži prefikse kao što su ES:, CS:, SS:, ... REP itd. Ako sadrže, treba generisati odgovarajući kod i za njih. Modifikatori kao što su NEAR i FAR se zamjenjuju njihovim dodavanjem na kraj operacionog koda instrukcije uz pomoć znaka podvlačilice. 17.13. Prvi prolaz Sada kada je realizovano prevođenje pojedinačne instrukcije, što je i najteži dio posla, može se prevesti cijeli program. Između asemblerskih instrukcija nema velike međuzavisnosti, kakva postoji između instrukcija u programskim jezicima visokog nivoa, tako da kada je realizovano prevođenje jedne instrukcije, prevođenje cijelog programa je lagan zadatak. Ipak, labele predstavljaju problem jer se instrukcije često referenciraju na labele koje još nisu definisane. Stoga je potrebno dva puta proći kroz izvornu datoteku. U prvom prolazu se dođe do heksadecimalne vrijednosti instrukcije i puni se tabela labela prilikom svake generisane labele, ali se heksadecimalna vrijednost intrukcije nigdje ne upisuje. 17.14. Drugi prolaz i generisanje koda U drugom prolazu se generiše 5 datoteka: Datoteka sa ekstenzijom .COD koja sadrži generisani kod iz CODE segmenta Datoteka sa ekstenzijom .DAT koja sadrži generisane podatke iz DATA segmenta Datoteka sa ekstenzijom .STA koja sadrži generisani kod iz STACK segmenta Datoteka sa ekstenzijom .LAB koja sadrži spisak labela Datoteka sa ekstenzijom .PAT koja sadrži popravke, tj. adrese na kojima se referencira pojedina labela Cijeli asembler se starta naredbom ASEM ime.asm /d za 16-bitno, DOS asembliranje ASEM ime.asm /w za 32-bitno, Windows asembliranje 17.15. Izvršna verzija Sa ovim asemblerom je dobijen mašinski kod ali treba još učiniti stvari da bi on bio izvršni na DOS ili Windows operativnom sistemu. Mašinski kod je u linearnom formatu. U nekim drugim slučajevima, ovaj format je najbolji. To su recimo loaderi operativnih sistema. To je prirodni format i pokazuje mašinski jezik onakav kakav on zaista jeste, ali ima svoje nedostatke. U slučaju DOS-a, on je ograničen na veličinu segmenta od 64 K U slučaju Windowsa, tog ograničenja nema, ali nije moguće povezati program sa dinamičkim bibliotekama. DOS programi generisani ovim asemblerom se mogu učitati i startati ukoliko nemaju podataka u DATA segmentu prostim preimenovanjem datoteke sa ekstenzijom .COD u datoteku sa ekstenzijom .COM. U slučaju da ima podataka u DATA segmentu i ako asemblerski program počinje sa MOV AX,CS ADD AX,<duzina CODE segmenta DIV 16 +1> MOV DS,AX Tada se mogu spojiti datoteke sa ekstenzijom COD i DAT u jedinstveni COM program, pri čemu se DAT datoteka smješta na prvu poziciju djeljivu sa 16 od početka COM datoteke iza iskopirane COD datoteke. Pored ovog zahvata potrebno je provjeriti PAT datoteku ukoliko se referiše program na podatke i promijeniti adrese u programu. Međutim, ovo nije primjenjivo za Windows programe, što je primarni zadatak ovog asemblera. Potrebno je sada konvertovati program u takav format da ga može razumjeti standardni linker. Stoga je sljedeći logičan korak je generisanje COFF objektnog formata (ekstenzija OBJ). Ovaj format sadrži mašinski kod, ali i sve potrebne informacije da bi linker mogao da poveže modul sa drugim modulima praveći izvršni EXE program. U tu svrhu su pripremljene tabele labela i tabele popravki . Sve informacije postoje, samo ih je potrebno upakovati prema standardima. U prilogu je dat listing cijelog asemblera. 166 17.16. Listing Asemblera Program asem; Type TLabTip = (lEqu, lprog, ldata, lextrn); TDsize = (d8, d16, d32, d64, d80); TLabela = Record labime: string[40]; labtip: TLabTip; labval: longint; labdsize: TDsize; End; texists=(exmodrm,exsib,exdisp8, exdisp16, exdisp32, exreg, exkind, exsegment); TOperand = Record existv: Set Of texists; datasizes: Set Of TDsize; adrsizes: Set Of TDsize; modrm: byte; sib: byte; disp8: byte; disp16: word; disp32: longint; segnum: word; reg: byte; kind: integer; End; toptable = Record instr: string[35]; gencod: string[20]; End; n := -n; greska := True; n := n - 1; End; negative := True; End; End last := length(br); Else If baza <> 10 Then last := last - 1; negative := False; While i <= last Do Begin st := IntToStr(n, 16); z := br[i]; While length(st)<digits Do st:= '0' + st; c := 16; If negative Then If (z >= '0') and (z <= '9') Then Begin c := Ord(z) - Ord('0'); For i := 1 To length(st) Do Begin If (z >= 'a') and (z <= 'f') Then Case st[i] Of c := Ord(z) - Ord('a') + 10; '0': st[i] := 'F'; If (z >= 'A') and (z <= 'F') Then '1': st[i] := 'E'; c := Ord(z) - Ord('A') + 10; '2': st[i] := 'D'; If c >= baza Then greska := True; '3': st[i] := 'C'; rez := rez * baza + c; '4': st[i] := 'B'; i := i + 1; '5': st[i] := 'A'; End; '6': st[i] := '9'; If greska Then rez := 0; '7': st[i] := '8'; Evaluirajbroj := p * rez; '8': st[i] := '7'; End; '9': st[i] := '6'; 'A': st[i] := '5'; Procedure UpisiIzlaz(outst: string); 'B': st[i] := '4'; Var 'C': st[i] := '3'; i: integer; 'D': st[i] := '2'; b: byte; 'E': st[i] := '1'; g: boolean; 'F': st[i] := '0'; Begin End; For i:=0 To(length(outst)div2)-1 Do Begin End; b := evaluirajbroj('0' + copy(outst, Var End; i * 2 + 1, 2) + 'H', g); labele: Array[1..10000] Of TLabela; inttohex := st; If prolaz = 2 Then optable: Array[1..2000] Of TOptable; End; Case actseg Of FPValue: Array[1..10] Of char; 1: Write(izlazcode, b); brlabela, actseg: integer; Function nadjilabelu(ime: string): integer; 2: Write(izlazdata, b); skok, dummyb: boolean; Var 3: Write(izlazstack, b); maxopcode, prolaz, dummy: integer; i: integer; End; pozicija: Array[1..3] Of longint; Begin End; patstr: string; nadjilabelu := -1; End; ulaz, izlazlab, izlazpat: Text; For i := 1 To brlabela Do izlazcode, izlazdata, izlazstack: File Of If ime = labele[i].labime Then Begin Function regcode(reg: string; Var kind: byte; nadjilabelu := i; integer): integer; End Const Function trim(st: string): string; End; Registers: Array[0..8, 0..7] Of string = Begin (('AL','CL','DL','BL','AH','CH','DH','BH'), While (st <> '') and (st[1] = ' ') Do Procedure upisilabelu(ime: string; adresa: ('AX','CX','DX','BX','SP','BP','SI','DI'), st := copy(st, 2, length(st)); integer; ('EAX','ECX','EDX','EBX','ESP','EBP','ESI', While (st <> '') and (st[length(st)] = ' lt: TLabtip; ds: TDSize); 'EDI'), ') Do Var ('CR0','***','CR2','CR3','CR4','***','***', st := copy(st, 1, length(st) - 1); p: integer; '***'), TRIM := ST; Begin ('DR0','DR1','DR2','DR3','***','***','DR6', End; p := NadjiLabelu(ime); 'DR7'), If p = -1 Then ('TR0','TR1','TR2','TR3','TR4','TR5','TR6', Function uppercase(st: string): string; Begin 'TR7'), Var brlabela := brlabela + 1; ('ES','CS','SS','DS','FS','GS',’***','***') i: integer; p := brlabela; ,('ST0','ST1','ST2','ST3','ST4','ST5','ST6' Begin End; ,'ST7'), For i := 1 To length(st) Do With labele[p] Do Begin ('MMX0','MMX1','MMX2','MMX3','MMX4','MMX5', If(st[i]>= 'a') and (st[i] <= 'z') Then labime := ime; 'MMX6', 'MMX7')); st[i] := chr(Ord(st[i]) - 32); labtip := lt; Var uppercase := st; labval := adresa; i, j: integer; End; labdsize := ds; Begin End; reg := uppercase(reg); Function IntToStr(n: longint; base: End; If copy(reg, 1, 3) = 'ST(' Then cardinal): string; reg := 'ST' + copy(reg, 4, 1); Var Function EvaluirajBroj(br: string; If copy(reg, 1, 4) = 'MMX(' Then st, c, pr: string; Var Greska: boolean): longint; reg := 'MMX' + copy(reg, 4, 1); ev: cardinal; Var For i := 0 To 8 Do Begin i, p, c, baza, last, rez: longint; For j := 0 To 7 Do If (base = 10) and (n < 0) Then Begin z: char; If registers[i, j] = reg Then Begin pr := '-'; Begin regcode := j; n := -n; Greska := False; kind := i; End rez := 0; exit; Else i := 1; End; pr := ''; If br = '' Then Begin regcode := -1; ev := n; EvaluirajBroj := 0; kind := -1; c := '0123456789ABCDEF'; greska := True; End; If ev = 0 Then st := '0' exit; Else End; Procedure deplasmani(Var op: TOperand; st := ''; If not (br[1] in ['0'..'9', '-']) Then broj: longint; While ev > 0 Do Begin greska := True; predzn: boolean); st := c[(ev mod base) + 1] + st; If (br[1] = '-')and(length(br) > 1) Then Begin ev := ev div base; Begin op.existv := op.existv + [exdisp32]; End; p := -1; op.disp32 := broj; IntToStr := pr + st; i := i + 1 If (predzn and (op.disp32 < 32768) and End; End (op.disp32>-32769))or(not (predzn) and Else (op.disp32<65536)and(op.disp32 >= 0)) Then Function inttohex(n, digits: longint): p := 1; Begin string; Case br[length(br)] Of op.existv := op.existv + [exdisp16]; Var 'o', 'O': baza := 8; op.disp16 := op.disp32; st: string; 'b', 'B': baza := 2; End; negative: boolean; 'h', 'H': baza := 16; If (predzn and (op.disp32 < 128) and i: integer; '0'..'9': baza := 10 (op.disp32>-129)) or(not (predzn) and Begin Else Begin (op.disp32 < 256) and (op.disp32 >= 0)) If n < 0 Then Begin baza := 0; Then Begin 167 op.existv := op.existv + [exdisp8]; op.disp8 := op.disp32; End; End; + 1, length(st)); If n2<>-1 Then Begin If kind <> 1 Then Greska := True Else {[bx+si],[bx+di],[bp+si],[bp+di]} Procedure Obrada1; { Slucaj A } If (n = 3) and (n2 = 6) Then Procedure ResolveDisp(Var disp, unknown: Begin setmod(0 * 64 + 0) string); n := regcode(A, kind); Else If (n = 3) and (n2 = 7) Then Var If n<>-1 Then Begin setmod(0 * 64 + 1) kind: integer; op.existv := op.existv + [exreg]; Else If (n = 5) and (n2 = 6) Then greska: boolean; op.reg := n; setmod(0 * 64 + 2) n: longint; op.kind := kind; Else If (n = 5) and (n2 = 7) Then Begin If kind in[0,1,2]Then SetMod(3*64+n); setmod(0 * 64 + 3) unknown := ''; Case kind Of Else If regcode(disp, kind)<>-1 Then exit; 0: op.datasizes := [d8]; Greska := True; dummy := EvaluirajBroj(disp, greska); 1, 6: op.datasizes := [d16]; End If not (greska) Then exit; 2, 3, 4, 5: op.datasizes := [d32]; Else Begin n := nadjilabelu(disp); 7, 8: op.datasizes := [d64]; m := 1; If n<>-1 Then Begin End; n2 := EvaluirajBroj(B, greska); patstr := disp; End Deplasmani(op, n2, True); disp := IntToStr(labele[n].labval, 10); Else Begin If exdisp8 in op.existv Then exit If pos(':', A) = 0 Then Begin Begin End n := EvaluirajBroj(A, greska); m := 1; Else Begin Deplasmani(op, n, n < 0); op.existv := [exdisp8] unknown := ''; End End disp := '0'; Else Begin Else End; op.segnum:=EvaluirajBroj(copy(A,1, If exdisp16 in op.existv Then End; pos(':', A) - 1), greska); Begin op.existv:=op.existv + [exSegment]; m := 2; Procedure zamijeni(Var x, y: string); n:=EvaluirajBroj(copy(A,pos(':',A)+ op.existv := [exdisp16] Var 1,length(A)), greska); End z: string; Deplasmani(op, n, n < 0); Else Begin End; Greska := True; z := x; x := y; y := z; End; Case n Of End; End; 3: setmod(m*64+7); {[bx+disp]} 5: setmod(m*64+6); {[bp+disp]} Function progutaj(st: string; Var puni: Procedure OBrada7; { Slucaj [A] } 6: setmod(m*64+4); {[si+disp]} string): boolean; Begin 7: setmod(m*64+5); {[di+disp]} Var n := regcode(A, kind); Else n: integer; If n<>-1 Then Begin Greska := True; Begin Case kind Of End; n := pos(st, uppercase(puni)); 1: Begin End; If n > 0 Then Begin Case n Of End; puni := trim(copy(puni,1,n-1)+copy( 3: setmod(0 * 64 + 7); {BX } 2: Begin puni, n + length(st), length(puni))); 6: setmod(0 * 64 + 4); {SI} { U 32 bita dopusteno samo progutaj := True; 7: setmod(0 * 64 + 5); {DI} REG+const. Za REG+REG koristi REG*1 + REG} End 5: Begin { BP} op.adrsizes := [d32]; Else tip := 8;B := '0'; n2 := regcode(B, kind); progutaj := False; ponovifazu := True; If n2<>-1 Then Begin End; End Greska := True; Else exit FUNCTION parseOp(arg: string; Var op: Greska := True; End; TOperand; End; n2 := EvaluirajBroj(B, greska); b32: boolean): boolean; op.adrsizes := [d16]; Deplasmani(op, n2, True); Var End; m := 1; tip: integer; 2: Begin If exdisp8 in op.existv Then Begin n: longint; Case n Of m := 1; Greska, ponovifazu: boolean; {EAX..EDI} 0..3,6,7:setmod(0*64+n); op.existv := [exdisp8] A, B, C, D: string; 4:Begin { ESP} End A1, B1, C1, D1, unknown, dsp: string; setmod(0 * 64 + 4); {SIB} Else If exdisp32 in op.existv Then kind, po: integer; setsib(64 * 0 + 8 * 4 + 4); Begin End; m := 2; Procedure setmod(x: byte); 5: Begin { EBP} op.existv := [exdisp32] Begin tip := 8; End op.modrm := x; B := '0'; Else op.existv := op.existv + [exmodrm]; ponovifazu := True; Greska := True; End; End If n <> 4 Then setmod(m * 64 + n) Else Else Procedure setsib(x: byte); Greska := True; Begin {ESP} Begin End; setmod(m * 64 + 4); op.sib := x; op.adrsizes := [d32]; setsib(64 * 0 + 8 * 4 + 4); op.existv := op.existv + [exsib]; End End End; Else End Greska := True; {ni 16 ni 32bit} Else Function Uzorak(pattern,st:string):boolean; End; Greska := True; { Ni 16 ni 32} Var End End; m: string; Else Begin End; i: integer; n := EvaluirajBroj(A, greska); Begin Deplasmani(op, n, False); Procedure OBrada9; { Slucaj [A*B]} Uzorak := True; If b32 Then Begin Var If pattern = 'A' Then Begin op.existv := [exdisp32]; sc: integer; a := st; setmod(0 * 64 + 5); Begin exit End n := regcode(A, kind); End; Else Begin If (kind<>2)or(n=1)or(n=4)or(n=-1) or For i := 1 To length(pattern) Do op.existv := [exdisp16]; (length(b) <> 1) or (not (b[1] in Begin setmod(0 * 64 + 6); ['1','2','4', '8'])) Then Begin If pattern[i]in['A','B','C','D'] Then End Greska := True; Begin End exit; m:=copy(st,1, End; End; pos(pattern[i+1],st)-1); op.adrsizes := [d32]; If m = '' Then Procedure OBrada8; { Slucaj [A+B]} sc := pos(b[1], '1248') - 1; uzorak := False; Var setmod(0 * 64 + 4); Case pattern[i] Of n2, m: longint; setsib(64*sc+8*n+5); { EBP specijalan} 'A': a := m; Begin End; 'B': b := m; n := regcode(A, kind); {Samo registar} 'C': c := m; If n = -1 Then Begin Procedure OBrada10; { Slucaj [A+B+C]} 'D': d := m; Greska := True; Var End; exit n2, n3, m: longint; st := copy(st, pos(pattern[i + 1], End; Begin st), length(st)); Case kind Of n := regcode(A, kind); End 1: Begin If(kind <> 1) or not (n in [3, 5]) Then Else op.adrsizes := [d16]; Begin st := copy(st, pos(pattern[i], st) n2 := regcode(B, kind); Greska := True; End; End; 168 exit; End; End; n3 := regcode(D, kind); n2 := regcode(B, kind); If (n3<>-1) Then Begin If (kind<>1) or not (n2 in [6, 7]) Then Greska := True; Begin exit; Greska := True; exit; End; End; n3 := EvaluirajBroj(D, greska); n3 := regcode(C, kind); Deplasmani(op, n3, True); If (n3<>-1) Then m := 1; Begin If exdisp8 in op.existv Then Begin Greska := True; m := 1; exit; op.existv := [exdisp8] End; End n3 := EvaluirajBroj(C, greska); Else If exdisp32 in op.existv Then op.adrsizes := [d16]; Begin Deplasmani(op, n3, True); m := 2; m := 1; op.existv := [exdisp32] If exdisp8 in op.existv Then End Begin Else m := 1; Greska := True; op.existv := [exdisp8] setmod(m * 64 + 4); End setsib(64 * sc + 8 * n + n2); Else If exdisp16 in op.existv Then End; Begin Begin {Parseop} m := 2; tip := -1; op.existv := [exdisp16] Greska := False; End op.datasizes := []; Else If progutaj('BYTE', arg) Then Greska := True; op.datasizes := [d8] If (n=3)and(n2=6)Then setmod(m*64+0) Else If progutaj('DWORD', arg) Then Else If (n=3)and(n2=7) Then op.datasizes := [d32] setmod(m * 64 + 1) Else If progutaj('QWORD', arg) Then Else If (n = 5) and (n2 = 6) Then op.datasizes := [d64] setmod(m * 64 + 2) Else If progutaj('TWORD', arg) Then Else If (n = 5) and (n2 = 7) Then op.datasizes := [d80] setmod(m * 64 + 3) Else If progutaj('WORD', arg) Then Else op.datasizes := [d16]; Greska := True; dummyb := progutaj('PTR', arg); End; { Prva faza: Obrada raznih slucajeva operanda} Procedure OBrada11; { Slucaj [A*B+C]} arg := trim(arg); Var If length(arg) >= 3 Then sc, n2, m: longint; If(arg[1]='''')and(arg[3]='''') Then Begin arg := IntToStr(Ord(arg[2]), 10); n := regcode(A, kind); If uzorak('[A*B+C+D]',arg)Then tip := 13 If (kind<>2)or(n=1)or(n=4)or(n = -1) or Else If uzorak('[A+B*C+D]',arg)Then tip:=14 (length(b) <> 1) or (not (b[1] in Else If uzorak('[A+B+C*D]',arg)Then tip:=15 ['1', '2', '4', '8'])) Then Begin Else If uzorak('[A*B+C-D]',arg)Then tip:=16 Greska := True; Else If uzorak('[A+B*C-D]',arg)Then tip:=17 exit; Else If uzorak('[A-B+C*D]',arg)Then tip:=18 End; Else If uzorak('[A*B-C+D]',arg)Then tip:=19 sc := pos(b[1], '1248') - 1; Else If uzorak('[A*B+C]',arg)Then tip:=11 n2 := regcode(C, kind); Else If uzorak('[A+B+C]',arg)Then tip:=10 op.adrsizes := [d32]; Else If uzorak('[A*B-C]',arg)Then tip:=20 m := 1; Else If uzorak('[A+B-C]',arg)Then tip:=21 If n2 = -1 Then Begin Else If uzorak('[A-B+C]',arg)Then tip:=22 n2 := EvaluirajBroj(C, greska); Else If uzorak('[A+B*C]',arg)Then tip:=12 Deplasmani(op, n2, True); Else If uzorak('[A*B]',arg)Then tip:=9 If exdisp8 in op.existv Then Begin Else If uzorak('[A+B]',arg)Then tip:=8 m := 1; Else If uzorak('[A-B]',arg)Then tip:=23 op.existv := [exdisp8] Else If uzorak('A[B*C+D]',arg)Then tip:=5 End Else If uzorak('A[B*C-D]',arg) Then tip:=24 Else If exdisp32 in op.existv Then Else If uzorak('A[B+C*D]',arg) Then tip:=6 Begin Else If uzorak('A[B*C]',arg) Then tip:=4 m := 2; Else If uzorak('A[B+C]',arg) Then tip:=3 op.existv := [exdisp32] Else If uzorak('A[B-C]',arg) Then tip:=25 End Else If uzorak('A[B]',arg) Then tip:=2 Else Else If uzorak('[A]',arg) Then tip:=7 Greska := True; Else If uzorak('A',arg) Then tip:=1; setmod(m * 64 + 4); If tip = -1 Then greska := True; setsib(64 * sc + 8 * n + 5); If not (greska) Then Begin End { Druga faza:Smanjivanje broja slucaja} Else Begin Case tip Of If kind <> 2 Then greska := True; 16: Begin If n2 = 5 Then Begin D := '-' + D; tip := 13 ponovifazu := True; End; tip := 13; 17: Begin D := '0'; D := '-' + D; tip := 14 exit End; End; 18: Begin setmod(0 * 64 + 4); B := '-' + B; tip := 15 setsib(64 * sc + 8 * n + n2); End; End; 19: Begin End; C := '-' + C; tip := 13 End; Procedure OBrada13; { Slucaj [A*B+C+D]} 20: Begin Var C := '-' + C; tip := 11 sc, n2, n3, m: longint; End; Begin 21: n := regcode(A, kind); Begin If (n=-1)or(kind<>2)or(n=1)or(n=4) or C := '-' + C; (length(b) <> 1) or (not (b[1] in tip := 10 ['1','2','4', '8'])) Then Begin End; Greska := True; 22: Begin exit; B := '-' + B; tip := 10 End; End; sc := pos(b[1], '1248') - 1; 23: Begin n2 := regcode(C, kind); B := '-' + B; tip := 8 op.adrsizes := [d32]; End; If (n2 = -1) or (kind <> 2) Then Begin 24: Begin Greska := True; D := '-' + D; tip := 5 exit; End; 25: Begin C := '-' + C; tip := 3 End; End; A1 := A; B1 := B; C1 := C; D1 := D; Case tip Of 2: tip := 8; 3: tip := 10; 4: Begin a := b1; b := c1; c := a1; tip := 11; End; 5: Begin d := a1; c := d1; b := c1; a := b1; tip := 13; End; 6: Begin d := a1; c := b1; a := c1; b := d1; tip := 13; End; 12: Begin c := a1; a := b1; b := c1; tip := 11; End; 14: Begin a := b1; b := c1; c := a1; d := d1; tip := 13; End; 15: Begin a := c1; b := d1; c := a1; d := b1; tip := 13; End; End; { Treca faza, deplasman na kraj} Case tip Of 8: Begin If regcode(A, kind) = -1 Then zamijeni(A, B); If regcode(B, kind) in [3, 5] Then If kind = 1 {16 bit} Then zamijeni(A, B); End; 10: Begin If regcode(A, kind) = -1 Then zamijeni(A, C); If regcode(B, kind) = -1 Then zamijeni(B, C); If regcode(B, kind) in [3, 5] Then If kind = 1 {16 bit} Then zamijeni(A, B); End; 9, 11: Begin If regcode(A, kind) = -1 Then zamijeni(A, B); End; 13: Begin If regcode(A, kind) = -1 Then zamijeni(A, B); If regcode(C, kind) = -1 Then zamijeni(C, D); End; End; { Cetvrta faza, proracun deplasmana, slucaj A moze postati [A] ako je rijec o labeli, slucaj [A+B] moze postati [A] ako ni jedan nije registar } If tip = 8 Then Begin If (RegCode(A, kind) = -1) and (RegCode(B,kind)=-1) Then Begin If (A[1] in ['0'..'9']) and not (B[1] in ['0'..'9']) Then Begin patstr := B; End Else Begin dsp := A + '+' + B; ResolveDisp(A, unknown); ResolveDisp(B, unknown); patstr := dsp; A := IntToStr(EvaluirajBroj(A, greska) + EvaluirajBroj(B, greska), 10); End; B := ''; tip := 7; End; End; If tip = 1 Then Begin If not (progutaj('OFFSET', A)) Then If RegCode(A,kind)=-1 Then Begin dummy := EvaluirajBroj(A,greska); If Greska Then Begin {Trazi labl} po := nadjilabelu(A); If(po=-1)and(skok = False) Then tip := 7 { Pretpostavka} Else If labele[po].labtip=ldata Then Begin tip := 7; op.datasizes:= [labele[po].labdsize]; End; End 169 End End; unknown := ''; Case tip Of 1: If pos(':', A) = 0 Then ResolveDisp(A, unknown); 7: ResolveDisp(A, unknown); 8: ResolveDisp(B, unknown); 10, 11: ResolveDisp(C, unknown); 13: ResolveDisp(D, unknown); End; greska := False; { Peta faza kalkulacija mod/rm, SIB i deplasmana } op.existv := []; op.adrsizes := []; repeat ponovifazu := False; Case tip Of 1: Obrada1; 7: Obrada7; 8: Obrada8; 9: Obrada9; 10: Obrada10; 11: Obrada11; 13: Obrada13; End; UNTIL not (ponovifazu); End; If greska Then parseop := False Else parseop := True; End; If p > 0 Then Begin Begin x := trim(copy(st, 1, p - 1)); endian32:=copy(a,7,2)+ copy(a, 5, 2) + st:=trim(copy(st,p+1,length(st)-p)); copy(a, 3, 2) + copy(a, 1, 2); End End; Else Begin Function end1632(a:string;n:TDsize): If sep = ':' Then x := '' string; Else Begin Begin x := trim(st); Case n Of st := ''; d16: end1632 := Endian16(a); End d32: end1632 := Endian32(a); End Else End; end1632 := a; Procedure ClearOp(Var op: TOperand); End; Begin End; With op Do Procedure writemodrm(slobodni: integer); Begin Var existv := []; op: toperand; datasizes := []; mrm: byte; adrsizes := []; Begin modrm := 0; If modski = 1 Then op := op1 sib := 0; Else If modski = 2 Then op := op2 disp8 := 0; Else disp16 := 0; greska := True; disp32 := 0; If slobodni = 8 Then segnum := 0; Begin reg := 0; If registarski = 1 Then kind := 0; slobodni := op1.reg End; Else If registarski = 2 Then End; slobodni := op2.reg Function MakeOps(arg: string; VAR op: Else TOperand; Var rez: string): boolean; greska := True; Begin End; If not(parseop(arg,op,b32))Then Begin mrm:=(op.modrm)and($C7)or(slobodni*8); Makeops := False; outstr := outstr + inttohex(mrm, 2); Procedure ReadOpcodeTable; exit; If patstr<>''Then patstr:=patstr+' ' + Var End; IntToStr(pozicija[actseg] i, j: integer; If length(arg) <= 4 Then +length(outstr) div 2,10) + ' A'; f: Text; rez := copy(arg + ' ', 1, 4) If exSIb in op.existv Then st: string; Else outstr:=outstr + inttohex(op.sib, 2); t: toptable; rez := ''; If exdisp8 in op.existv Then Begin If exsegment in op.existv Then Begin outstr:=outstr+inttohex(op.disp8, 2) maxopcode := 0; If exdisp16 in op.existv Then Else If exdisp16 in op.existv Then Assign(f, 'opcod.txt'); rez:= rez + 's:16'; outstr := outstr + reset(f); If(exdisp32 in op.existv)and b32 Then endian16(inttohex(op.disp16, 4)) While not EOF(f) Do rez := rez + 's:32'; Else If exdisp32 in op.existv Then Begin End outstr := outstr + readln(f, st); Else If exreg in op.existv Then Begin endian32(inttohex(op.disp32, 8)); maxopcode := maxopcode + 1; Case op.kind Of End; optable[maxopcode].instr := 0: rez := rez + 'reg8rgm8'; trim(copy(st, 1, 20)); 1: rez := rez + 'rg16rm16'; Procedure writedisp(ex: texists); optable[maxopcode].gencod := copy(st, 2: rez := rez + 'rg32rm32'; Var 21, 20); 3: rez := rez + 'creg'; op: TOperand; End; 4: rez := rez + 'dreg'; Begin For i := 1 To maxopcode - 1 Do 5: rez := rez + 'treg'; If (arg1<>'')and(ex in op1.existv) Then For j := i + 1 To maxopcode Do 6: rez := rez + 'segr'; op := op1 If optable[i].instr > 7: rez := rez + 'fpur'; Else If(arg2<>'')and(ex in op2.existv) optable[j].instr Then Begin 8: rez := rez + 'mmxr'; Then op := op2 t := optable[i]; End; Else If(arg3<>'')and(ex in op3.existv) optable[i] := optable[j]; End Then op := op3 optable[j] := t; Else Else End; Begin { Memorija ili neposredno} greska := True; End; If exmodrm in op.existv Then Begin If patstr <> '' Then Begin rez := rez + 'memg'; patstr := patstr + ' ' + Function Binsearch(instr: string): integer; If op.datasizes = [] Then IntToStr(pozicija[actseg] + Var rez := rez + length(outstr) div 2, 10) + ' D'; high, j, low: integer; 'mem8mm16mm32mm64mm80rgm8rm16rm32rm64' op.disp32 := 0; {za coff} Begin Else Begin End; low := 0; If d8 in op.datasizes Then If ex = exdisp8 Then high := maxopcode; rez := rez + 'mem8rgm8'; outstr:=outstr+ While high - low > 1 Do Begin If d16 in op.datasizes Then (inttohex(op.disp8,2)); j := (high + low) div 2; rez := rez + 'mm16rm16'; If ex = exdisp16 Then If instr<=optable[j].instr Then high:=j If d32 in op.datasizes Then outstr := outstr + endian16(inttohex Else rez := rez + 'mm32rm32'; (op.disp16, 4)); low := j If d64 in op.datasizes Then If ex = exdisp32 Then End; rez := rez + 'mm64rm64'; outstr := outstr + endian32(inttohex( If optable[high].instr=instr Then If d80 in op.datasizes Then op.disp32, 8)); Binsearch:=high rez := rez + 'mm80rm80'; End; Else End; Binsearch := -1; If b32 and (op.modrm = 5) Then Procedure writeseg; End; rez := rez + 'ab32'; Begin {*******************} If not(b32) and (op.modrm = 6) Then outstr := outstr + endian16(inttohex( Function GenerateHexInstruction(inst: rez := rez + 'ab16abs8'; op1.segnum, 4)); string; End End; b32: boolean): string; Else Procedure writerel(offs:longint; Label Begin ex: texists); postoji; rez := rez + 'immg'; Var Var If exdisp8 in op.existv Then op: TOperand; labela, opcode, arg1, arg2, arg3, comb1, rez := rez + 'ime8'; Function test(a,min,max:integer): comb2,comb3, cf: string; If exdisp16 in op.existv Then integer; op1, op2, op3: TOperand; rez := rez + 'im16'; Begin p, i, j, k, n: integer; If exdisp32 in op.existv Then If (a < min) or (a > max) Then b1, greska, no67: boolean; rez := rez + 'im32'; greska := True; g1, outstr, st, modif: string; End test := a; modski, registarski: integer; End; End; MakeOps := True; Begin Procedure izdvoji(Var x:string;sep:char); End; If (arg1 <> '') Then op := op1 Begin Else If (arg2 <> '') Then op := op2 If st = '' Then Begin Function endian16(a: string): string; Else If (arg3 <> '') Then op := op3 x := ''; Begin Else exit endian16:=copy(a,3,2)+ copy(a, 1, 2); greska := True; End; End; If ((op.disp32 = 0) and (prolaz = 1)) p := pos(sep, st); Function endian32(a: string): string; or (op.disp32 = -1) Then 170 op.disp32 := offs; If patstr<>'' Then patstr := patstr + ' ' + IntToStr(pozicija[actseg] + length(outstr) div 2, 10) + ' R'; If ex = exdisp8 Then outstr := outstr + {malo drugacije jer je rijec o razlici} (inttohex(test(op.disp32 - offs, - 128, 127), 2)); If ex = exdisp16 Then outstr := outstr + endian16(inttohex(test(op.disp32 offs, - 32768, 32767), 4)); If ex = exdisp32 Then outstr := outstr + endian32(inttohex(op.disp32-offs,8)); End; FLDCW CWNear Else FLDZ puta := 1; End; pozicija[actseg]:=pozicija[actseg] + While tekstime[Brojac] in ['0'..'9'] Do (length(outstr) div 2); Begin UpisiIzlaz(outstr); Temp:=Ord(tekstime[Brojac])-Ord('0'); outstr := ''; asm For i := 1 To puta Do Begin FIMUL DCon10 If (vr[1] = chr(39)) and FIADD Temp (vr[length(vr)] = chr(39)) and End; (opcode[2] = 'B') Then Begin Brojac := Brojac + 1; For j := 2 To length(vr) - 1 Do End; Begin If brojac > length(tekstime) Then outstr := outstr +inttohex( Goto writenum; Ord(vr[j]), 2); If tekstime[Brojac] = '.' Then End; Brojac := Brojac + 1 End Else If tekstime[Brojac]in['e','E']Then Else Begin Goto GetExponent; If pos('.', vr) > 0 Then Begin If brojac > length(tekstime) Then StrToFloat2(vr, opcode[2]); Function dod(n: integer): integer; Goto writenum; For j := 1 To sz div 2 Do Begin While tekstime[Brojac]in['0'..'9'] Do outstr := outstr + IntTohex( dod := (length(outstr) div 2) + n; Begin Ord(FPValue[j]), 2); End; Temp:=Ord(tekstime[Brojac])-Ord('0'); End Procedure prefix(pr, cod: string); asm Else Begin FIMUL DCon10 outstr := outstr + end1632( If progutaj(pr,st)Then FIADD Temp Inttohex(EvaluirajBroj(vr, outstr := outstr + cod; End; greska), sz), dsz); End; Brojac := Brojac + 1; End; Procedure modifikator(pr: string); DecCifara := DecCifara + 1; If i <> puta Then Begin Begin End; pozicija[actseg]:=pozicija[actseg] If progutaj(pr,st)Then modif:='_' + pr; Exponent := -DecCifara; +(length(outstr) div 2); End; If brojac>length(tekstime)Then UpisiIzlaz(outstr); Function ispseudo(x: string): boolean; Goto DivExp; outstr := ''; Begin If not(tekstime[Brojac]in['e','E'])Then End x := copy(x, 1, 3); Goto DivExp; End If (x='DB ')or(x='DW ')or(x = 'DD ')Or Brojac := Brojac + 1; End; (x='DQ ')or(x='DT ') Then Begin If tekstime[Brojac] = '+' Then Begin ispseudo := True Brojac := Brojac + 1 opcode := copy(opcode, 1, 3); End Else If tekstime[Brojac]='-'Then Begin Case opcode[2] Of Else Brojac := Brojac + 1; 'B': Begin ispseudo := False; ExpNegative := True; sz := 2; dsz := d8 End; End; End; If brojac > length(tekstime) Then 'W': Begin Function posnostr(bb: char; s1: string): Goto writenum; sz := 4; dsz := d16 integer; GetExponent: End; Var Exponent := 0; 'D': Begin odsijeci, ustringu: boolean; While tekstime[Brojac] in ['0'..'9'] Do sz := 8; dsz := d32 i: integer; Begin End; Begin Temp:=Ord(tekstime[Brojac])-Ord('0'); 'Q': Begin i := 1; Exponent := Exponent * 10 + temp; sz := 16; dsz := d64 odsijeci := False; Brojac := Brojac + 1; End; ustringu := False; End; 'T': Begin While not (odsijeci) Do Begin If ExpNegative Then sz := 20; dsz := d80 If i>length(s1) Then odsijeci := True Exponent := -Exponent; End; Else Begin Exponent := Exponent - DecCifara; Else Begin If s1[i] = chr(39) Then DivExp: sz := 2; dsz := d8 ustringu := not (ustringu); If Exponent > 0 Then End; If not(ustringu)and(s1[i]=bb) Then For i := 1 To Exponent Do Begin End; odsijeci := True asm If labela <> '' Then Else FIMUL DCon10 UpisiLabelu(labela, i := i + 1; End; pozicija[actseg], ldata, dsz); End; End bajtovi := trim(copy(inst, End; Else pos(opcode, inst) + 3,length(inst))); If i <= length(s1) Then posnostr := i For i := 1 To -Exponent Do Begin; While (posnostr(',', bajtovi) > 0) Do Else asm Begin posnostr := 0; FIDIV DCon10 p := posnostr(',', bajtovi); End; End element:=trim(copy(bajtovi,1,p-1)); End; bajtovi := trim(copy(bajtovi, p + 1, Procedure StrToFloat2(tekstime: string; If Negative Then length(bajtovi))); ValueType: char); asm putdb(element); Label FCHS End; WriteNum, GetExponent, DivExp; End; If bajtovi <> '' Then Const writenum: putdb(bajtovi); CWNear: word = $133F; Case ValueType Of If greska Then outstr := ''; DCon10: integer = 10; 'T': asm End; Var FSTP TBYTE PTR FPValue Begin {Generate Hex instruction} Temp: integer; End; p := posnostr(';', inst); CtrlWord: word; 'Q': asm If p > 0 Then Brojac,DecCifara, Exponent, i: integer; FSTP QWORD PTR FPValue inst := copy(inst, 1, p - 1); Negative, ExpNegative: boolean; End; st := inst; Begin 'D': asm outstr := ''; Brojac := 1; FSTP DWORD PTR FPValue prefix('ES:', '26'); If length(tekstime) = 0 Then exit; End; prefix('CS:', '2E'); While tekstime[Brojac] = ' ' Do Begin End; prefix('SS:', '36'); Brojac := Brojac + 1; End; prefix('DS:', '3E'); If brojac>length(tekstime) Then exit; prefix('FS:', '64'); End; Procedure dopseudo; prefix('GS:', '65'); ExpNegative := False; Var prefix('REP ', 'F3'); Negative := False; sz, p, d: integer; prefix('REPE ', 'F3'); DecCifara := 0; dsz: TDSize; prefix('REPNE ', 'F2'); If tekstime[Brojac] = '+' Then bajtovi, element: string; prefix('REPZ ', 'F3'); Brojac := Brojac + 1 Procedure putdb(Var vr: string); prefix('REPNZ ', 'F2'); Else If tekstime[Brojac]='-'Then Begin Var prefix('LOCK ', 'F0'); Brojac := Brojac + 1; i, j, puta: integer; modif := ''; Negative := True; Begin modifikator('NEAR'); End; d := pos('DUP(', vr); modifikator('FAR'); If brojac > length(tekstime) Then exit; If d > 0 Then Begin izdvoji(labela, ':'); If not (tekstime[Brojac] in puta:=EvaluirajBroj(trim(copy(vr, izdvoji(opcode, ' '); ['0'..'9', '.']) Then exit; 1,d-1)), greska); izdvoji(arg1, ','); asm vr:=trim(copy(vr,d+4,pos(')', vr) – izdvoji(arg2, ','); FSTCW CtrlWord d - 4)); izdvoji(arg3, ';'); FCLEX End If pos(' ', labela) > 0 Then Begin 171 { JMP , CALL A:B} Begin arg1 := copy(labela,pos(' ',labela)+1, If (arg1<>'')and(arg2<>'')Then Begin length(labela)) + ':' + opcode; If (exmodrm in op1.existv) Then opcode := copy(labela, 1, pos(' ', modski := 1; labela) - 1); If (exmodrm in op2.existv) Then End; modski := 2; opcode := opcode + modif; If (exreg in op1.existv) Then If ispseudo(arg1) Then Begin registarski := 1; labela := opcode; If (exreg in op2.existv) Then opcode := arg1; registarski := 2; End; If (exmodrm in op1.existv) and If ispseudo(opcode) Then Begin (exreg in op2.existv) Then Begin DoPseudo; modski := 1; GenerateHexInstruction := outstr; registarski := 2; Exit; End; End; If (exmodrm in op2.existv) and b1 := True; (exreg in op1.existv) Then Begin skok := False; modski := 2; If length(opcode) > 1 Then registarski := 1; If(opcode[1]='J')or(opcode='CALL') Then End; skok := True; End; If (labela <> '') and (prolaz = 1) Then If (arg1 <> '')and(arg2='') Then Begin Begin If (exmodrm in op1.existv) Then UpisiLabelu(labela, pozicija[actseg], modski := 1; lprog, d32); If (exreg in op1.existv) Then End; registarski := 1; If opcode = '' Then Begin End; GenerateHexInstruction := 'XX'; If g1[i * 3] = ' ' Then Begin exit; cf := copy(g1, i * 3 - 2, 2); End; If cf = '/r' Then Begin ClearOp(op1); ClearOp(op2); ClearOp(op3); writemodrm(8); If arg1 <> '' Then End b1 := Makeops(arg1, op1, comb1); Else If(cf>='/0')and(cf<= '/9') Then If arg2 <> '' Then Begin b1 := b1 and Makeops(arg2, op2, comb2); writemodrm(Ord(cf[2]) - Ord('0')); If arg3 <> '' Then End b1 := b1 and Makeops(arg3, op3, comb3); Else If cf = 'ib' Then Begin If not (b1) Then writedisp(exdisp8); greska := True; End If (arg1='')and(arg2='')and(arg3='') Then Else If cf = 'sw' Then Begin Begin writedisp(exdisp16); n := binsearch(opcode); writeseg; If n<>-1 Then Goto postoji; End End; Else If cf = 'sd' Then Begin If (arg1<>'')and(arg2='')and(arg3='')Then writedisp(exdisp32); For i := 1 To length(comb1) div 4 Do writeseg; Begin End st := opcode; Else If (cf = 'iw') or ((cf = 'o?') st:=st+' '+ and not (b32)) Then Begin TRIM(copy(comb1,(I-1)*4+ 1, 4)); writedisp(exdisp16); n := binsearch(st); End If n<>-1 Then Goto postoji; Else If (cf = 'id') or ((cf = 'o?') End; and (b32)) Then Begin If (arg2 <> '') and (arg3 = '') Then writedisp(exdisp32); For i := 1 To length(comb1) div 4 Do End For j := 1 To length(comb2) div 4 Do Else If cf = 'rb' Then Begin Begin writerel(pozicija[actseg] + dod(1), st := UPPERCASE(opcode); exdisp8); st := st + ' ' + TRIM(copy( End comb1, (I - 1) * 4 + 1, 4)); Else If (cf = 'rw') or ((cf = 'r?') st := st + ',' + TRIM(copy( and not (b32)) Then Begin comb2, (j - 1) * 4 + 1, 4)); writerel(pozicija[actseg] + dod(2), n := binsearch(st); exdisp16); If n<>-1 Then Goto postoji; End End; Else If (cf = 'rd') or ((cf = 'r?') If arg3 <> '' Then and b32) Then Begin For i := 1 To length(comb1) div 4 Do writerel(pozicija[actseg] + dod(4), For j := 1 To length(comb2) div 4 Do exdisp32); For k:=1 To length(comb3) div 4 Do End Begin Else If(cf<>'rg')and(cf<>'cc') Then st := UPPERCASE(opcode); outstr := outstr + cf st := st + ' ' + TRIM(copy( End; comb1, (I - 1) * 4 + 1, 4)); If g1[i * 3] = '+' Then Begin st := st + ',' + TRIM(copy( If copy(g1,i*3+1,2)='rg' Then Begin comb2, (j - 1) * 4 + 1, 4)); If exreg in op1.existv Then st := st + ',' + TRIM(copy( n := op1.reg comb3, (K - 1) * 4 + 1, 4)); Else If exreg in op2.existv Then n := binsearch(st); n := op2.reg If n<>-1 Then Goto postoji; Else End; greska := True; greska := True; outstr := outstr + GenerateHexInstruction := ''; Inttohex(evaluirajbroj('0' + exit; copy(g1, i * 3 - 2, 2) + 'h', postoji: greska) + n, 2); g1 := Optable[n].gencod; End; no67 := True; End; If (copy(g1, 1, 3) = 'o16') and b32 Then End; outstr := outstr + '66'; If no67 Then Begin If(copy(g1,1,3)='o32') and not (b32) Then If b32 and (d16 in op1.adrsizes + outstr := outstr + '66'; op2.adrsizes) Then If ((copy(g1, 1, 3) = 'a16') and b32) or outstr := '67' + outstr; ((copy(g1,1,3)='a32')and not(b32)) Then If not (b32) and (d32 in op1.adrsizes + Begin op2.adrsizes) Then outstr := outstr + '67'; outstr := '67' + outstr; no67 := False; End; End; If not (greska) Then If G1[1] <> ' ' Then GenerateHexInstruction := outstr g1 := copy(g1, 4, length(g1)); Else g1 := trim(g1) + ' '; GenerateHexInstruction := ''; modski := 0; End; registarski := 0; For i := 1 To length(g1) div 3 Do Procedure Glavni; Var inst, outst, par: string; opt: boolean; i: integer; Procedure ac(n: integer); Begin actseg := n; inst := ''; End; Begin opt := True; {32 bit } If ParamStr(2) = '/d' Then opt := False; If ParamStr(2) = '/w' Then opt := True; par := uppercase(ParamStr(1)); If pos('.ASM', par) > 0 Then par:=copy(par,1,pos('.ASM', par) - 1); Assign(ulaz, ParamStr(1)); Assign(izlazcode, par + '.cod'); Assign(izlazdata, par + '.dat'); Assign(izlazstack, par + '.sta'); Assign(izlazlab, par + '.lab'); Assign(izlazpat, par + '.pat'); prolaz := 1; While prolaz <= 2 Do Begin reset(ulaz); If opt Then pozicija[1] := 0 Else pozicija[1] := 256; pozicija[2] := 0; pozicija[3] := 0; actseg := 1; If prolaz = 2 Then Begin rewrite(izlazcode); rewrite(izlazdata); rewrite(izlazstack); rewrite(izlazlab); rewrite(izlazpat); End; While not EOF(ulaz) Do Begin readln(ulaz, inst); inst := trim(inst); If inst = '.CODE' Then ac(1); If inst = '.DATA' Then ac(2); If inst = '.STACK' Then ac(3); If (inst = '.486') or (inst = 'OPTION CASEMAP:NONE') or (inst = '.MODEL FLAT,STDCALL') or (inst = '.386') Then inst := ''; If (uppercase(copy(inst,1,5))= 'EXTRN') Then Begin inst := inst + ':'; upisilabelu(trim(copy(inst, 6, pos(':', inst) - 6)), - 1, lextrn, d32); inst := ''; End; If (uppercase(copy(inst, 1, 6) ) = 'PUBLIC') Or uppercase(copy(inst, 1, 3)) = 'END') Then Begin If prolaz = 2 Then writeln(izlazlab, inst); inst := ''; End; If inst <> '' Then Begin patstr := ''; outst := GenerateHexInstruction( inst, opt); If outst = '' Then Begin Writeln('Greska u liniji ', inst) End Else If outst <> 'XX' Then Begin pozicija[actseg] := pozicija[actseg] + (length(outst) div 2); If(prolaz=2)and(patstr<>'') Then writeln(izlazpat, patstr); UpisiIzlaz(outst); End; End End; prolaz := prolaz + 1; End; For i := 1 To brlabela Do With labele[i] Do writeln(izlazlab, labime, ' ', Ord(labtip),' ', labval, ' ', Ord(labdsize)); Close(ulaz); Close(izlazcode); Close(izlazdata); Close(izlazstack); Close(izlazlab); Close(izlazpat); End; Begin readopcodetable; Glavni; End. 172 18. PRAVLJENJE STANDARDNOG OBJ FORMATA Mašinski kod generisan asemblerom iz prethodnog poglavlja je upotrebljiv za situacije kada se piše novi operativni sistem ili kada se koristi vrlo jednostavan operativni sistem kao što su CP/M ili MS DOS. Moćniji operativni sistemi imaju znatno složeniju strukturu izvršnog programa. Složeni projekti zahtijevaju da se programi sastoje iz više izvornih datoteka koje se separatno kompajliraju i zatim spajaju u jedinstveni izvršni format. 18.1. Objektni formati Objektni modul je izlaz iz asemblera ili kompajlera. Njegove primarne komponente su mašinski kod i podaci koje procesor može da razumije. Za operativni sistem Windows koriste se dva standarda (sa svojim varijacijama) od kojih oba imaju istu ekstenziju OBJ. Jedan od ovih standarda je COFF (korišten u Microsoftovim kompajlerima) a drugi je OMF (korišten na šesnaestobitnim operativnim sistemima, ali i sa Borlandovim kompajlerima na tridesetdvobitnim verzijama Windowsa). COFF format se javlja u dvije podvarijante, Microsoftov i GNU. 18.2. Objektni format Microsoft COFF COFF objektni format razvijen je u okviru besplatnog GNU C kompajlera, a koristi ga i Microsoft u svojim kompajlerima za C, uz malu razliku u metodi relokacije koda. Osobina formata je da se njegov sadržaj dijeli na sekcije koje služe za grupisanje koda i podataka. Pored sekcija, u objektnoj datoteci postoje razne tabele (simbola, relokacije i linijskih brojeva). Struktura ovog formata data na slici Sl. 18.2.1: Struktura Zaglavlje datoteke Opciono zaglavlje Zaglavlje sekcije Podaci sekcije Sekcijske direktive Linijski brojevi Tabela simbola Tabela stringova 18.3. Lokacija? Početak datoteke Odmah iza zaglavlja datoteke Namjena Opis datoteke, podaci o drugim sekcijama Za EXE datoteke, pozicija inicijalnog programskog brojača Iza opcionog zaglavlja èija je Lokacija i veličina sekcija koda, podataka i veličina navedena u zaglavlju specijalne namjene Navedeni u zaglavlju sekcije Sadrži kod i podatke programa Navedeno u zaglavlju sekcije Sadrži informacije o popravkama potrebne prilikom relociranja sekcije Navedeno u zaglavlju sekcije Čuva sve linijske brojeve, potrebno debageru Navedeno u zaglavlju datoteke Za svaki simbol (varijable, potprogrami) čuva se po jedno mjesto Iza tabele simbola Imena simbola koja su duža od 8 bajtova. Prva èetiri bajta su dužina tabele. Sl. 18.2.1. Struktura COFF OBJ datoteke Zaglavlje COFF OBJ datoteke TFileHeader= Record Machine:word; { 014C (i386) } NumberOfSections: word; { 0003 } TimeDateStamp: LongInt; { 41543009 -> Fri Sep 24 16:32:41 2004 } PointerToSymbolTable: LongInt; NumberOfSymbols:LongInt; SizeOfOptionalHeader:word; Characteristics:word; end; Ova struktura je uvijek na početku datoteke. Njeni elementi su Machine – Magični broj. Ova konstanta mora biti jednaka 0x14C i ona služi za raspoznavanje ovog formata. NumberOfSections – Koliko ima sekcija i samim tim sekcijskih zaglavlja. Konvertor u OBJ koji se razvija u ovom poglavlju ima tri sekcije, .text, .data i .drectve TimeDateStamp -Vrijeme i datum datoteke PointerToSymbolTable – Pozicija u datoteci poèetka tabele simbola NumberOfSymbols - Broj simbola u tabeli simbola. SizeOfOptionalHeader – Veličina opcionog zaglavlja. OBJ koji se generiše u ovom programu nema opciono zaglavlje, pa će ovaj parametar biti jednak nuli 173 Characteristics - flag bits Ovi flegovi definišu dodatno značenje zaglavlja: Bit Oznaka Značenje $0001 F_RELFLG Ako je postavljen tada nema relokacijskih informacija. Najèešæe se relokacijske informacije ukljuèuju u OBJ, a ne u EXE. $0002 F_EXEC Ako je postavljen, znaèi da nema nerazriješenih simbola i da se može smatrati izvršnim programom $0004 F_LNNO Ako je postavljen datoteka nema linijskih brojeva $0008 F_LSYMS Ako je postavljen, datoteka nema lokalnih simbola $0100 F_AR32WR Ako je postavljen, znaèi da je format Little Endian 18.4. Opciono zaglavlje Opciono zaglavlje se nalazi odmah iza glavnog zaglavlja. Ono se javlja samo u EXE programima. Njegova svrha je da definiše ulaznu taèku u program. Kako ovaj konvertor generiše samo OBJ, opcionog zaglavlja nema. TOptionalFileHeader= Record MagicWord:word; { Type of file } Vstamp: word; { Version } TSize: LongInt; { Text size in bytes } DSize: LongInt; { Initialized data size in bytes } BSize: LongInt; { Uninitialized data size in bytes } Entry: LongInt; { Entry point } Text_Start: LongInt; { Base of text used for this file } Data_Start: LongInt; { Base of text used for this file } end; Ako ima opcionog zaglavlja, samo dva polja su bitna MagicWord – Magični broj, uvijek ZMAGIC (0x010b). Entry – Ulazna tačka: Inicijalna pozicija programskog brojaèa (EIP) 18.5. Zaglavlje coff sekcije TSection=Record Name:array[0..7] of char; { section name in ASCII .text .data ili .drectve } PhysicalAddress:Longint; { size mapped into memory } VirtualAddress:Longint; { memory address relative to image base } SizeOfRawData:Longint; { physical size, multiple of file alignment } PointerToRawData:Longint; { file offset } PointerToRelocations:LongInt; { offset of relocation entries } PointerToLinenumbers:LongInt; { offset of line number entries } NumberOfRelocations:word; { number of relocation entries } NumberOfLinenumbers:word; { number of line number entries } Characteristics:Cardinal; { $20 = text, $40 = data, $80 = bss, $200 = no-load, $800 = don't link, $10000000 = shared, $20000000 = execute, $40000000 = read, $80000000 = write } end; Ova struktura se nalazi neposredno iza opcionalnog zaglavlja u COFF datoteci (ili iza zaglavlja datoteke ako opcionalnog zaglavlja nema). Znaèenja polja su: Name – Ime sekcije, ne smije biti duže od osam znakova i završava se nulom. Ako je taèno osam znakova tada nema krajnje nule. Ako je kraæe od osam znakova, ostali se popunjavaju nulama. PhysicalAddress – Fizička adresa sekcije. To je adresa gdje će se sekcija učitati u memoriju. Za linkovane izvršne programe, to je apsolutna adresa u programskom podruèju. Za nepovezane objekte, ova adresa je relativna u odnosu na adresni prostor objekta, to jest prva sekcija je uvijen na adresi nula. VirtualAddress - Virtualna adresa sekcije, nula ili jednaka PhysicalAddress SizeOfRawData – Veličina sekcije. Broj bajtova podataka smještenih u datoteku za ovu sekciju. Ovdje nisu uraèunate relokacione tabele i linijski brojevi, nego samo čisti kod odnosno podaci. PointerToRawData – Pokazivaè na podatke sekcije. Sadrži poziciju poèetka sekcije u datoteci. PointerToRelocations - Pozicija relokacijske tabele u datoteci 174 PointerToLineNumbers -Pozicija linijskih brojeva NumberOfRelocations - Broj elemenata relokacijske tabele. Pažnja: ovaj broj je ogranièen na 65535 NumberOfLineNumbers - Broj elemenata tabele linijskih brojeva. Pažnja: ovaj broj je ogranièen na 65535 Characteristics - flag bits. Ovi flegovi daju dodatne informacije za svaku sekciju. $0020 STYP_TEXT Ako je postavljen, sekcija sadrži samo izvršni kod $0040 STYP_DATA Ako je postavljen, sekcija sadrži samo inicijalizirane podatke $0080 STYP_BSS Ako je postavljen, sekcija sadrži samo neincijalizirane podatke i nema dijela sa podacima u COFF datoteci Microsoftovi kompajleri smještaju mašinski kod u sekciju .text, a podatke u sekciju .data. Ova imena nemaju posebno značenje osim kao napomena za namjeru upotrebe date sekcije. Drugi kompajleri imaju drugačija imena za svoje sekcije. Sekcije imaju sličnosti sa segmentima koji su korišteni pod MS DOSom ili Windowsom 3.1. Imena najčešće korištenih sekcija data su na slici: .text .data .rdata .rsrc .reloc .edata .idata .idata$XXX .CRT .CRT$XXX .bss .drectve .debug$XX X Machine code instructions. Initialized data. Read only data. OLE GUIDs are stored here, among other things. Resources. Produced by the resource compiler, and placed into RES files. Linker copies it to the executable. Base relocations. Produced by the linker. Not found in OBJs. The exported function table. Created by the linker and placed in an EXP file. Linker copies it to the executable. Imported function table in an executable file. Portions of an imported function table. The librarian creates these sections in an import library. The linker combines them into the final .idata section in the executable. Tables of initialization and shutdown pointers in the executable that are used by the Microsoft C++ runtime library. Initialization and shutdown pointers in OBJs, prior to the linker combining them in the executable. Uninitialized data. OBJ file section containing linker directives. Not copied to executable. COFF symbol table information in an OBJ file. Sl. 18.5.1. 18.6. Standardne sekcije u OBJ i EXE datotekama Relokacijska sekcija TRelocationTable=record r_vaddr:Longint; { address of relocation } r_symndx:Longint; { symbol we're adjusting for } r_type:Longint; { type of relocation } end; Veličina ove strukture nije djeljiva sa četiri, pa treba biti oprezan prilikom njenog upisa u datoteku. Normalno se pojavljuju dva tipa relokacija: RELOC_ADDR32 6 Relociraj 32-bitnu apsolutnu referencu RELOC_REL32 20 Relociraj a 32-bitnu relativnu referencu Za svaku relokaciju mora se odrediti nova adresa relociranog simbola koji se prilagođava. Ako je simbol drugi objekt (eksterni), tabela će sadržati referencu na taj eksterni simbol i relokacija æe se odnositi na njega. Ako je simbol u istom objektu, tabela simbola će sadržati elemente koji se odnose na same sekcije (uvijek prisutni i uvijek privatni). Kada se relocira sama sekcija, ovi simboli će prikazati njihovu novu lokaciju. 175 1. RELOC_ADDR32 Da se izvrši ova relokacija, moraju se izvesti sljedeæi koraci: • Uzeti adresu simbola na koji se referiše • Dodati vrijednost koja se trenutno nalazi na toj lokaciji • Upisati vrijednost nazad 2. RELOC_REL32 Ova relokacija se dešava samo u izvršivim programima i odnosi se samo na eksterne simbole. Za realizaciju ove relokacije, moraju se obaviti sljedeći koraci: 18.7. • Uzeti adresu simbola na koji se referiše • Dodati vrijednost koja se trenutno nalazi na toj lokaciji • Oduzeti adresu poèetka sekcije • Pridodati originalnu adresu poèetka ove sekcije (normalno je ona 0, pošto su .text sekcija obièno na poèetku, a samo kod njih postoji ovaj vid relokacije) • Upisati vrijednost nazad COFF: Linijski brojevi TlineNumbers=Record e:record case Boolean of true: (l_symndx: Longint); { function name symbol index } false: (l_paddr:Longint); { address of line number } end; l_lnno:word; { line number } end; Izvršne sekcije mogu da imaju linijske brojeve, koji su korisni za debagere. Linijski brojevi, međutim, neće biti obrađeni u konvertoru jer informacija o brojevima linija programa u FILDZAN-32 nije bila ugraðena u asemblersku datoteku. 18.8. COFF: Tabela simbola TSymbolTable=record e:record case Boolean of true: (e_name:Array[0..7] of char); false: (e1:record e_zeroes:Longint; e_offset:Longint; end); end; e_value:Longint; e_scnum:Word; e_type:Word; e_sclass:Byte; e_numaux:Byte; end; Tabela simbola je najkompleksniji dio objektne COFF datoteke, jer ima mnogo tipova simbola. Tabela simbola ima ulaze za sve simbole i metasimbole, ukljuèujuæi javne, statičke eksterne, sekcijske i debagerske simbole. e.e_name – Ugniježdeno ime simbola Ako je ime simbola manje ili jednako od 8 znakova, ono se smješta u ovo polje. Ime dugaèko taèno osam znakova se ne završava nulom. Treba primijetiti da se ovo polje memorijski preklapa sa poljem e_zeroes i e_offset e.e.e_zeroes - flag to tell if name is inlined Ako je e_zeroes jednak nuli, ime je duže od osam znakova i nalazi se u tabeli stringova. e.e.e_offset - offset of name in string table Ako je e_zeroes jednak nuli, ovo polje sadrži položaj imena simbola u tabeli stringova. e_value – Vrijednost simbola. Na primjer, ako simbol predstavlja funkciju, ovdje je data adresa funkcije. Značenje ove vrijednosti zavisi od tipa simbola (ispod) 176 e_scnum – Broj sekcije Broj sekcije kojoj pripada ovaj simbol. Prva sekcija u tabeli sekcija je sekcija br. 1. Pored ovoga, e_scnum može imati i sljedeće vrijednosti: N_UNDEF N_ABS N_DEBUG 0 -1 -2 An undefined (extern) symbol An absolute symbol (e_value is a constant, not an address) A debugging symbol e_type – Tip simbola. Ovaj tip simbola je sastavljen od baznog i izvedenog tipa. Na primjer, "pointer to int" je "pointer to T" i "int". Type T_NULL T_VOID T_CHAR T_SHORT T_INT T_LONG T_FLOAT T_DOUBLE T_STRUCT T_UNION T_ENUM T_MOE T_UCHAR T_USHORT T_UINT T_ULONG T_LNGDBL DT_NON DT_PTR DT_FCN DT_ARY Bits ---------------------------------------------------1 --00 --01 --10 --11 Meaning 0000 No symbol 0001 void function argument (not used) 0010 character 0011 short integer 0100 integer 0101 long integer 0110 floating point 0111 double precision float 1000 structure 1001 union 1010 enumeration 1011 member of enumeration 1100 unsigned character 1101 unsigned short 1110 unsigned integer 1111 unsigned long 0000 long double (special case bit pattern) ---- No derived type ---- pointer to T ---- function returning T ---- array of T e_sclass – Klasa smještaja Ovo polje označava gdje se simbol nalazi i šta predstavlja Class C_NULL C_AUTO C_EXT C_STAT C_REG C_EXTDEF C_LABEL C_ULABEL C_MOS C_ARG C_STRTAG C_MOU C_UNTAG C_TPDEF C_USTATIC C_ENTAG C_MOE C_REGPARM C_FIELD C_AUTOARG C_LASTENT C_BLOCK C_FCN C_EOS C_FILE C_LINE C_ALIAS C_HIDDEN C_EFCN Value 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 100 101 102 103 104 105 106 255 Meaning No entry Automatic variable External (public) symbol - this covers globals and externs static (private) symbol register variable External definition label undefined label member of structure function argument structure tag member of union union tag type definition undefined static enumaration tag member of enumeration register parameter bit field auto argument dummy entry (end of block) ".bb" or ".eb" - beginning or end of block ".bf" or ".ef" - beginning or end of function end of structure file name line number, reformatted as symbol duplicate tag ext symbol in dmert public lib physical end of function e_numaux – Broj pomoćnih elemenata. Uz svaki simbol se mogu pridodati dodatni podaci koji se takođe nalaze u tabeli simbola. Za većinu simbola ovaj element je 0. Ipak, kod nekih simbola (npr. ime datoteke) dodatni podaci mogu slijediti i oni se tada preklapaju sa uobičajenim poljima tabele simbola. 18.9. COFF: Tabela stringova Tabela stringova sadrži imena stringova koja su prevelika da stanu u tabelu simbola. Tabela je organizovana tako da na samom početku se nalaze četiri bajta koja predstavljaju njenu dužinu. Nakon toga redom slijede sami stringovi završeni znakom 0. 177 18.10. Program konvertor Nakon što je objašnjena struktura COFF formata slijedi razvoj konvertora. Asembler je generisao program, podatke, labele, popravke i stek (koji se ne koristi u generatoru OBJ) u posebnim datotekama. Datoteke sa programom i podacima se mogu direktno iskopirati u objektnu datoteku, dok je za uključivanje labela u popravki potrebna konverzija formata. Prema redoslijedu koji zahtijeva COFF obje format, kao i potrebnim dobivanjem jednih podataka iz drugih, program treba da uradi sljedeće: • Učita veličinu datoteka sa kodom i podacima (procedura ReadSizes) • Napuni tabelu simbola, (Procedura LoadLabels) iz datoteke sa ekstenzijom .LAB. Pored ovoga se generišu simboli .file, .text, .data i .drectve, koji imaju pomoćne simbole. U pomoćnom simbolu iza simbola .file se smještaju ime datoteke s izvornim kodom, a u ostala tri početak istoimenog segmenta. Prilikom punjenja ove tabele se puni i tabela stringova za sva imena koja su duža od 8 znakova. • Učita tabelu relokacije. (Procedure LoadRelocs) Iz datoteke sa ekstenzijom .PAT se učitaju oni elementi koji zadovoljavaju koji zadovoljavaju jedan od sljedećih uslova: a) Da su u pitanju apsolutne relokacije podataka ili koda (tipovi ‘D’ i ‘A’ unutar .PAT datoteke), što se dalje realizuje relokacijskim tipom RELOC_ADDR32 b) Da su u pitanju relativne relokacije koda, a da je riječ o eksternim simbolima (tip ‘R’ unutar .PAT datoteke), što se dalje realizuje relokacijskim tipom RELOC_REL32 • Otvori datoteku sa OBJ ekstenzijom (Procedura OpenOutObj) • U Obj datoteku upiše zaglavlje u koje je u međuvremenu upisan broj elemenata u svim tabelama (Procedura WriteObjHeader) • Generišu se i upišu u OBJ zaglavlja sekcija (WriteSectionHeaders) • Generiše se .text sekcija (CopyCodeSection) iz .COD datoteke, prebacivši cijeli sadržaj .COD datoteke • Upiše se u OBJ relokacijska tabela (WriteRelocations) • Generiše se .data sekcija (CopyDataSection) iz .DAT datoteke, prebacivši cijeli sadržaj .DAT datoteke • Generiše se .drectve sekcije (WriteStartupSection) upisivanjem imena labele koja je bila navedena iza podatka END u tabeli labela. • Upišu se u izlaznu datoteku svi simboli iz tabele simbola (WriteSymbols) • Upiše se tabela stringova, pazeći da prva četiri bajta budu njena dužina (WriteStringTable) • Zatvori se objektna datoteka • Eventualno obrišu datoteke sa ekstenzijama .COD, .DAT, .LAB, .STA i .PAT jer više nisu potrebne. 18.11. Upotreba programa konvertora Prevedeni program sa naredbom asem (npr. Asem primjer7.asm ) se prevede dalje programom konvertorom COFF, čiji je izvorni kod dat u prilogu. Na primjer: Coff primjer7 Nakon ovoga se dobija OBJ datoteka, koja se može propustiti kroz mnoge linker programe (isprobano sa linkerima LINK, GOLINK i ALINK), povezati sa bibliotekama i dobiti EXE program. Za vježbu je moguće integrisati ovaj konvertor sa asemblerom, tako da se pomoćne datoteke ne generišu ili bar ne vide direktno. 18.12. Rezime poglavlja Ovim korakom je projekt razvoja programskog jezika postao slobodan od tuđeg asemblera. Sljedeći zadatak je vlastiti linker. Korišten je jedan od standardnih objektnih formata, COFF. Ovaj format se sastoji od zaglavlja, sekcija i dodatnih tabela. Zahvaljujući pogodnoj strukturi izlaznih datoteka asemblera, izgradnja konvertora formata u standardni objektni format je prilično pravolinijski zadatak. 178 end else begin if sep=':' then x:='' else begin program Coff; x:=trim(st); uses sysutils; st:=''; const end relocationentrysize=10; end symbolentrysize=18; end; Type Procedure NewSymbol(LabIme:string); { Na pocetku fajla ide FileHeader } var TFileHeader= Record i:integer; Machine:word; { 014C (i386) } begin NumberOfSections: word; { 0003 } TotSym:=TotSym+1; TimeDateStamp: LongInt; { 41543009 -> Fri Sep 24 16:32:41 2004 } with SymbolTable[TotSym] do PointerToSymbolTable: LongInt; begin NumberOfSymbols:LongInt; if length(labime)>8 then begin SizeOfOptionalHeader:word; e.e1.E_zeroes:=0; Characteristics:word; e.e1.e_offset:=StringTabLen+4; end; for i:=1 to length(labime) do begin StringTabLen:=StringTabLen+1; { Odmah nakon slijede opisi sekcija n puta} StringTable[StringTabLen]:=LabIme[i]; TSection=Record end; Name:array[0..7] of char; { section name in ASCII } end PhysicalAddress:Longint; { size mapped into memory } else begin VirtualAddress:Longint; { memory address relative to image base } for i:=1 to length(labime) do begin SizeOfRawData:Longint; { physical size, multiple of file alignment e.e_name[i-1]:=LabIme[i]; } end; PointerToRawData:Longint; { file offset } end; PointerToRelocations:LongInt; { offset of relocation entries } end PointerToLinenumbers:LongInt; { offset of line number entries } end; NumberOfRelocations:word; { number of relocation entries } Procedure NewPublic(PubIme:string); NumberOfLinenumbers:word; { number of line number entries } begin Characteristics:Cardinal; TotPublic:=TotPublic+1; end; PublicTable[TotPublic]:=Pubime+#0; { zatim same sekcije nakon svake sekcije njena relokaciona tabela pa end; tabela simbola } TRelocationTable=record function IsPublicSymbol(Simbol:String):Boolean; r_vaddr:Longint; { address of relocation } var r_symndx:Longint; { symbol we're adjusting for } i:integer; r_type:Longint; { type of relocation } begin end; IsPublicSymbol:=false; for i:=1 to TotPublic do begin TSymbolTable=record if PublicTable[TotPublic]=Simbol then begin e:record IsPublicSymbol:=true; case Boolean of exit; true: (e_name:Array[0..7] of char); end false: (e1:record end; e_zeroes:Longint; e_offset:Longint; end; end); procedure LoadLabels; end; var e_value:Longint; st,labime,labtip,labval,labdsize,entry,publicsym:String; e_scnum:Word; i:integer; e_type:Word; begin e_sclass:Byte; entry:=''; e_numaux:Byte; AssignFile(infile,genname+'.lab'); end; Reset(infile); TotSym:=0; StringTabLen:=0; { U .drectve sekciji se nalazi -entry:ULAZ } NewSymbol('.file'); with SymbolTable[TotSym] do begin var e_scnum:=65535; FileHeader:TFileHeader; e_type:=0; genname:String; e_value:=0; infile:text; e_sclass:=$67; SymbolTable:Array[1..10000] of TSymbolTable; e_numaux:=1; StringTable:Array[1..10000] of char; end; PublicTable:Array[1..1000] of String; NewSymbol('h.asm'); Sections:Array[1..3] of TSection; with SymbolTable[TotSym] do begin RelocationTable:Array[1..10000] of TRelocationTable; e_scnum:=0; TotSym,StringTabLen,TotRelocs,TotPublic, e_type:=0; datahelpsympos,codehelpsympos, e_value:=0; drectvehelpsympos:Longint; e_sclass:=0; CodeSize,DataSize:Longint; e_numaux:=0; drectve:string; end; outobj:file; NewSymbol('@comp.id'); function trim(st:string):String; with SymbolTable[TotSym] do begin begin e_scnum:=65535; while (st<>'') and (st[1]=' ') do st:=copy(st,2,length(st)); e_type:=0; while (st<>'') and (st[length(st)]=' ') do st:=copy(st,1,length(st)e_value:=$001220FC; 1); e_sclass:=3; TRIM:=ST; e_numaux:=0; end; end; NewSymbol('.text'); with SymbolTable[TotSym] do begin procedure izdvoji(var st,x:string; sep:char); e_scnum:=1; var e_type:=0; p:Integer; e_value:=0; begin e_sclass:=3; if st='' then e_numaux:=1; begin end; x:=''; NewSymbol('.texhlp'); exit codehelpsympos:=totsym; end; NewSymbol('.data'); p:=pos(sep,st); with SymbolTable[TotSym] do begin if p>0 then e_scnum:=2; begin e_type:=0; x:=trim(copy(st,1,p-1)); e_value:=0; st:=TRIM(copy(st,p+1,length(st)-p)); LISTING GENERATORA STANDARDNOG OBJ FORMATA 179 e_sclass:=3; e_numaux:=1; end; NewSymbol('.dathlp'); datahelpsympos:=totsym; drectve:=''; while not eof(infile) do begin readln(infile,st); if (pos('END ',st)>0) then begin entry:=copy(st,5,length(st)); drectve:='-entry:'+entry+' '#0; end else if (pos('PUBLIC ',st)=0) then begin st:=st+';'; izdvoji(st,labime,' '); labime:=labime+#0; izdvoji(st,labtip,' '); izdvoji(st,labval,' '); izdvoji(st,labdsize,';'); if (Labtip='3') or (labime=entry+#0) or (ispublicsymbol(labime)) then labime:='_'+labime; NewSymbol(labime); with SymbolTable[TotSym] do begin val(labval,e_value,i); e_numaux:=0; if Labtip='0' {lEqu} then begin e_scnum:=65534; e_sclass:=1; end; if Labtip='1' {lProg} then begin e_scnum:=1; e_sclass:=3; end; if Labtip='2' {lData} then begin e_scnum:=2; e_sclass:=3; end; if Labtip='3' {lExtrn} then begin e_scnum:=0; e_value:=0; e_sclass:=2; end; if labime='_'+entry+#0 then begin e_sclass:=2; end; if LabDsize='0' {8 bit} then e_type:=$2; if LabDsize='1' {16 bit} then e_type:=$3; if LabDsize='2' {32 bit} then e_type:=$20; if LabDsize='3' {64 bit} then e_type:=$6; if LabDsize='4' {80 bit} then e_type:=$7; end; end else begin publicsym:=copy(st,7,length(st)); NewPublic(publicsym); end; end; NewSymbol('.drectve'); with SymbolTable[TotSym] do begin e_scnum:=3; e_type:=0; e_value:=0; e_sclass:=3; e_numaux:=1; end; NewSymbol('.datahlp'); drectvehelpsympos:=totsym; close(infile); end; procedure LoadRelocs; var st,labime,labimeunder,position,relkind:String; i,rez:integer; p1:pchar; posvalint:Longint; label dalje; begin AssignFile(infile,genname+'.pat'); Reset(infile); TotRelocs:=0; while not eof(infile) do begin readln(infile,st); st:=st+';'; izdvoji(st,labime,' '); labime:=labime+#0; labimeunder:='_'+labime; izdvoji(st,position,' '); izdvoji(st,relkind,';'); labime:=copy(labime,1,length(labime)); for i:=1 to TotSym do begin if SymbolTable[i].e.e1.E_zeroes=0 then p1:=Addr(StringTable[SymbolTable[i].e.e1.e_offset-3]) else p1:=Addr(SymbolTable[i].e.e_name[0]); if (strcomp(addr(labime[1]),p1)=0) or (strcomp(addr(labimeunder[1]),p1)= 0) then begin rez:=i-1; goto dalje; end; end; rez:=0; dalje: if rez<>0 then begin val(position,posvalint,i); if (RelKind='R') and (SymbolTable[rez+1].e_scnum=0) then begin TotRelocs:=TotRelocs+1; RelocationTable[TotRelocs].r_vaddr:=posvalint; RelocationTable[TotRelocs].r_symndx:=rez; RelocationTable[TotRelocs].r_type:=20; end; if (RelKind='A') then begin TotRelocs:=TotRelocs+1; RelocationTable[TotRelocs].r_vaddr:=posvalint; RelocationTable[TotRelocs].r_symndx:=rez; RelocationTable[TotRelocs].r_type:=6; end; if (RelKind='D') then begin TotRelocs:=TotRelocs+1; RelocationTable[TotRelocs].r_vaddr:=posvalint; RelocationTable[TotRelocs].r_symndx:=rez; RelocationTable[TotRelocs].r_type:=6; end end; end; close(infile); end; procedure ReadSizes; var f: file of Byte; begin Assign(f,genname+'.cod'); Reset(f); CodeSize:=FileSize(f); Close(f); Assign(f,genname+'.dat'); Reset(f); DataSize:=FileSize(f); Close(f); end; procedure FillSectionHeaders; Var SetName:String; i:Integer; begin with SymbolTable[codehelpsympos] do begin e.e1.e_zeroes:=CodeSize; e.e1.e_offset:=TotRelocs; end; with SymbolTable[datahelpsympos] do begin e.e1.e_zeroes:=DataSize; e.e1.e_offset:=0; end; with SymbolTable[drectvehelpsympos] do begin e.e1.e_zeroes:=Length(drectve)-1; e.e1.e_offset:=0; end; With Sections[1] do begin SetName:='.text'#0; for i:=1 to length(setname) do Name[i-1]:=setname[i]; PhysicalAddress:=0; VirtualAddress:=0; SizeOfRawData:=CodeSize; PointerToRawData:=sizeof(TfileHeader)+3*sizeof(TSection); PointerToRelocations:=PointerToRawData+CodeSize; PointerToLinenumbers:=0; NumberOfRelocations:=TotRelocs; NumberOfLinenumbers:=0; Characteristics:=$60500020; end; With Sections[2] do begin SetName:='.data'#0; for i:=1 to length(setname) do Name[i-1]:=setname[i]; PhysicalAddress:=CodeSize; VirtualAddress:=0; SizeOfRawData:=DataSize; PointerToRawData:=Sections[1].PointerToRelocations+ TotRelocs* relocationentrysize ; PointerToRelocations:=0; PointerToLinenumbers:=0; NumberOfRelocations:=0; NumberOfLinenumbers:=0; Characteristics:=$C0500040; end; With Sections[3] do begin SetName:='.drectve'#0; for i:=1 to length(setname) do Name[i-1]:=setname[i]; PhysicalAddress:=CodeSize+DataSize; VirtualAddress:=0; SizeOfRawData:=length(drectve)-1; PointerToRawData:=Sections[2].PointerToRawData+DataSize; PointerToRelocations:=0; PointerToLinenumbers:=0; NumberOfRelocations:=0; NumberOfLinenumbers:=0; Characteristics:=$00000A00; end; end; procedure FillObjHeader; begin with FileHeader do begin 180 Machine:=$014C; NumberOfSections:=3; TimeDateStamp:=0; PointerToSymbolTable:=sections[3]. PointerToRawData+length(drectve); NumberOfSymbols:=totsym; SizeOfOptionalHeader:=0; Characteristics:=0; end; end; procedure OpenOutObj; begin Assign(outobj,genname+'.obj'); Rewrite(outobj,1); end; procedure writeobjheader; begin BlockWrite(outobj,FileHeader,sizeof(TFileHeader)); end; procedure writesectionheaders; begin BlockWrite(outobj,sections[1],sizeof(TSection)); BlockWrite(outobj,sections[2],sizeof(TSection)); BlockWrite(outobj,sections[3],sizeof(TSection)); end; procedure copycodesection; var f: file of Byte; b: Byte; begin Assign(f,genname+'.cod'); Reset(f); while not(eof(f)) do begin Read(f,b); BlockWrite(outobj,b,1) end; Close(f); end; procedure writerelocations; var i:integer; begin for i:=1 to TotRelocs do begin BlockWrite(outobj,RelocationTable[i],relocationentrysize); end; end; procedure copydatasection; var f: file of Byte; b: Byte; begin Assign(f,genname+'.dat'); Reset(f); while not(eof(f)) do begin Read(f,b); BlockWrite(outobj,b,1) end; Close(f); end; procedure writestartupsection; begin BlockWrite(outobj,drectve[1],length(drectve)); end; procedure writesymbols; var i:integer; begin for i:=1 to TotSym do begin BlockWrite(outobj,SymbolTable[i],symbolentrysize); end; end; procedure writestringtable; var s:Longint; begin s:=stringtablen+4; BlockWrite(outobj,s,4); BlockWrite(outobj,stringtable,StringTabLen); end; procedure DeleteTempFiles; procedure erase1(fn:string); var f:file; begin assignfile(f,fn); erase(f); end; begin erase1(genname+'.cod'); erase1(genname+'.dat'); erase1(genname+'.sta'); erase1(genname+'.lab'); erase1(genname+'.pat'); end; begin genname:=paramstr(1); ReadSizes; loadlabels; loadrelocs; fillsectionheaders; fillobjheader; openoutobj; writeobjheader; writesectionheaders; copycodesection; writerelocations; copydatasection; writestartupsection; writesymbols; writestringtable; close(outobj); if not(paramstr(2)='/k') then deletetempfiles; end. 181 19. LINKER Posljednji korak za dobivanje izvršnog programa je pokretanje linkera. U ovom poglavlju se neće razvijati vlastiti linker, ali će se ući u to šta linker generalno radi. 19.1. Princip rada linkera Linkerov zadatak je da spoji OBJ datoteke u jedinstvenu izvršnu datoteku. Ipak, kada bi stvari bile tako jednostavne linker bi bio obični program koji spaja gomile podataka. Komplikovani dio linkera je posao fiksiranja, o čemu će biti riječi kasnije. Kao i asembler i linker obavlja zadatak u dva prolaza. U prvom prolazu linker sastavi skup pravila za povezivanje, a u drugom primjenjujući ta pravila upisuje izvršnu datoteku. Linker treba da stavi sav kod i podatke iz svake OBJ datoteke u izvršnu datoteku. Ako se linkeru proslijede tri OBJ datoteke tada se kod i podaci iz sve tri OBJ datoteke smješta u EXE. Ali to se ne radi prostim lijepljenjem OBJ datoteka jedne na kraj druge. Umjesto toga linker spaja sve sekcije sa istim imenom u jedinstvenu. Na primjer, tri OBJ datoteke od kojih svaka ima jednu .text sekciju će se povezati u jedinstveni EXE sa jednom .text sekcijom, koja se sastoji od tri individualne .text sekcije kakve su bile u OBJ datoteci. Jedinstvena sekcija se formira spajanjem istoimenih sekcija u redoslijedu kako je proslijeđeno kroz parametre linkeru. Ako su linkeru proslijeđeni parametri A.OBJ B.OBJ C.OBJ Linker će spojiti ove OBJ datoteke kao što je prikazano na slici Sl. 19.1.1. U promjeru sa slile se uočava da sve sekcije sa istim imenom se spajaju u jedinstvene sekcije _text i _data, dok se sekcije sa jedinstvenim imenom smještaju po redu. Sekcije koje u svom imenu imaju znak $ predstavljaju izuzetak. Kod ovih sekcija se ignoriše dio imena iza znaka $ kao i sam ovaj znak. Na primjer, mogu postojati sekcija sa imenima info$a, info$b i info$other. Sve one će se spojiti u jedinstvenu sekciju sa imenom info. Pored pravila sa znakom $, standardni prioritet redoslijeda sekcija se podešava označavajući ih specijalnim atributima. Sekcije sa atributom koda se smještaju prve u izvršni program, zatim slijede sekcije sa neinicijaliziranim podacima (ako ih ima, a koji se smještaju u .bss sekciju), sekcije sa inicijaliziranim podacima (uključujući .data sekcija), zatim sekcije generisane linkerom kao što je .reloc. Obično se na kraj EXE programa smješta .debug sekcija, jer se ona ne mora uvijek učitavati. Sekcije sa atributima LINK_REMOVE i LINK_INFO, a koje se zovu .drectve se ne ugrađuju u EXE program. One se koriste da se proslijede parametri linkeru Sl. 19.1.1. 19.2. Primjer spajanja sekcija u OBJ Fiksiranja i relokacije Zašto kompajler prosto ne generiše izvršnu datoteku direktno iz izvorne, eliminišući potrebu za linkerom? Iako ima i takvih kompajlera, glavni razlog je što se većina programa ne sastoji od jedne datoteke sa izvornim kodom. Kompajleri su specijalizovani za preuzimanje jedne datoteke sa izvornim kodom proizvodeći sirovi ekvivalent u mašinskom kodu. Pošto izvorna datoteka može imati reference na kod ili podatke izvan izvorne datoteke, kompajler ne može generisati egzaktno pravi kod koji poziva tu funkciju ili pristupa toj varijabli. Umjesto toga, kompajler uključuje dodatne informacije u izlaznu datoteku koja opisuje spoljni kod ili podatke. Te informacije se zovu popravke, jer je kod kojim se pristupa eksternim funkcijama i varijablama nekorektan i mora se popraviti kasnije. Neka na primjer treba pozvati podprogram naredbom CALL PODPROGRAM Asembler će na ovom mjestu, ako se podprogram ne nalazi u istoj datoteci sa izvornim kodom, generisati mašinski kod: E8 00 00 00 00 Očigledno, E8 je kod instrukcije CALL, a ove četiri nule su adresa potprograma. Očigledno je da podprogram neće biti udaljen 0 bajtova od naredbe CALL. Ovaj dio koda je neispravan i mora se popraviti. 182 U datom primjeru, linker sada zamjenjuje ova četiri bajta iza CALL naredbe korektnom adresom potprograma. On će znati da ih treba zamijeniti preko informacije iz sloga popravki. Korektnu adresu saznaje sam linker spajajući sekcije. Postoje tri vrste slogova popravki. Popravka REL32 znači da nova adresa treba da se upiše relativno od adrese na kojoj se vrši popravka. U primjeru sa CALL naredbom treba zamijeniti ove četiri nule popravkom REL32. Ukoliko su se ove nule nalazile na adresi 1000, a nakon spajanja modula PODPROGRAM upadne na adresu 2530, umjesto nula upisuje se 1530. Podprogram se dakle poziva sa relativnom adresom i na taj način je omogućena relokatibilnost. Ovaj tip popravke se ne upisuje u izvršnu datoteku. Popravka DIR32 je predviđena za popravku apsolutnih adresa. Pogledati sljedeći primjer. MOV EAX,VRIJEDNOST VRIJEDNOST DD 43332 Neka se labela VRIJEDNOST nalazi na adresi 00002E03 Asembler će prevesti prvu instrukciju u apsolutnu adresiranje, npr. B8 03 2E 00 00. Učita li se program na adresu 00600000, i instrukcija MOV EAX se mora mijenjati, na primjer u B8 03 2E 40 00 jer je labela VRIJEDNOST sada na adresi 00602E03. Nova vrijednost koju linker upiše nakon DIR32 popravke jednaka je zbiru podrazumijevane startne adrese programa i prethodne vrijednosti koja se nalazila na adresi koja se popravlja. Podrazumijevana startna adresa je 00400000h, pa linker treba u našem slučaju da primjeni sabiranje konstanti 00400000h i 00002E03h i upiše adresu 00402E03h. Windowsov loader će, ukoliko postoji .reloc sekcija, obaviti ovaj zadatak još jednom, ali samo ako se program učitava na nepodrazumijevanu adresu. Tada se za svaki DIR32 slog sabira vrijednost na adresi koju popravljamo sa razlikom između podrazumijevane i stvarne adrese gdje je program učitan. Treći tip popravke DIR32NB (Direct 32, No Base), se koristi za debagerske informacije. Ova popravka se razlikuje od DIR32 što ne sadrži podrazumijevanu adresu učitavanja izvršnog programa. 19.3. Biblioteke Često je potrebno spojiti više OBJ datoteka u jedinstvenu datoteku koja se zatim prosljeđuje linkeru. Tipični primjer je izvršna biblioteka jezika C++, koja se zove LIBC.LIB. U njoj se nalazi mnogo OBJ datoteka koje obavljaju funkcije kao što su printf, sin, atoi ili fopen. Biblioteke se sastoje od zaglavlja biblioteke i zatim kopija OBJ datoteka koje su ugrađene u biblioteku. Za razliku od OBJ datoteka direktno proslijeđenih linkeru kroz parametre, linker ne mora uključiti u EXE program sve OBJ datoteke ugrađene u biblioteku. OBJ datoteke unutar biblioteke će biti ugrađene samo ako se koristi bar jedna varijabla ili podprogram iz njih. Ako program iz objektne datoteke koja se uključuje EXE poziva neki podprogram, npr. printf, i linker pronađe objektnu datoteku unutar biblioteke u kojoj se nalazi podprogram printf, ta datoteka se ugrađuje u EXE. Ali ne samo ona. Neka printf dalje poziva putchar koji je u svojoj OBJ datoteci, a putchar opet poziva checkvideomode koji je u trećoj OBJ datoteci. Tada će sve tri OBJ datoteke biti uključene u EXE. Specijalna grupa biblioteka su importne biblioteke. Strukturalno, one se ne razlikuju od regularnih biblioteka, niti ih linker razlikuje kada razrješava simbole. Ključna razlika je u tome što importne biblioteke nisu nastale iz izvornog koda i OBJ datoteka proizvedenih od njega. Importne biblioteke pravi linker prilikom povezivanja drugog EXE, odnosno DLL programa. Ove biblioteke se baziraju na importnim tabelama. 19.4. Pravljenje importne tabele Jedna od najznačajnijih osobina 32 bitnog Windows-a je mogućnost importa funkcija iz drugih EXE i DLL programa. Sve ove informacije o uključenim DLL nalaze se u importnoj tabeli. Importna tabela se obično smješta u sekciju .idata. Izgleda neobično da linker u stvari ne brine da li se pozvani podprogram nalazi unutar EXEa ili u spoljašnjem DLLu. Prostim praćenjem pravila spajanja sekcija i razrješavanja simbola linker pravi importnu tabelu, neinformisan o specijalnom značenju ove tabele. 1121 public symbols EA14 _ActivateKeyboardLayout@8 ... Archive member name at EA14: USER32.dll/ ... 183 SECTION HEADER #2 .text name RAW DATA #2 00000000 FF 25 00 00 00 00 .%.... ... SECTION HEADER #4 .idata$5 name RAW DATA #4 00000000 00 00 00 00 .... ... SECTION HEADER #5 .idata$4 name RAW DATA #5 00000000 00 00 00 00 .... ... SECTION HEADER #6 .idata$6 name RAW DATA #6 00000000 00 00 41 63 74 69 76 61 | 74 65 4B 65 79 62 6F 61 ..Activa|teKeyboa 00000010 72 64 4C 61 79 6F 75 74 | 00 00 rdLayout|.. ... COFF SYMBOL TABLE ... 003 00000000 SECT2 notype () External | _ActivateKeyboardLayout@8 Pogleda li se dio importne biblioteke USER32.LIB na gornjoj slici može se zaključiti kako linker obrađuje importne datoteke. Neka je pozvana API funkcija ActivateKeyboardLayout. Slog popravke za _ActivateKeyboardLayout@8 se nalazi OBJ datoteci korisničkog programa. U zaglavlju biblioteke USER32.LIB linker zaključuje da se ova funkcija nalazi u OBJ datoteci na poziciji 0xEA14. Time se linkeru da do znanja da se ova OBJ biblioteka uključi u EXE. A u njoj ima više sekcija, kao što su .text, .idata$5, .idata$4, and .idata$6. U .text sekciji je JMP instrukcija (FF 25 00 00 00 00). Iz COFF tabele simbola se vidi da se _ActivateKeyboardLayout@8 nalaz na početku druge sekcije, a to znači da će poziv CALL _ActivateKeyboardLayout@8 rezultovati JMP instrukcijom Treba primijetiti da sekcije .idata$4, .idata$5 i .idata$6 sadrže podatke za importnu tabelu. Koristeći pravilo da se sekcije čije ime sadrži znak $ grupišu u jedinstvene sekcije sa imenom koje se nalazi prije znaka $, importna tabela se generiše redovnim poslom linkera. 19.5. Kreiranje eksportne tabele Pored kreiranja importnih tabela za izvršne programe, linker je odgovoran i za obrnuti zadatak, eksportne tabele. Ovdje je zadatak linkera istovremeno lakši i teži. U prvom prolazu, linker sakuplja informacije o svim eksportovanim simbolima i kreira tabelu eksportovanih funkcija. To se sekciju .edata posebne OBJ datoteke koja je preimenovana u ekstenziju EXP iako je po strukturi standardna OBJ datoteka. U drugom prolazu se EXP ugradi u EXE kao i svaka standardna OBJ datoteka, mada mnogi linkeri spajaju sekcije .rdata i .edata. 19.6. Drugi zadaci linkera Pored navedenog, linkeri ubacuju informacije potrebne za debager, kreiranje MAP datoteka koje daju informaciju o tome šta je uključeno u izvršni program te dodavanje programčića koji se starta ako je EXE pokrenut iz MS DOSa. Ali, ovo nisu obavezni zadaci jednog linkera, nego više korisne pomoćne funkcije. O projektu razvoja linkera vidjeti http://www.iecc.com/linker/ 19.7. Rezime poglavlja Linker je alatka koja povezuje više prevedenih jedinica u funkcionalni izvršni program. Njegov ključni zadatak je spajanje sekcija, a drugi je razrješavanje referenci (popravke) između kombinovanih sekcija. Više OBJ datoteka se povezuju u biblioteke. Biblioteke koje ne sadrže kod, nego samo informacije o adresama unutar EXE ili DLL se zovu importne biblioteke. Da bi se napravile importne datoteke koriste se importne i eksportne tabele. 184 20. INTERPRETER Drugi popularni koncept za realizaciju viših programskih jezika, pored kompajlera su interpreteri. U ovom poglavlju će biti opisan jedan od načina pravljenja interpretera 20.1. Interpreteri i jezici za njihov razvoj Iako se mnogi interpreteri pišu u asembleru radi što veće brzine rada, interpretere je, za razliku od kompajlera, moguće pisati potpuno u višem programskom jeziku i bez ikakvog znanja o arhitekturi mašine na kojoj se interpreter izvršava. Pored ovoga, za pisanjem vlastitog interpretera potreba je češća nego za pisanjem vlastitog kompajlera, jer je u mnogim aplikacijama potrebno dodati neki skriptni jezik. 20.2. Interpretirani jezik U ovom primjeru implementirati će se interpreter vrlo primitivne verzije BASICa. Ova verzija ima 26 cjelobrojnih varijabli pod imenom a,b,c ... , z. Naredbe su PRINT <izraz> prikaz aritmetičkog izraza LET <varijabla> = <izraz> dodjela vrijednosti varijabli INPUT <varijabla> unošenje vrijednosti varijable LIST prikaz cijelog programa IF <izraz1> THEN <izraz2> skok na liniju <izraz2> ako je <izraz1> različit od 0 GOTO <izraz> bezuslovni skok END kraj programa ili izlazak iz interpretera Kao u klasičnom, danas pomalo zaboravljenom, BASICu, naredbe se mogu izvršiti direktno kucanjem ili se ispred naredbe može staviti linijski broj kada se ona smješta u program. 20.3. Linijski editor Prvo je potrebno realizovati smještanje linija programa. Da bi interpreter bio što jednostavniji, program se čuva u nizu od 1000 stringova. Naravno da je ovo najneracionalniji način, i da bi trebalo ići na dinamičke strukture podataka, ali bi i listing interpretera tada bio veći. Linije (kojima se radi lakše interpretacije dodaje simbol ';') se unose Pascal-skom naredbom readln (ili se uzimaju iz niza linija) i, kada se linija unese, provjerava se da li ona počinje cifrom. Ako linija počinje cifrom , prepozna se linijski broj i tekst linije bez linijskog broja se smjesti u navedeni element niza stringova koji odgovara liniji sa tim linijskim brojem. Ako linija ne počinje cifrom, prelazi se u analizu naredbe i njeno izvršavanje. Nakon toga je interpreter spreman za izvršenje ili unos nove naredbe. 20.4. Interpreterska petlja Interpreter, dakle, ima dva režima rada, komandni i programski. U komandnom režimu rada naredba se očitava preko readln , a u programskom režimu iz niza stringova o kome su naredbe. Nakon dohvaćene naredbe slijedi njeno prepoznavanje i izvršenje, a zatim se u programskom režimu rada traži sljedeća instrukcija. Ako je prethodna instrukcija bila instrukcija GOTO ili IF, naredna instrukcija je navedena kao argument ove instrukcije. U ostalim slučajevima, to je prva naredna neprazna instrukcija, što se traži uvećanjem broja trenutne instrukcije (varijabla izvrlinija) za jedan, sve dok se ne dođe do naredbe koja nije prazna ili dok se ne dostigne linija 1000. Glavna interpreterska petlja izgleda ovako: procedure Glavni; var brlinije:integer; begin quit:=false; repeat if inprogram then linija:=naredbe[izvrlinija] else readln(linija); linija:=uppercase(linija); gr:=false; linija:=linija+';'; pozicija:=0; novi; if znak in ['0'..'9'] then begin if slijedi('INPUT')then DoInput else brlinije:=uzmikonstantu; if slijedi('END') then DoEnd else if (brlinije>0) and Greska('Nepoznata naredba'); (brlinije<1000) then begin end; linija:=trim(copy( if inprogram then begin linija,pozicija, if not skok then length(linija))); repeat if linija=';' then linija:=''; izvrlinija:=izvrlinija+1; naredbe[brlinije]:=linija; until (izvrlinija>=1000) or end (naredbe[izvrlinija]<>''); end if izvrlinija=1000 then else begin inprogram:=false; if slijedi('PRINT')then DoPrint else skok:=false; if slijedi('LIST') then Dolist else end; if slijedi('GOTO') then DoGoto else until quit; if slijedi('LET') then DoLet else end; if slijedi('IF') then DoIf else 185 20.5. Realizacija aritmetičkih izraza Dosta znanja iz pisanja kompajlera se može primijeniti na pisanje interpretera. Glavna razlika je što umjesto generisanog koda koji izlazi kao listing treba simulirati izvršenje odgovarajućih naredbi. Tako na primjer, u trećoj verziji kompajlera dio koda koji je realizovao jezički pojam Clan izgledao je ovako procedure Clan; var z: char; begin Faktor; while (znak in ['*', '/', '%']) do begin z := znak; Emit(' PUSH EAX'); Novi; Faktor; case z of '*': begin Emit(' POP EBX'); Emit(' IMUL EBX'); end; '/', '%': begin Emit(' MOV EBX,EAX'); Emit(' POP EAX'); Emit(' CDQ'); Emit(' IDIV EBX'); if z = '%' then Emit(' MOV EAX,EDX'); end; end; end; end; Emitovanje mašinskih naredbi treba zamijeniti procedurama koje rade ekvivalentnu stvar, pa će u interpreteru procedura Clan izgledati ovako: procedure Clan; var z: char; begin Faktor; if gr then exit; while (znak in ['*', '/', '%']) do begin z := znak; push(eax); if gr then exit; Novi; if gr then exit; Faktor; if gr then exit; case z of '*': begin ebx:=pop; eax:=eax*ebx; end; '/', '%': begin ebx:=eax; eax:=pop; if ebx<>0 then begin if z = '%' then eax:=eax mod ebx else eax:=eax div ebx end else Greska('Dijeljenje s nulom'); end; end; end; end; Kao što se vidi, iako se uočava razlika što postoje varijable eax i ebx , i procedure push i pop koje rade sa simuliranim stekom, struktura procedure je ista. Umjesto generisanih asemblerskih naredbi koje rade ekvivalentan efekat, izvršavaju se adekvatne operacija nad varijablama eax i ebx. Pošto u interpreteru greška ne smije izazvati prekid rada samog interpretera nego samo interpretiranog programa, nakon svakog potprograma se provjerava da li je izazvana greška naredbom if gr then exit; dok sama procedura Greska nema naredbe halt koja izaziva prekid rada. Ova procedura treba da pored ispisa teksta poruke i da postavi varijablu gr na tačnu vrijednost. Za simuliranje steka, baš kao kod mašinskog steka, i ovdje se koristi sp kao oznaka trenutne pozicije na steku. Funkcija pop i procedura push izgledaju ovako: function pop:integer; begin pop:=0; if gr then exit; if (sp<=0) or (sp>100) then begin Greska('Izraz'); pop:=0; end else begin pop:=stek[sp]; sp:=sp-1; end; end; procedure push(n:integer); begin if gr then exit; if (sp<0) or (sp>=100) then begin Greska('Izraz'); end else begin sp:=sp+1; stek[sp]:=n; end; end; I kod ostalih procedura za izračunavanje izraza vidi se sličnost sa istoimenim procedurama iz treće verzije kompajlera. U cilju skraćenja koda, izbačen je pojam IzrazDodjeljivanja, a operatori >,< i = prebačeni na isti prioritet kao i sabiranje i oduzimanje. Varijable su predstavljene nizom od 26 cijelih brojeva. Pristup pojedinoj varijabli se svodi na proračun pozicije u nizu na osnovu imena varijable, a zatim se očitava odgovarajući element niza. 20.6. Realizacija naredbi primitivnog BASICa Zahvaljujući činjenici da prevedeni program napisan u Pascalu već ima sve potrebne rutine, realizacija samih naredbi je trivijalna. Tako se naredba print realizuje kao 186 procedure DoPrint; begin Novi; if gr then exit; Izraz; if gr then exit; writeln(eax); end; Procedurom Novi se pređe na sljedeći znak ulazne linije. Procedurom Izraz se izračuna aritmetički izraz i njegov rezultat dobije u varijabli eax. Analogno se dobijaju realizacije ostalih naredbi, što se može vidjeti u kompletnom programu 20.7. Instrukcije za dohvatanje simbola Funkcije novi, slijedi i idido su preuzete iz koda korištenog u trećoj verziji kompajlera, a zatim pojednostavljene jer je interpreter linijski orijentisan. Tako u proceduri Novi nema potrebe prelaziti u sljedeću liniju, nego se sve provjere vrše unutar jedne linije, kao u sljedećoj implementaciji ove procedure. procedure Novi; begin if gr then exit; repeat pozicija := pozicija + 1; if pozicija > Length(linija) then Greska('Preko kraja linije') else znak:=linija[pozicija]; until (pozicija>Length(linija)) or (znak<>' '); end; Dodane su i procedure Uppercase i Trim za pretvaranje malih slova u velika odnosno izbacivanje blankova iz stringova. 20.8. Listing interpretera primitivnog BASICa Slijedi kompletan listing ovog interpretera: program Interpreter; var linija: string; pozicija,izvrlinija:integer; naredbe: Array [1..1000] of string; varijable:Array [0..25] of integer; znak:char; stek:array[0..100] of integer; sp,eax,ebx:integer; inprogram,quit,skok,gr:Boolean; function trim(st:string):String; begin while (st<>'') and (st[1]=' ') do st:=copy(st,2,length(st)); while (st<>'') and (st[length(st)]=' ') do st:=copy(st,1,length(st)-1); TRIM:=ST; end; function uppercase(st:string):String; var i:integer; begin for i:=1 to length(st) do if (st[i]>='a') and (st[i]<='z') then st[i]:=chr(ord(st[i])-32); uppercase:=st; end; procedure Greska(poruka: string); begin if inprogram then Writeln(poruka,' u liniji ', izvrlinija) else WriteLn(poruka); inprogram:=false; gr:=true; sp:=0; end; function pop:integer; begin pop:=0; if gr then exit; if (sp<=0) or (sp>100) then begin Greska('Izraz'); pop:=0; end else begin pop:=stek[sp]; sp:=sp-1; end; end; procedure push(n:integer); begin if gr then exit; if (sp<0) or (sp>=100) then begin Greska('Izraz'); end else begin sp:=sp+1; stek[sp]:=n; end; end; procedure Novi; begin if gr then exit; repeat pozicija := pozicija + 1; if pozicija > Length(linija) then Greska('Preko kraja linije') else znak:=linija[pozicija]; until (pozicija>Length(linija)) or (znak<>' '); end; procedure IdiDo(z: char); begin if gr then exit; if (znak <> z) then Greska('Ocekivano' + z); Novi; if gr then exit; end; function Slijedi(ocekivano: string): Boolean; begin SLijedi:=false; if gr then exit; if (copy(linija,pozicija, Length(ocekivano)) = ocekivano) then begin Slijedi := true; pozicija := pozicija + Length(ocekivano) - 1; end else Slijedi := false; end; function UzmiKonstantu: integer; var rezultat: integer; begin UzmiKonstantu:=0; if gr then exit; rezultat := 0; while (znak >= '0') and (znak <= '9') do begin rezultat := 10 * rezultat + ord(znak) - ord('0'); Novi; if gr then exit; end; if (znak = ' ') or (znak = '`') then Novi; if gr then exit; UzmiKonstantu := rezultat; end; procedure Varijabla; var rezultat: integer; begin if gr then exit; rezultat := (ord(znak) ord('A')); eax:=varijable[rezultat]; ebx:=rezultat; Novi; if gr then exit; end; procedure Izraz;forward; procedure Faktor; var rezultat: integer; begin case znak of '-': begin Novi; if gr then exit; Faktor; if gr then exit; eax:=-eax; end; '~': begin Novi; if gr then exit; Faktor; if gr then exit; eax:=not(eax); end; '!': begin Novi; if gr then exit; Faktor; if gr then exit; if eax=0 then eax:=1; end; '0'..'9': begin rezultat := UzmiKonstantu; eax:=rezultat; end; '(': begin Novi; if gr then exit; 187 Izraz; if gr then exit; IdiDo(')'); if gr then exit; end; 'A'..'Z': begin Varijabla; if gr then exit; end else Greska('Izraz'); end; end; procedure Clan; var z: char; begin Faktor; if gr then exit; while (znak in ['*', '/', '%']) do begin z := znak; push(eax); if gr then exit; Novi; if gr then exit; Faktor; if gr then exit; case z of '*': begin ebx:=pop; eax:=eax*ebx; end; '/', '%': begin ebx:=eax; eax:=pop; if ebx<>0 then begin if z = '%' then eax:=eax mod ebx else eax:=eax div ebx end else Greska('Dijeljenje s nulom'); end; end; end; end; procedure Izraz; var z: char; begin Clan; while (znak in ['+', '-', '&', '|', '^','>','<','=']) do begin push(eax); z := znak; Novi; if gr then exit; Clan; if gr then exit; case z of '+': begin ebx:=pop; eax:=eax+ebx; end; '=': begin ebx:=pop; if eax=ebx then eax:=1 else eax:=0; end; '>': begin ebx:=pop; if ebx>eax then eax:=1 else eax:=0; end; '<': begin ebx:=pop; if ebx<eax then eax:=1 else eax:=0; end; '-': begin 20.9. ebx:=eax; eax:=pop; eax:=eax-ebx; end; '&': begin ebx:=pop; eax:=eax and ebx; end; '|': begin ebx:=pop; eax:=eax or ebx; end; '^': begin ebx:=pop; eax:=eax xor ebx; end; end; end; end; procedure DoPrint; begin Novi; if gr then exit; Izraz; if gr then exit; writeln(eax); end; procedure DoGoto; begin novi; if gr then exit; Izraz; if gr then exit; izvrlinija:=eax; inprogram:=true; skok:=true; end; procedure DoLet; var dodvar:char; begin Novi; if gr then exit; dodvar:=znak; if dodvar in ['A'..'Z'] then begin Novi; if gr then exit; IdiDo('='); if gr then exit; izraz; varijable[ord(dodvar)ord('A')]:=eax; end else Greska('Varijabla'); end; procedure DoInput; var unizraz:string; dodvar:Char; begin Novi; if gr then exit; dodvar:=znak; if dodvar in ['A'..'Z'] then begin write('?'); readln(unizraz); if gr then exit; linija:=unizraz+';'; pozicija:=0; Novi; if gr then exit; Izraz; if gr then exit; varijable[ord(dodvar)ord('A')]:=eax; end else Greska('Varijabla'); end; procedure DoIf; begin Novi; if gr then exit; Izraz; if gr then exit; if eax<>0 then begin if not(slijedi('then')) then Greska ('Then'); if gr then exit; Novi; if gr then exit; Izraz; if gr then exit; IzvrLinija:=eax; skok:=true; end; end; procedure doEnd; begin if inprogram then inprogram:=false else quit:=true end; procedure DoList; var i:integer; begin for i:=1 to 1000 do if naredbe[i]<>'' then writeln(i,' ',copy(naredbe[i],1, length(naredbe[i])-1)); end; procedure Glavni; var brlinije:integer; begin quit:=false; repeat if inprogram then linija:=naredbe[izvrlinija] else readln(linija); linija:=uppercase(linija); gr:=false; linija:=linija+';'; pozicija:=0; novi; if znak in ['0'..'9'] then begin brlinije:=uzmikonstantu; if (brlinije>0) and (brlinije<1000) then begin linija:=trim(copy( linija,pozicija, length(linija))); if linija=';' then linija:=''; naredbe[brlinije]:=linija; end end else begin if slijedi('PRINT')then DoPrint else if slijedi('LIST') then Dolist else if slijedi('GOTO') then DoGoto else if slijedi('LET') then DoLet else if slijedi('IF') then DoIf else if slijedi('INPUT')then DoInput else if slijedi('END') then DoEnd else Greska('Nepoznata naredba'); end; if inprogram then begin if not skok then repeat izvrlinija:=izvrlinija+1; until (izvrlinija>=1000) or (naredbe[izvrlinija]<>''); if izvrlinija=1000 then inprogram:=false; skok:=false; end; until quit; end; begin Glavni end. Rezime poglavlja Pisanje interpretera može biti jednostavniji zadatak od pisanja kompajlera, jer se interpreter može napisati bez znanja mašinskog jezika. Umjesto generisanja koda, naredbe se izvršavaju simulirajući odgovarajući asemblerski kod. U ovom poglavlju realizovana je primitivna verzija BASICa, ali dobiveni program može biti polazna osnova za dalje proširenje jezika 188 21. SADRŽAJ 1. VRSTE SISTEMSKOG SOFTVERA...............................................................................................................................3 1.1. 1.2. 1.3. 1.4. 1.5. 1.6. 2. PROCESOR I OPERATIVNI SISTEM ZA KOJE SE GENERIŠE KÔD ...................................................................5 2.1. 2.2. 2.3. 2.4. 2.5. 3. PROŠIRENJE ARITMETIČKIH IZRAZA ................................................................................................................................20 USLOVI ...........................................................................................................................................................................22 PETLJE ............................................................................................................................................................................23 GENERALIZOVANI JEZIČKI POJAM BLOK ..........................................................................................................................24 TESTNI PRIMJER ..............................................................................................................................................................25 REZIME POGLAVLJA ........................................................................................................................................................25 KLJUČNE RIJEČI, STRINGOVI, DINAMIČKI NIZOVI I FUNKCIJE..................................................................27 7.1. 7.2. 7.3. 7.4. 7.5. 7.6. 7.7. 8. FORMAT INSTRUKCIJA ....................................................................................................................................................15 BLOKOVI.........................................................................................................................................................................15 MODIFIKACIJE PROCEDURA KOMPAJLERA ZBOG PREVOĐENJA IZ DATOTEKE ..................................................................15 MODIFIKACIJE KOMPAJLERA ZBOG GENERISANJA DATOTEKA SA ASEMBLERSKIM KODOM..............................................16 PROŠIRENJA ARITMETIČKIH IZRAZA ................................................................................................................................16 TESTNI PRIMJER ..............................................................................................................................................................17 REZIME POGLAVLJA ........................................................................................................................................................19 VARIJABLE, RELACIONI OPERATORI, USLOVI, PETLJE .................................................................................20 6.1. 6.2. 6.3. 6.4. 6.5. 6.6. 7. STRUKTURA TIPIČNIH ARITMETIČKIH IZRAZA .................................................................................................................10 SINTAKSNA ANALIZA ARITMETIČKIH IZRAZA ..................................................................................................................11 GENERISANJE KODA ZA RAČUNANJE ARITMETIČKE IZRAZE.............................................................................................11 PRVA VERZIJA KOMPAJLERA ...........................................................................................................................................12 TESTNI PRIMJER ..............................................................................................................................................................13 REZIME POGLAVLJA ........................................................................................................................................................14 PREVOĐENJE IZ DATOTEKA, BLOKOVI, VIŠECIFRENI BROJEVI..............................................................15 5.1. 5.2. 5.3. 5.4. 5.5. 5.6. 5.7. 6. ITERATIVNI PRISTUP ..........................................................................................................................................................7 PRIMJENA GENERATORA KODA .........................................................................................................................................7 ANALIZA GOTOVOG KOMPAJLERA ....................................................................................................................................7 CRENSHAW-OVA NETEHNIČKA METODA ...........................................................................................................................8 WATERFALL I SPIRALNI PRISTUP RAZVOJU INFORMACIONIH SISTEMA ...............................................................................8 PROGRAMSKI JEZIK U KOME SE RAZVIJA KOMPAJLER ........................................................................................................9 HARDVERSKO I SOFTVERSKO OKRUŽENJE ZA KOJE SE RAZVIJA KOMPAJLER .....................................................................9 REZIME POGLAVLJA ..........................................................................................................................................................9 PROSTI ARITMETIČKI IZRAZI .................................................................................................................................10 4.1. 4.2. 4.3. 4.4. 4.5. 4.6. 5. REGISTRI...........................................................................................................................................................................5 ADRESNI REŽIMI ...............................................................................................................................................................5 INSTRUKCIJE .....................................................................................................................................................................5 OPERATIVNI SISTEM ..........................................................................................................................................................6 REZIME POGLAVLJA ..........................................................................................................................................................6 UOBIČAJENI PRISTUPI U RAZVOJU KOMPAJLERA ............................................................................................7 3.1. 3.2. 3.3. 3.4. 3.5. 3.6. 3.7. 3.8. 4. SISTEMSKI SOFTVER..........................................................................................................................................................3 SISTEMSKI SOFTVER ZA KONTROLU IZVRŠENJA PROGRAMA ..............................................................................................3 SOFTVER ZA KORISNIČKO OKRUŽENJE ..............................................................................................................................3 RAZVOJNI ALATI ...............................................................................................................................................................3 POMOĆNE ALATKE ............................................................................................................................................................4 REZIME POGLAVLJA ..........................................................................................................................................................4 KLJUČNE RIJEČI ..............................................................................................................................................................27 KOMENTARI I NEIGNORISANJE SIMBOLA .........................................................................................................................27 MODIFIKACIJA USLOVA I PETLJI ......................................................................................................................................28 MODIFIKACIJE ARITMETIČKIH IZRAZA I UVOĐENJE STRINGOVA ......................................................................................28 FUNKCIJE I PROCEDURE ..................................................................................................................................................29 TESTNI PRIMJER ..............................................................................................................................................................31 REZIME POGLAVLJA ........................................................................................................................................................33 DEKLARACIJE VARIJABLI, STANDARDNE FUNKCIJE......................................................................................36 8.1. TABELA IDENTIFIKATORA ...............................................................................................................................................36 8.2. 8.3. 8.4. 8.5. 8.6. 8.7. 8.8. 9. 189 TIPOVI ............................................................................................................................................................................37 DEKLARISANJE VARIJABLI I NOVA STRUKTURA PROGRAMA ............................................................................................37 IZRAZI I SEMANTIKA .......................................................................................................................................................38 TABLICE GENERISANOG KODA ZA RAZLIČITE OPERANDE ................................................................................................39 FUNKCIJE I PROVJERA PARAMETARA...............................................................................................................................43 TESTNI PRIMJER ..............................................................................................................................................................45 REZIME POGLAVLJA ........................................................................................................................................................46 REALNI BROJEVI ..........................................................................................................................................................51 9.1. 9.2. 9.3. 9.4. 9.5. 9.6. 9.7. 9.8. 10. KOPROCESOR ..................................................................................................................................................................51 REALNE KONSTANTE ......................................................................................................................................................51 KOMUNIKACIJA IZMEĐU FP STEKA I MEMORIJE ..............................................................................................................51 ARITMETIČKE OPERACIJE ................................................................................................................................................52 REALNE VARIJABLE ........................................................................................................................................................53 FUNKCIJE REALNOG ARGUMENTA I UNARNI OPERATORI .................................................................................................54 TESTNI PRIMJER ..............................................................................................................................................................54 REZIME POGLAVLJA ........................................................................................................................................................55 SLOŽENI TIPOVI PODATAKA....................................................................................................................................61 10.1. 10.2. 10.3. 10.4. 10.5. 11. PREDPROCESIRANJE I OPTIMIZACIJA KODA ....................................................................................................74 11.1. 11.2. 11.3. 11.4. 11.5. 11.6. 11.7. 11.8. 12. PRIMJER: BAZE PODATAKA I KORISNIČKI INTERFEJS ..................................................................................................81 PRIMJER: MULTIMEDIJA.............................................................................................................................................83 PRIMJER: WEB SERVER ..............................................................................................................................................83 PRIMJER: NUMERIČKA ANALIZA ................................................................................................................................85 REZIME POGLAVLJA ...................................................................................................................................................85 TEORIJA JEZIKA I PARSIRANJA..............................................................................................................................98 13.1. 13.2. 13.3. 13.4. 13.5. 13.6. 13.7. 13.8. 13.9. 13.10. 14. STRUKTURA KOMPAJLERA .........................................................................................................................................74 PREDPROCESORSKA DIREKTIVA #DEFINIRAJ ..............................................................................................................74 DIREKTIVE USLOVNOG KOMPAJLIRANJA ....................................................................................................................74 DIREKTIVA #DODAJ ZA UKLJUČIVANJE DATOTEKE .....................................................................................................75 REALIZACIJA PREDPROCESORA ..................................................................................................................................75 OPTIMIZACIJA KODA ..................................................................................................................................................75 TESTNI PRIMJER OPTIMIZACIJE ...................................................................................................................................79 REZIME POGLAVLJA ...................................................................................................................................................80 TESTNI PRIMJERI .........................................................................................................................................................81 12.1. 12.2. 12.3. 12.4. 12.5. 13. VIŠEDIMENZIONALNI NIZOVI ......................................................................................................................................61 INDIREKTNI POZIV FUNKCIJE ......................................................................................................................................62 SLOGOVI ....................................................................................................................................................................63 TESTNI PRIMJER .........................................................................................................................................................66 REZIME POGLAVLJA ...................................................................................................................................................67 FORMALNE GRAMATIKE .............................................................................................................................................98 KONTEKSTNO OSJETLJIVA GRAMATIKA ......................................................................................................................98 NESAŽIMAJUĆA GRAMATIKA......................................................................................................................................98 KONTEKSTNO SLOBODNA GRAMATIKA ......................................................................................................................98 REGULARNA GRAMATIKA ..........................................................................................................................................98 PARSIRANJE ...............................................................................................................................................................99 LL PARSIRANJE .........................................................................................................................................................99 LR PARISRANJE .......................................................................................................................................................100 GENERATORI PARSERA .............................................................................................................................................102 REZIME POGLAVLJA .................................................................................................................................................103 OSNOVNI WIN32 API PROGRAM ............................................................................................................................104 14.1. 14.2. 14.3. 14.4. 14.5. 14.6. 14.7. 14.8. 14.9. 14.10. HELLO WORLD ........................................................................................................................................................104 PROSTI PROZOR .......................................................................................................................................................104 KORAK 1: REGISTRACIJA PROZORSKE KLASE ...........................................................................................................105 KORAK 2: KREIRANJE PROZORA ..............................................................................................................................105 KORAK 3: PETLJA PORUKA ......................................................................................................................................106 KORAK 4: PROZORSKA PROCEDURA.........................................................................................................................106 OBRADA PORUKA .....................................................................................................................................................107 ŠTA JE TO PORUKA? .................................................................................................................................................108 KOMUNIKACIJA SA DIALOŠKIM PROZORIMA .............................................................................................................109 ŠTA JE RED ČEKANJA PORUKA? ................................................................................................................................109 14.11. 14.12. 15. KORISNIČKI INTERFEJS I GRAFIČKE PRIMITIVE...........................................................................................110 15.1. 15.2. 15.3. 15.4. 15.5. 15.6. 15.7. 15.8. 15.9. 15.10. 15.11. 15.12. 15.13. 15.14. 15.15. 16. INSTRUKCIJSKI SET PENTIUMA II..............................................................................................................................158 OPERACIONI KODOVI, OPIS .......................................................................................................................................158 OPERANDI ................................................................................................................................................................159 KODIRANJE ADRESE: MODR/M AND SIB BYTES .....................................................................................................159 PRIMJERI KODIRANJA KOMPLETNIH INSTRUKCIJA ....................................................................................................160 PARSIRANJE INSTRUKCIJE ........................................................................................................................................163 PREPOZNAVANJE ADRESNIH REŽIMA ........................................................................................................................163 PRORAČUN MODRM , SIB I DEPLASMANA ................................................................................................................163 PUNJENJE I PRETRAŽIVANJE TABELE INSTRUKCIJA ...................................................................................................164 GENERISANJE HEKSADEKADNOG KODA....................................................................................................................164 NUMERIČKE KONSTANTE .........................................................................................................................................164 PSEUDOINSTRUKCIJE, PREFIKSI I MODIFIKATORI ......................................................................................................164 PRVI PROLAZ ............................................................................................................................................................165 DRUGI PROLAZ I GENERISANJE KODA .......................................................................................................................165 IZVRŠNA VERZIJA .....................................................................................................................................................165 LISTING ASEMBLERA ...............................................................................................................................................166 PRAVLJENJE STANDARDNOG OBJ FORMATA ..................................................................................................172 18.1. 18.2. 18.3. 18.4. 18.5. 18.6. 18.7. 18.8. 18.9. 18.10. 18.11. 18.12. 19. NAJVAŽNIJI PODSISTEMI WINDOWS API-JA .............................................................................................................119 DLL DATOTEKE U KOJIMA SE NALAZE FUNKCIJE .....................................................................................................120 SPISAK API FUNKCIJA ..............................................................................................................................................120 PORTIRANJE WINDOWS API FUNKCIJE .....................................................................................................................155 REZIME POGLAVLJA .................................................................................................................................................157 ASEMBLER....................................................................................................................................................................158 17.1. 17.2. 17.3. 17.4. 17.5. 17.6. 17.7. 17.8. 17.9. 17.10. 17.11. 17.12. 17.13. 17.14. 17.15. 17.16. 18. SERVISNE APLIKACIJE ..............................................................................................................................................110 KONZOLNE APLIKACIJE ............................................................................................................................................110 GRAFIČKE KONTROLE ..............................................................................................................................................110 FUNKCIJE GRAFIČKIH KONTROLA KROZ PRIMJER......................................................................................................111 MENIJI .....................................................................................................................................................................114 DUGME - BUTTON ....................................................................................................................................................114 EDITNA I MEMO POLJA .............................................................................................................................................115 GRUPE KONTROLA I RADIO TASTERI .........................................................................................................................115 KONTROLNE KUĆICE (CHECKBOX) ...........................................................................................................................116 LISTE PODATAKA (LISTBOX) ....................................................................................................................................116 KOMBINOVANE LISTE (COMBO BOX) ........................................................................................................................116 STATIČKI TEKST .......................................................................................................................................................116 KLIZNA TRAKA (SCROLLBAR) ..................................................................................................................................117 ISCRTANE SLIKE I WM_PAINT PORUKA .................................................................................................................117 REZIME POGLAVLJA .................................................................................................................................................118 SPISAK WIN32API FUNKCIJA ..................................................................................................................................119 16.1. 16.2. 16.3. 16.4. 16.5. 17. 190 ŠTA JE PETLJA PORUKA ............................................................................................................................................109 REZIME POGLAVLJA .................................................................................................................................................109 OBJEKTNI FORMATI ..................................................................................................................................................172 OBJEKTNI FORMAT MICROSOFT COFF ....................................................................................................................172 ZAGLAVLJE COFF OBJ DATOTEKE .........................................................................................................................172 OPCIONO ZAGLAVLJE ...............................................................................................................................................173 ZAGLAVLJE COFF SEKCIJE ........................................................................................................................................173 RELOKACIJSKA SEKCIJA ...........................................................................................................................................174 COFF: LINIJSKI BROJEVI..........................................................................................................................................175 COFF: TABELA SIMBOLA.........................................................................................................................................175 COFF: TABELA STRINGOVA ....................................................................................................................................176 PROGRAM KONVERTOR ............................................................................................................................................177 UPOTREBA PROGRAMA KONVERTORA ......................................................................................................................177 REZIME POGLAVLJA .................................................................................................................................................177 LINKER ..........................................................................................................................................................................181 19.1. 19.2. 19.3. 19.4. 19.5. PRINCIP RADA LINKERA ...........................................................................................................................................181 FIKSIRANJA I RELOKACIJE ........................................................................................................................................181 BIBLIOTEKE .............................................................................................................................................................182 PRAVLJENJE IMPORTNE TABELE ...............................................................................................................................182 KREIRANJE EKSPORTNE TABELE ...............................................................................................................................183 19.6. 19.7. 20. INTERPRETER .............................................................................................................................................................184 20.1. 20.2. 20.3. 20.4. 20.5. 20.6. 20.7. 20.8. 20.9. 21. 191 DRUGI ZADACI LINKERA ..........................................................................................................................................183 REZIME POGLAVLJA .................................................................................................................................................183 INTERPRETERI I JEZICI ZA NJIHOV RAZVOJ ................................................................................................................184 INTERPRETIRANI JEZIK .............................................................................................................................................184 LINIJSKI EDITOR .......................................................................................................................................................184 INTERPRETERSKA PETLJA .........................................................................................................................................184 REALIZACIJA ARITMETIČKIH IZRAZA ........................................................................................................................185 REALIZACIJA NAREDBI PRIMITIVNOG BASICA ........................................................................................................185 INSTRUKCIJE ZA DOHVATANJE SIMBOLA ..................................................................................................................186 LISTING INTERPRETERA PRIMITIVNOG BASICA .......................................................................................................186 REZIME POGLAVLJA .................................................................................................................................................187 SADRŽAJ........................................................................................................................................................................188