You are on page 1of 44

IDZ DO

PRZYKADOWY ROZDZIA
SPIS TRECI

KATALOG KSIEK
KATALOG ONLINE
ZAMW DRUKOWANY KATALOG

Asembler.
Sztuka programowania
Autor: Randall Hyde
Tumaczenie: Przemysaw Szeremiota
ISBN: 83-7361-602-0
Tytu oryginau: The Art of Assembly Language
Format: B5, stron: 968

TWJ KOSZYK
DODAJ DO KOSZYKA

CENNIK I INFORMACJE
ZAMW INFORMACJE
O NOWOCIACH
ZAMW CENNIK

CZYTELNIA
FRAGMENTY KSIEK ONLINE

Ksika Asembler. Sztuka programowania to podrcznik programowania w jzyku


asemblera oparty na jzyku HLA. Opisuje 32-bitow architektur procesorw Intel
oraz zasady tworzenia programw w jzyku HLA. Przedstawia sposoby pisania,
kompilacji i uruchamiania programw wykorzystujcych rne, nawet najbardziej
zoone typy danych.
Wprowadzenie do jzyka HLA
Sposoby reprezentacji danych
Organizacja pamici i tryby adresowania
Typy danych
Podzia programu na procedury i moduy
Sterowanie wykonaniem programu
Instrukcje arytmetyczne
Operacje na plikach
Operacje bitowe i acuchowe
Makrodefinicje
Klasy i obiekty
Poczenie asemblera z programami w innych jzykach

Przekonaj si, jak prosty jest jzyk asemblera

Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl

Spis treci
Rozdzia 1. Wstp do jzyka asemblerowego...................................................... 13
1.1. Wprowadzenie........................................................................................................ 13
1.2. Anatomia programu HLA....................................................................................... 13
1.3. Uruchamianie pierwszego programu HLA ............................................................. 16
1.4. Podstawowe deklaracje danych programu HLA..................................................... 17
1.5. Wartoci logiczne ................................................................................................... 19
1.6. Wartoci znakowe................................................................................................... 20
1.7. Rodzina procesorw 80x86 firmy Intel .................................................................. 21
1.7.1. Podsystem obsugi pamici........................................................................... 24
1.8. Podstawowe instrukcje maszynowe........................................................................ 26
1.9. Podstawowe struktury sterujce wykonaniem programu HLA............................... 30
1.9.1. Wyraenia logiczne w instrukcjach HLA ..................................................... 31
1.9.2. Instrukcje if..then..elseif..else..endif jzyka HLA ......................................... 33
1.9.3. Iloczyn, suma i negacja w wyraeniach logicznych...................................... 35
1.9.4. Instrukcja while ............................................................................................ 37
1.9.5. Instrukcja for................................................................................................. 38
1.9.6. Instrukcja repeat............................................................................................ 39
1.9.7. Instrukcje break oraz breakif......................................................................... 40
1.9.8. Instrukcja forever.......................................................................................... 40
1.9.9. Instrukcje try, exception oraz endtry............................................................. 41
1.10. Biblioteka standardowa jzyka HLA wprowadzenie ......................................... 44
1.10.1. Stae predefiniowane w module stdio ........................................................... 46
1.10.2. Standardowe wejcie i wyjcie programu ..................................................... 46
1.10.3. Procedura stdout.newln................................................................................. 47
1.10.4. Procedury stdout.putiN ................................................................................. 47
1.10.5. Procedury stdout.putiNSize .......................................................................... 48
1.10.6. Procedura stdout.put ..................................................................................... 49
1.10.7. Procedura stdin.getc...................................................................................... 51
1.10.8. Procedury stdin.getiN ................................................................................... 52
1.10.9. Procedury stdin.readLn i stdin.flushInput..................................................... 53
1.10.10. Procedura stdin.get ....................................................................................... 54
1.11. Jeszcze o ochronie wykonania kodu w bloku try..endtry........................................ 55
1.11.1. Zagniedone bloki try..endtry ..................................................................... 56
1.11.2. Klauzula unprotected bloku try..endtry......................................................... 58
1.11.3. Klauzula anyexception bloku try..endtry ...................................................... 61
1.11.4. Instrukcja try..endtry i rejestry...................................................................... 61
1.12. Jzyk asemblerowy a jzyk HLA ........................................................................... 63
1.13. rda informacji dodatkowych.............................................................................. 64

Asembler. Sztuka programowania

Rozdzia 2. Reprezentacja danych ...................................................................... 65


2.1. Wprowadzenie........................................................................................................ 65
2.2. Systemy liczbowe ................................................................................................... 66
2.2.1. System dziesitny przypomnienie............................................................ 66
2.2.2. System dwjkowy......................................................................................... 66
2.2.3. Formaty liczb dwjkowych........................................................................... 68
2.3. System szesnastkowy.............................................................................................. 69
2.4. Organizacja danych ................................................................................................ 72
2.4.1. Bity ............................................................................................................... 72
2.4.2. Pbajty......................................................................................................... 73
2.4.3. Bajty ............................................................................................................. 73
2.4.4. Sowa ............................................................................................................ 75
2.4.5. Podwjne sowa ............................................................................................ 76
2.4.6. Sowa poczwrne i dugie............................................................................. 77
2.5. Operacje arytmetyczne na liczbach dwjkowych i szesnastkowych....................... 77
2.6. Jeszcze o liczbach i ich reprezentacji...................................................................... 78
2.7. Operacje logiczne na bitach.................................................................................... 81
2.8. Operacje logiczne na liczbach dwjkowych i cigach bitw.................................. 84
2.9. Liczby ze znakiem i bez znaku ............................................................................... 86
2.10. Rozszerzanie znakiem, rozszerzanie zerem, skracanie, przycinanie....................... 91
2.11. Przesunicia i obroty .............................................................................................. 95
2.12. Pola bitowe i dane spakowane................................................................................ 99
2.13. Wprowadzenie do arytmetyki zmiennoprzecinkowej ........................................... 104
2.13.1. Formaty zmiennoprzecinkowe przyjte przez IEEE ................................... 108
2.13.2. Obsuga liczb zmiennoprzecinkowych w jzyku HLA ............................... 112
2.14. Reprezentacja liczb BCD ..................................................................................... 115
2.15. Znaki .................................................................................................................... 117
2.15.1. Zestaw znakw ASCII................................................................................ 117
2.15.2. Obsuga znakw ASCII w jzyku HLA...................................................... 121
2.16. Zestaw znakw Unicode....................................................................................... 125
2.17. rda informacji dodatkowych............................................................................ 126

Rozdzia 3. Dostp do pamici i jej organizacja ................................................ 127


3.1. Wprowadzenie...................................................................................................... 127
3.2. Tryby adresowania procesorw 80x86 ................................................................. 127
3.2.1. Adresowanie przez rejestr........................................................................... 128
3.2.2. 32-bitowe tryby adresowania procesora 80x86........................................... 129
3.3. Organizacja pamici fazy wykonania ................................................................... 135
3.3.1. Obszar kodu................................................................................................ 137
3.3.2. Obszar zmiennych statycznych................................................................... 139
3.3.3. Obszar niemodyfikowalny .......................................................................... 140
3.3.4. Obszar danych niezainicjalizowanych ........................................................ 141
3.3.5. Atrybut @nostorage.................................................................................... 141
3.3.6. Sekcja deklaracji var ................................................................................... 142
3.3.7. Rozmieszczenie sekcji deklaracji danych w programie HLA ..................... 143
3.4. Przydzia pamici dla zmiennych w programach HLA......................................... 144
3.5. Wyrwnanie danych w programach HLA ............................................................ 146
3.6. Wyraenia adresowe............................................................................................. 149
3.7. Koercja typw ...................................................................................................... 151
3.8. Koercja typu rejestru ............................................................................................ 154
3.9. Pami obszaru stosu oraz instrukcje push i pop .................................................. 155
3.9.1. Podstawowa posta instrukcji push............................................................. 155
3.9.2. Podstawowa posta instrukcji pop .............................................................. 157
3.9.3. Zachowywanie wartoci rejestrw za pomoc instrukcji push i pop .......... 158

Spis treci

5
3.9.4. Stos jako kolejka LIFO ............................................................................... 159
3.9.5. Pozostae wersje instrukcji obsugi stosu.................................................... 161
3.9.6. Usuwanie danych ze stosu bez ich zdejmowania ........................................ 163
3.9.7. Odwoywanie si do danych na stosie bez ich zdejmowania ...................... 165
3.10. Dynamiczny przydzia pamici obszar pamici sterty ..................................... 166
3.11. Instrukcje inc oraz dec.......................................................................................... 171
3.12. Pobieranie adresu obiektu..................................................................................... 171
3.13. rda informacji dodatkowych............................................................................ 172

Rozdzia 4. Stae, zmienne i typy danych.......................................................... 173


4.1. Wprowadzenie...................................................................................................... 173
4.2. Kilka dodatkowych instrukcji: intmul, bound i into ............................................. 174
4.3. Typ tbyte............................................................................................................... 178
4.4. Deklaracje staych i zmiennych w jzyku HLA.................................................... 178
4.4.1. Typy staych ............................................................................................... 182
4.4.2. Literay staych acuchowych i znakowych............................................... 183
4.4.3. Stae acuchowe i napisowe w sekcji const............................................... 185
4.4.4. Wyraenia staowartociowe....................................................................... 186
4.4.5. Wielokrotne sekcje const i ich kolejno w programach HLA ................... 189
4.4.6. Sekcja val programu HLA .......................................................................... 190
4.4.7. Modyfikowanie obiektw sekcji val w wybranym miejscu
kodu rdowego programu ....................................................................... 191
4.5. Sekcja type programu HLA .................................................................................. 192
4.6. Typy wyliczeniowe w jzyku HLA ...................................................................... 193
4.7. Typy wskanikowe ............................................................................................... 194
4.7.1. Wskaniki w jzyku asemblerowym........................................................... 196
4.7.2. Deklarowanie wskanikw w programach HLA ........................................ 197
4.7.3. Stae wskanikowe i wyraenia staych wskanikowych............................ 197
4.7.4. Zmienne wskanikowe a dynamiczny przydzia pamici ........................... 199
4.7.5. Typowe bdy stosowania wskanikw ...................................................... 200
4.8. Modu chars.hhf biblioteki standardowej HLA .................................................... 205
4.9. Zoone typy danych ............................................................................................ 207
4.10. acuchy znakw................................................................................................. 208
4.11. acuchy w jzyku HLA...................................................................................... 210
4.12. Odwoania do poszczeglnych znakw acucha ................................................. 217
4.13. Modu strings biblioteki standardowej HLA i procedury manipulacji acuchami...219
4.14. Konwersje wewntrzpamiciowe ......................................................................... 231
4.15. Zbiory znakw...................................................................................................... 232
4.16. Implementacja zbiorw znakw w jzyku HLA................................................... 233
4.17. Literay, stae i wyraenia zbiorw znakw w jzyku HLA ................................. 235
4.18. Operator in w wyraeniach logicznych
wysokopoziomowego rozszerzenia jzyka HLA.................................................. 237
4.19. Obsuga zbiorw znakw w bibliotece standardowej HLA.................................. 237
4.20. Wykorzystywanie zbiorw znakw w programach HLA ..................................... 241
4.21. Tablice.................................................................................................................. 243
4.22. Deklarowanie tablic w programach HLA ............................................................. 244
4.23. Literay tablicowe................................................................................................. 245
4.24. Odwoania do elementw tablicy jednowymiarowej ............................................ 246
4.24.1. Porzdkowanie tablicy wartoci ................................................................. 248
4.25. Tablice wielowymiarowe ..................................................................................... 250
4.25.1. Wierszowy ukad elementw tablicy .......................................................... 251
4.25.2. Kolumnowy ukad elementw tablicy ........................................................ 255
4.26. Przydzia pamici dla tablic wielowymiarowych ................................................. 256
4.27. Odwoania do elementw tablic wielowymiarowych w jzyku asemblerowym... 258

Asembler. Sztuka programowania


4.28. Due tablice i MASM (tylko dla programistw systemu Windows) .................... 259
4.29. Rekordy (struktury) .............................................................................................. 260
4.30. Stae rekordowe.................................................................................................... 263
4.31. Tablice rekordw.................................................................................................. 264
4.32. Wykorzystanie tablic i rekordw w roli pl rekordw ......................................... 265
4.33. Ingerowanie w przesunicia pl rekordw ........................................................... 269
4.34. Wyrwnanie pl w ramach rekordu...................................................................... 270
4.35. Wskaniki na rekordy........................................................................................... 271
4.36. Unie ...................................................................................................................... 273
4.37. Unie anonimowe................................................................................................... 275
4.38. Typy wariantowe .................................................................................................. 276
4.39. Stae unii............................................................................................................... 277
4.40. Przestrzenie nazw ................................................................................................. 278
4.41. Tablice dynamiczne w jzyku asemblerowym ..................................................... 281
4.42. Obsuga tablic w bibliotece standardowej jzyka HLA ........................................ 284
4.43. rda informacji dodatkowych............................................................................ 287

Rozdzia 5. Procedury i moduy ........................................................................ 289


5.1. Wprowadzenie...................................................................................................... 289
5.2. Procedury.............................................................................................................. 289
5.3. Zachowywanie stanu systemu .............................................................................. 292
5.4. Przedwczesny powrt z procedury ....................................................................... 296
5.5. Zmienne lokalne ................................................................................................... 297
5.6. Symbole lokalne i globalne obiektw innych ni zmienne................................... 303
5.7. Parametry.............................................................................................................. 304
5.7.1. Przekazywanie przez warto ..................................................................... 305
5.7.2. Przekazywanie przez adres ......................................................................... 308
5.8. Funkcje i wartoci funkcji .................................................................................... 311
5.8.1. Zwracanie wartoci funkcji......................................................................... 312
5.8.2. Zoenie instrukcji jzyka HLA .................................................................. 313
5.8.3. Atrybut @returns procedur jzyka HLA..................................................... 316
5.9. Rekurencja............................................................................................................ 318
5.10. Deklaracje zapowiadajce .................................................................................... 322
5.11. Procedury w ujciu niskopoziomowym instrukcja call.................................... 323
5.12. Rola stosu w procedurach..................................................................................... 325
5.13. Rekordy aktywacji................................................................................................ 328
5.14. Standardowa sekwencja wejcia do procedury ..................................................... 331
5.15. Standardowa sekwencja wyjcia z procedury....................................................... 333
5.16. Niskopoziomowa implementacja zmiennych automatycznych ............................ 334
5.17. Niskopoziomowa implementacja parametrw procedury..................................... 336
5.17.1. Przekazywanie argumentw w rejestrach ................................................... 337
5.17.2. Przekazywanie argumentw w kodzie programu........................................ 340
5.17.3. Przekazywanie argumentw przez stos....................................................... 342
5.18. Wskaniki na procedury ....................................................................................... 365
5.19. Parametry typu procedurowego............................................................................ 368
5.20. Nietypowane parametry wskanikowe ................................................................. 370
5.21. Zarzdzanie duymi projektami programistycznymi............................................ 371
5.22. Dyrektywa #include ............................................................................................. 372
5.23. Unikanie wielokrotnego wczania do kodu tego samego pliku........................... 374
5.24. Moduy a atrybut @external................................................................................. 375
5.24.1. Dziaanie atrybutu @external ..................................................................... 380
5.24.2. Pliki nagwkowe w programach HLA....................................................... 382
5.25. Jeszcze o problemie zamiecania przestrzeni nazw .............................................. 384
5.26. rda informacji dodatkowych............................................................................ 386

Spis treci

Rozdzia 6. Arytmetyka.................................................................................... 389


6.1. Wprowadzenie...................................................................................................... 389
6.2. Zestaw instrukcji arytmetycznych procesora 80x86 ............................................. 389
6.2.1. Instrukcje mul i imul................................................................................... 389
6.2.2. Instrukcje div i idiv..................................................................................... 393
6.2.3. Instrukcja cmp ............................................................................................ 396
6.2.4. Instrukcje setXX ......................................................................................... 401
6.2.5. Instrukcja test.............................................................................................. 403
6.3. Wyraenia arytmetyczne ...................................................................................... 404
6.3.1. Proste przypisania ....................................................................................... 405
6.3.2. Proste wyraenia ......................................................................................... 406
6.3.3. Wyraenia zoone...................................................................................... 408
6.3.4. Operatory przemienne................................................................................. 413
6.4. Wyraenia logiczne .............................................................................................. 414
6.5. Idiomy maszynowe a idiomy arytmetyczne.......................................................... 417
6.5.1. Mnoenie bez stosowania instrukcji mul, imul i intmul.............................. 417
6.5.2. Dzielenie bez stosowania instrukcji div i idiv............................................. 419
6.5.3. Zliczanie modulo n za porednictwem instrukcji and ................................. 420
6.5.4. Nieostrone korzystanie z idiomw maszynowych .................................... 420
6.6. Arytmetyka zmiennoprzecinkowa ........................................................................ 421
6.6.1. Rejestry jednostki zmiennoprzecinkowej.................................................... 421
6.6.2. Typy danych jednostki zmiennoprzecinkowej ............................................ 429
6.6.3. Zestaw instrukcji jednostki zmiennoprzecinkowej ..................................... 430
6.6.4. Instrukcje przemieszczania danych............................................................. 431
6.6.5. Instrukcje konwersji.................................................................................... 433
6.6.6. Instrukcje arytmetyczne .............................................................................. 436
6.6.7. Instrukcje porwna ................................................................................... 442
6.6.8. Instrukcje adowania staych na stos koprocesora....................................... 445
6.6.9. Instrukcje funkcji przestpnych .................................................................. 445
6.6.10. Pozostae instrukcje jednostki zmiennoprzecinkowej ................................. 447
6.6.11. Instrukcje operacji cakowitoliczbowych.................................................... 449
6.7. Tumaczenie wyrae arytmetycznych na kod maszynowy
jednostki zmiennoprzecinkowej........................................................................... 449
6.7.1. Konwersja notacji wrostkowej do odwrotnej notacji polskiej..................... 451
6.7.2. Konwersja odwrotnej notacji polskiej do kodu jzyka asemblerowego...... 453
6.8. Obsuga arytmetyki zmiennoprzecinkowej w bibliotece standardowej jzyka HLA.....455
6.8.1. Funkcje stdin.getf i fileio.getf ..................................................................... 455
6.8.2. Funkcje trygonometryczne moduu math.................................................... 455
6.8.3. Funkcje wykadnicze i logarytmiczne moduu math................................... 456
6.9. Podsumowanie...................................................................................................... 458

Rozdzia 7. Niskopoziomowe struktury sterujce wykonaniem programu............ 459


7.1. Wprowadzenie...................................................................................................... 459
7.2. Struktury sterujce niskiego poziomu................................................................... 460
7.3. Etykiety instrukcji................................................................................................. 460
7.4. Bezwarunkowy skok do instrukcji (instrukcja jmp) ............................................. 462
7.5. Instrukcje skoku warunkowego ............................................................................ 465
7.6. Struktury sterujce redniego poziomu jt i jf................................................ 468
7.7. Implementacja popularnych struktur sterujcych w jzyku asemblerowym ......... 469
7.8. Wstp do podejmowania decyzji .......................................................................... 469
7.8.1. Instrukcje if..then..else................................................................................ 471
7.8.2. Tumaczenie instrukcji if jzyka HLA na jzyk asemblerowy.................... 475
7.8.3. Obliczanie wartoci zoonych wyrae logicznych
metoda penego szacowania wartoci wyraenia................................... 480

Asembler. Sztuka programowania


7.8.4. Skrcone szacowanie wyrae logicznych ................................................. 481
7.8.5. Wady i zalety metod szacowania wartoci wyrae logicznych ................. 483
7.8.6. Efektywna implementacja instrukcji if w jzyku asemblerowym ............... 485
7.8.7. Instrukcje wyboru ....................................................................................... 490
7.9. Skoki porednie a automaty stanw...................................................................... 500
7.10. Kod spaghetti........................................................................................................ 503
7.11. Ptle...................................................................................................................... 504
7.11.1. Ptle while .................................................................................................. 505
7.11.2. Ptle repeat..until ........................................................................................ 506
7.11.3. Ptle nieskoczone ..................................................................................... 508
7.11.4. Ptle for ...................................................................................................... 508
7.11.5. Instrukcje break i continue.......................................................................... 509
7.11.6. Ptle a rejestry ............................................................................................ 513
7.12. Optymalizacja kodu.............................................................................................. 514
7.12.1. Obliczanie warunku zakoczenia ptli na kocu ptli ................................ 515
7.12.2. Zliczanie licznika ptli wstecz .................................................................... 517
7.12.3. Wstpne obliczanie niezmiennikw ptli.................................................... 518
7.12.4. Rozciganie ptli ........................................................................................ 519
7.12.5. Zmienne indukcyjne ................................................................................... 521
7.13. Mieszane struktury sterujce w jzyku HLA........................................................ 522
7.14. rda informacji dodatkowych............................................................................ 524

Rozdzia 8. Pliki .............................................................................................. 525


8.1. Wprowadzenie...................................................................................................... 525
8.2. Organizacja plikw............................................................................................... 525
8.2.1. Pliki jako listy rekordw............................................................................. 526
8.2.2. Pliki tekstowe a pliki binarne...................................................................... 528
8.3. Pliki sekwencyjne ................................................................................................. 530
8.4. Pliki dostpu swobodnego .................................................................................... 538
8.5. Indeksowany sekwencyjny dostp do pliku (ISAM) ............................................ 543
8.6. Przycinanie pliku .................................................................................................. 546
8.7. rda informacji dodatkowych............................................................................ 548

Rozdzia 9. Zaawansowane obliczenia w jzyku asemblerowym......................... 549


9.1. Wprowadzenie...................................................................................................... 549
9.2. Operacje o zwielokrotnionej precyzji ................................................................... 550
9.2.1. Obsuga operacji zwielokrotnionej precyzji
w bibliotece standardowej jzyka HLA...................................................... 550
9.2.2. Dodawanie liczb zwielokrotnionej precyzji ................................................ 553
9.2.3. Odejmowanie liczb zwielokrotnionej precyzji............................................ 556
9.2.4. Porwnanie wartoci o zwielokrotnionej precyzji ...................................... 558
9.2.5. Mnoenie operandw zwielokrotnionej precyzji ........................................ 562
9.2.6. Dzielenie wartoci zwielokrotnionej precyzji ............................................. 565
9.2.7. Negacja operandw zwielokrotnionej precyzji ........................................... 575
9.2.8. Iloczyn logiczny operandw zwielokrotnionej precyzji.............................. 577
9.2.9. Suma logiczna operandw zwielokrotnionej precyzji................................. 577
9.2.10. Suma wyczajca operandw zwielokrotnionej precyzji........................... 578
9.2.11. Inwersja operandw zwielokrotnionej precyzji .......................................... 578
9.2.12. Przesunicia bitowe operandw zwielokrotnionej precyzji ........................ 578
9.2.13. Obroty operandw zwielokrotnionej precyzji............................................. 583
9.2.14. Operandy zwielokrotnionej precyzji w operacjach wejcia-wyjcia........... 583
9.3. Manipulowanie operandami rnych rozmiarw.................................................. 604
9.4. Arytmetyka liczb dziesitnych.............................................................................. 606
9.4.1. Literay liczb BCD...................................................................................... 608
9.4.2. Instrukcje maszynowe daa i das.................................................................. 608

Spis treci

9
9.4.3. Instrukcje maszynowe aaa, aas, aam i aad .................................................. 610
9.4.4. Koprocesor a arytmetyka spakowanych liczb dziesitnych ........................ 612
9.5. Obliczenia w tabelach........................................................................................... 615
9.5.1. Wyszukiwanie w tabeli wartoci funkcji .................................................... 615
9.5.2. Dopasowywanie dziedziny ......................................................................... 620
9.5.3. Generowanie tabel wartoci funkcji............................................................ 621
9.5.4. Wydajno odwoa do tabel przegldowych ............................................. 625
9.6. rda informacji dodatkowych............................................................................ 625

Rozdzia 10. Makrodefinicje i jzyk czasu kompilacji .......................................... 627


10.1. Wprowadzenie...................................................................................................... 627
10.2. Jzyk czasu kompilacji wstp .......................................................................... 627
10.3. Instrukcje #print i #error....................................................................................... 629
10.4. Stae i zmienne czasu kompilacji.......................................................................... 631
10.5. Wyraenia i operatory czasu kompilacji............................................................... 632
10.6. Funkcje czasu kompilacji ..................................................................................... 635
10.6.1. Funkcje czasu kompilacji konwersja typw........................................... 636
10.6.2. Funkcje czasu kompilacji obliczenia numeryczne ................................. 638
10.6.3. Funkcje czasu kompilacji klasyfikacja znakw ..................................... 638
10.6.4. Funkcje czasu kompilacji manipulacje acuchami znakw .................. 639
10.6.5. Funkcje czasu kompilacji dopasowywanie wzorcw............................. 639
10.6.6. Odwoania do tablicy symboli .................................................................... 641
10.6.7. Pozostae funkcje czasu kompilacji ............................................................ 643
10.6.8. Konwersja typu staych napisowych........................................................... 643
10.7. Kompilacja warunkowa........................................................................................ 645
10.8. Kompilacja wielokrotna (ptle czasu kompilacji)................................................. 650
10.9. Makrodefinicje (procedury czasu kompilacji) ...................................................... 653
10.9.1. Makrodefinicje standardowe....................................................................... 654
10.9.2. Argumenty makrodefinicji.......................................................................... 656
10.9.3. Symbole lokalne makrodefinicji ................................................................. 663
10.9.4. Makrodefinicje jako procedury czasu kompilacji ....................................... 666
10.9.5. Symulowane przecianie funkcji .............................................................. 667
10.10. Tworzenie programw czasu kompilacji.............................................................. 672
10.10.1. Generowanie tabel wartoci funkcji............................................................ 673
10.10.2. Rozciganie ptli ........................................................................................ 677
10.11. Stosowanie makrodefinicji w osobnych plikach kodu rdowego ...................... 679
10.12. rda informacji dodatkowych ........................................................................... 679

Rozdzia 11. Manipulowanie bitami .................................................................... 681


11.1. Wprowadzenie...................................................................................................... 681
11.2. Czym s dane bitowe? .......................................................................................... 681
11.3. Instrukcje manipulujce bitami............................................................................. 683
11.4. Znacznik przeniesienia w roli akumulatora bitw ................................................ 692
11.5. Wstawianie i wyodrbnianie acuchw bitw .................................................... 693
11.6. Scalanie zbiorw bitw i rozpraszanie acuchw bitowych................................ 696
11.7. Spakowane tablice acuchw bitowych .............................................................. 699
11.8. Wyszukiwanie bitw ............................................................................................ 701
11.9. Zliczanie bitw ..................................................................................................... 704
11.10. Odwracanie acucha bitw.................................................................................. 707
11.11. Scalanie acuchw bitowych .............................................................................. 709
11.12. Wyodrbnianie acuchw bitw ......................................................................... 710
11.13. Wyszukiwanie wzorca bitowego .......................................................................... 712
11.14. Modu bits biblioteki standardowej HLA ............................................................. 713
11.15. rda informacji dodatkowych ........................................................................... 715

10

Asembler. Sztuka programowania

Rozdzia 12. Operacje acuchowe..................................................................... 717


12.1. Wprowadzenie...................................................................................................... 717
12.2. Instrukcje acuchowe procesorw 80x86............................................................ 717
12.2.1. Sposb dziaania instrukcji acuchowych ................................................. 718
12.2.2. Przedrostki instrukcji acuchowych repX ............................................ 719
12.2.3. Znacznik kierunku ...................................................................................... 719
12.2.4. Instrukcja movs........................................................................................... 721
12.2.5. Instrukcja cmps........................................................................................... 727
12.2.6. Instrukcja scas............................................................................................. 731
12.2.7. Instrukcja stos............................................................................................. 732
12.2.8. Instrukcja lods ............................................................................................ 733
12.2.9. Instrukcje lods i stos w zoonych operacjach acuchowych .................... 733
12.3. Wydajno instrukcji acuchowych procesorw 80x86 ...................................... 734
12.4. rda informacji dodatkowych............................................................................ 735

Rozdzia 13. Instrukcje MMX............................................................................. 737


13.1. Wprowadzenie...................................................................................................... 737
13.2. Sprawdzanie obecnoci rozszerzenia MMX......................................................... 738
13.3. rodowisko programowania MMX ...................................................................... 739
13.3.1. Rejestry MMX............................................................................................ 739
13.3.2. Typy danych MMX .................................................................................... 741
13.4. Przeznaczenie instrukcji zestawu MMX............................................................... 742
13.5. Arytmetyka z nasycaniem a arytmetyka z zawijaniem ......................................... 743
13.6. Operandy instrukcji MMX ................................................................................... 744
13.7. Instrukcje zestawu MMX ..................................................................................... 746
13.7.1. Instrukcje transferu danych......................................................................... 747
13.7.2. Instrukcje konwersji.................................................................................... 747
13.7.3. Arytmetyka operandw spakowanych ........................................................ 752
13.7.4. Instrukcje logiczne...................................................................................... 755
13.7.5. Instrukcje porwna ................................................................................... 756
13.7.6. Instrukcje przesuni bitowych................................................................... 760
13.7.7. Instrukcja emms.......................................................................................... 762
13.8. Model programowania MMX............................................................................... 763
13.9. rda informacji dodatkowych............................................................................ 774

Rozdzia 14. Klasy i obiekty............................................................................... 775


14.1. Wprowadzenie...................................................................................................... 775
14.2. Wstp do programowania obiektowego................................................................ 775
14.3. Klasy w jzyku HLA ............................................................................................ 779
14.4. Obiekty ................................................................................................................. 782
14.5. Dziedziczenie ....................................................................................................... 784
14.6. Przesanianie......................................................................................................... 785
14.7. Metody wirtualne a procedury statyczne .............................................................. 786
14.8. Implementacje metod i procedur klas ................................................................... 788
14.9. Implementacja obiektu ......................................................................................... 793
14.9.1. Tabela metod wirtualnych .......................................................................... 796
14.9.2. Reprezentacja w pamici obiektu klasy pochodnej..................................... 798
14.10. Konstruktory i inicjalizacja obiektw................................................................... 802
14.10.1. Konstruktor a dynamiczny przydzia obiektu ............................................. 804
14.10.2. Konstruktory a dziedziczenie...................................................................... 806
14.10.3. Parametry konstruktorw i przecianie procedur klas .............................. 810
14.11. Destruktory........................................................................................................... 811
14.12. acuchy _initialize_ oraz _finalize_ w jzyku HLA .......................................... 812
14.13. Metody abstrakcyjne ............................................................................................ 818

Spis treci

11
14.14. Informacja o typie czasu wykonania (RTTI) ........................................................ 822
14.15. Wywoania metod klasy bazowej ......................................................................... 824
14.16. rda informacji dodatkowych ........................................................................... 825

Rozdzia 15. Na styku asemblera i innych jzykw programowania...................... 827


15.1. Wprowadzenie...................................................................................................... 827
15.2. czenie kodu HLA i kodu asemblera MASM bd Gas ..................................... 827
15.2.1. Kod asemblera MASM (Gas) rozwijany w kodzie jzyka HLA................. 828
15.2.2. Konsolidacja moduw MASM (Gas) z moduami HLA............................ 832
15.3. Moduy HLA a programy jzyka Delphi (Kylix) ................................................. 837
15.3.1. Konsolidacja moduw HLA z programami jzyka Delphi (Kylix) ........... 838
15.3.2. Zachowywanie wartoci rejestrw.............................................................. 842
15.3.3. Wartoci zwracane funkcji.......................................................................... 843
15.3.4. Konwencje wywoa .................................................................................. 849
15.3.5. Przekazywanie argumentw przez warto i adres,
parametry niemodyfikowalne i wyjciowe ................................................. 854
15.3.6. Skalarne typy danych w jzykach HLA i Delphi (Kylix) ........................... 856
15.3.7. Przekazywanie acuchw znakw z Delphi do procedury HLA ............... 858
15.3.8. Przekazywanie rekordw z programu w jzyku Delphi do kodu HLA....... 862
15.3.9. Przekazywanie zbiorw z programu w jzyku Delphi do kodu HLA ......... 866
15.3.10. Przekazywanie tablic z programu w jzyku Delphi do kodu HLA ............. 867
15.3.11. Odwoania do obiektw programu pisanego w Delphi w kodzie HLA....... 867
15.4. Moduy HLA a programy jzykw C i C++ ......................................................... 870
15.4.1. Konsolidacja moduw jzyka HLA z programami jzykw C i C++........ 872
15.4.2. Zachowywanie wartoci rejestrw.............................................................. 875
15.4.3. Wartoci funkcji ......................................................................................... 876
15.4.4. Konwencje wywoa .................................................................................. 876
15.4.5. Tryby przekazywania argumentw ............................................................. 880
15.4.6. Odwzorowanie typw skalarnych
pomidzy jzykiem C (C++) a jzykiem HLA ........................................... 881
15.4.7. Przekazywanie acuchw znakw
pomidzy programem w jzyku C (C++) a moduem HLA........................ 883
15.4.8. Przekazywanie rekordw
pomidzy programem w jzyku C (C++) a moduem HLA........................ 883
15.4.9. Przekazywanie tablic
pomidzy programem w jzyku C (C++) a moduem HLA........................ 886
15.5. rda informacji dodatkowych............................................................................ 886

Dodatek A Tabela kodw ASCII....................................................................... 887


Dodatek B Instrukcje procesorw 80x86......................................................... 891
Skorowidz...................................................................................... 927

1.9. Podstawowe struktury sterujce


wykonaniem programu HLA
Instrukcje ,  oraz , cho niezwykle uyteczne, nie wystarczaj do napisania
sensownych programw. Aby takie programy mogy powsta, podstawowe instrukcje
musz zosta uzupenione o podstawowy zbir struktur sterujcych wykonaniem kodu
umoliwiajcych tworzenie ptli i podejmowanie decyzji w programie. Jzyk HLA
przewiduje szereg wysokopoziomowych struktur sterujcych wykonaniem charakterystycznych dla jzykw wyszego ni asembler poziomu. Programista HLA ma wic do
dyspozycji konstrukcje
 
 
,    , 
  i tak dalej. Dopiero znajomo i umiejtno wykorzystywania owych konstrukcji
pozwala na stworzenie prawdziwego programu.
Przed zagbieniem si w cechach struktur sterujcych naleaoby podkreli, e nie maj
one odpowiednikw w zestawie instrukcji maszynowych procesorw 80x86. Kompilator HLA tumaczy owe struktury do postaci szeregu prawdziwych instrukcji maszynowych za programist. Sposb, w jaki to czyni, opisany zostanie w dalszej czci ksiki;
wtedy te Czytelnik nauczy si pisa kod w czystym jzyku asemblerowym, bez wykorzystania wysokopoziomowych cech kompilatora HLA. Na razie jednak, z racji
niewielkiego jeszcze zasobu wiedzy o jzyku asemblerowym, nieco sztuczne struktury
sterujce HLA bd bardzo pomocne.
Warto przy tym pamita, e wysokopoziomowe na pierwszy rzut oka struktury sterujce
nie s w istocie tak wysokopoziomowe. Maj one bowiem jedynie uatwi rozpoczcie
pisania programw w jzyku asemblerowym w adnym razie nie zastpuj asemblerowych instrukcji sterujcych wykonaniem kodu. Ju wkrtce okae si wic, e owe
wysokopoziomowe struktury sterujce maj szereg ogranicze, ktre w miar nabierania przez Czytelnika dowiadczenia i w miar komplikowania kolejnych programw
stan si do uciliwe. To zreszt efekt zamierzony po osigniciu pewnego poziomu
umiejtnoci programista sam stwierdzi, e w wielu przypadkach wygoda (i czytelno
programu) wynikajca z zastosowania struktur sterujcych HLA nie rekompensuje
utraty efektywnoci, charakterystycznej dla kodu wykorzystujcego wprost instrukcje
maszynowe procesora.
Niniejsze omwienie kierowane jest do tych Czytelnikw, ktrzy znaj ju przynajmniej
jeden z popularnych jzykw wysokiego poziomu. Znajomo ta znakomicie uproci
prezentacj struktur sterujcych wykonaniem programu HLA, pozwalajc na pominicie
opisw sposobw zastosowania owych struktur w typowych zadaniach programistycznych. Czytelnicy potraficy korzysta ze struktur sterujcych wykonaniem programu
w dowolnym z jzykw wysokiego poziomu nie powinni by zaskoczeni, kiedy odkryj,
e analogiczne struktury wykorzystywane s w programach HLA w sposb dosownie
identyczny.

Rozdzia 1. Wstp do jzyka asemblerowego

31

1.9.1. Wyraenia logiczne w instrukcjach HLA


Niektre z instrukcji sterujcych wykonaniem programu HLA wymagaj okrelenia
w miejsce operandu wartoci logicznej (prawda bd fasz); cieka wykonania programu zaley wtedy od wartoci wyraenia logicznego. Przykadami struktur wymagajcych okrelenia wyraenia logicznego s instrukcje
,   oraz   .
Pierwsz oznak ogranicze struktur sterujcych wykonaniem programu HLA jest
skadnia owych wyrae. W tym jednym miejscu nawyki wyniesione z jzykw wysokiego poziomu zwracaj si przeciwko programicie asemblera: w jzyku HLA wyraenia logiczne s bardzo ograniczone nie sposb konstruowa tu wyrae rwnie
wymylnych, z jakimi moe mie do czynienia programista jzyka C++.
Wyraenia logiczne w jzyku HLA mog przyj jedn z nastpujcych postaci1:


 

 

  
  
   
      


 

 
 
 

 
 

Znacznik moe zosta okrelony za porednictwem jednego z symboli wyliczonych


w tabeli 1.2.
Tabela 1.2. Symbole reprezentujce znaczniki

Symbol

Znacznik

Znaczenie

Przeniesienie

Prawda dla ustawionego (1) znacznika przeniesienia;


fasz dla wyzerowanego (0) znacznika przeniesienia.



Brak przeniesienia

Prawda dla wyzerowanego (0) znacznika przeniesienia;


fasz dla ustawionego (1) znacznika przeniesienia.

Zero

Prawda dla ustawionego (1) znacznika zera; fasz


dla wyzerowanego (0) znacznika zera.



Brak zera

Prawda dla wyzerowanego (0) znacznika zera; fasz


dla ustawionego (1) znacznika zera.



Przepenienie

Prawda dla ustawionego (1) znacznika przepenienia;


fasz dla wyzerowanego (0) znacznika przepenienia.



Brak przepenienia

Prawda dla wyzerowanego (0) znacznika przepenienia;


fasz dla ustawionego (1) znacznika przepenienia.

Znak

Prawda dla ustawionego (1) znacznika znaku; fasz


dla wyzerowanego (0) znacznika znaku.



Brak znaku

Prawda dla wyzerowanego (0) znacznika znaku; fasz


dla ustawionego (1) znacznika znaku.

Istnieje jeszcze kilka postaci dodatkowych; zostan one omwione w dalszych podrozdziaach
i rozdziaach.

32

Asembler. Sztuka programowania

Wykorzystanie tych znacznikw w wyraeniach logicznych to ju do zaawansowane


programowanie w asemblerze. Sposb konstruowania wyrae logicznych angaujcych
znaczniki sowa stanu procesora zaprezentowany zostanie w nastpnym rozdziale.
W przypadku, kiedy warto logiczna angauje operand rejestrowy, operand ten moe
odnosi si do zarwno do rejestru 8-bitowego, 16-bitowego, jak i 32-bitowego. Wyraenie takie przyjmuje warto fasz, jeli rejestr zawiera warto zero. Dla kadej innej
wartoci rejestru wyraenie logiczne przyjmuje warto prawda.
Jeli w wyraeniu logicznym uwikana jest zmienna przechowywana w pamici, jej warto jest sprawdzana, a wyraenie przyjmuje warto logiczn prawdy bd faszu
w zalenoci od tej wartoci, wedug regu identycznych jak dla rejestrw. Naley
jednak pamita, e w wyraeniu logicznym powinna wystpowa zmienna typu logicznego (). Uwikanie w wyraeniu logicznym zmiennej innego typu spowoduje
bd. W przypadku potrzeby okrelenia wartoci logicznej zmiennej typu innego ni
 naley skorzysta z wyrae logicznych oglnego przeznaczenia, omwionych poniej.
Najbardziej oglna posta wyraenia logicznego w jzyku HLA pozwala na okrelenie
operatora relacji wraz z dwoma operandami. List dozwolonych kombinacji rodzajw
operandw i operatorw relacji zawiera tabela 1.3.
Tabela 1.3. Dozwolone wyraenia logiczne
Operand lewy

Operator relacji

Operand prawy

Zmienna w pamici bd rejestr

albo

Zmienna w pamici, rejestr bd staa

 albo 





Nie mona okreli obu operandw jako operandw pamiciowych. Lewy operand mona wic utosami z operandem rdowym, a operand prawy z operandem docelowym
i stosowa kombinacje rodzajw operandw takie jak dla instrukcji  czy .
Kolejna analogia operatorw relacji do instrukcji  i  objawia si w wymogu
identycznego rozmiaru operandw. I tak, oba operandy musz by albo bajtami, albo
sowami, albo podwjnymi sowami. Jeli operand prawy jest sta, jego warto musi
nadawa si do zapisania w operandzie lewym.
I jeszcze jedno: jeli lewy operand jest rejestrem, a prawy to staa dodatnia albo inny
rejestr, porwnanie odbywa si bez uwzgldnienia znaku operandw. Efekty takiego
porwnania omwione zostan w nastpnym rozdziale; na razie wystarczy zapamita,
e nie powinno si porwnywa wartoci ujemnej przechowywanej w rejestrze z wartoci sta albo zawartoci innego rejestru. Wynik porwnania moe bowiem odbiega
od oczekiwa programisty.

Rozdzia 1. Wstp do jzyka asemblerowego

33

Operatory  i    pozwalaj na wykonanie testu zawierania si wartoci przechowywanej w rejestrze w okrelonym zbiorze liczb. Na przykad wyraenie  
  daje warto logiczn , jeli warto przechowywana w rejestrze
EAX to warto z zakresu od 2000 do 2099 (wcznie). Operator    ma dziaanie
odwrotne da warto logiczn  jedynie wtedy, kiedy zawarto rejestru to
liczba spoza okrelonego zbioru. Na przykad wyraenie     bdzie
miao warto  tylko wtedy, kiedy znak przechowywany w rejestrze AL nie bdzie
ma liter alfabetu.
Oto kilka przykadw wyrae logicznych w jzyku HLA:




 

 

 
!""
#$$$
$

1.9.2. Instrukcje if..then..elseif..else..endif jzyka HLA


Skadnia instrukcji warunkowego wykonania kodu
w wydaniu jzyka HLA prezentowana jest na rysunku 1.10.

Rysunek 1.10. Skadnia instrukcji if w jzyku HLA

Wyraenia wystpujce w instrukcji


musz odpowiada jednej z postaci wyrae logicznych, zaprezentowanych w poprzednim ustpie. Jeli wyraenie przyjmie warto logiczn prawda, wykonany zostanie kod umieszczony za klauzul . W przeciwnym
przypadku sterowanie przekazane zostanie do kodu w ramach klauzuli 
bd .

34

Asembler. Sztuka programowania

Poniewa klauzule 


i  nie s obowizkowe, instrukcja
w najprostszej
postaci skada si z wyraenia logicznego i pojedynczej klauzuli , za ktr wystpuje instrukcja lub blok instrukcji wykonywanych warunkowo, w zalenoci od wartoci wyraenia logicznego:
%& ! "'# 
 ()*)&+,(-. /011+2'3
(%3

Jeli w trakcie wykonania programu wyraenie logiczne w instrukcji


bdzie miao
warto , wykonany zostanie kod znajdujcy si pomidzy sowami  i 
.
W przypadku kiedy wyraenie logiczne bdzie miao warto
, kod w zostanie
pominity.
Inn powszechnie wystpujc form instrukcji
jest forma z pojedyncz klauzul

. Instrukcja taka wyglda nastpujco:


%& ! "'# 

 ()*)&+,(-. /011. 4


4+2'3

 ()*)&+5*.. . 4
4+2'3
(%3

Jeli wyraenie logiczne przyjmie warto , wykonany zostanie kod zawarty midzy
sowami  a . W przypadku wartoci
 sterowanie przekazane zostanie do
kodu ograniczonego klauzul  i sowem 
.
Przez osadzanie opcjonalnych klauzul 
w instrukcji
mona rozbudowywa
podejmowanie decyzji o wykonaniu kodu. Na przykad, jeli rejestr CH zawiera warto
znakow, mona na podstawie jego wartoci dokona wyboru spord dostpnych
opcji menu, konstruujc nastpujc instrukcj
:
%& # $$'# 
 ()*)&+67,*
7 8 9 )-$$+2'3
 %& # $,$'# 
 ()*)&+67,*
7 8 9 )-$,$+2'3
 %& # $ $'
 ()*)&+67,*
7 8 9 )-$ $+2'3

 ()*)&+(-.7,* 8 *
9 )+2'3
(%3

Rozdzia 1. Wstp do jzyka asemblerowego

35

Cho nie wida tego w powyszym przykadzie, jzyk HLA nie wymaga umieszczania
po sekwencji klauzul 
klauzuli . Jednak przy podejmowaniu decyzji o wykonaniu jednej z wielu cieek kodu warto uzupeni instrukcj
klauzul  rozpoczynajc ciek kodu obsugi ewentualnych bdw wyboru. Nawet jeli pozornie
wykonanie owego kodu wydaje si niemoliwe, to naley wzi pod uwag ewentualny
rozwj aplikacji w kolejnych wersjach kodu wybr cieki wykonania moe mie
inny przebieg; warto, aby wtedy kod decyzyjny uzupeniony zosta o obsug sytuacji
wyjtkowych i niespodziewanych.

1.9.3. Iloczyn, suma i negacja


w wyraeniach logicznych
Na licie operatorw zaprezentowanej w poprzednich punktach zabrako bardzo wanych
operatorw logicznych: operatora iloczynu logicznego (AND), logicznej sumy (OR)
oraz logicznej negacji (NOT). Ich zastosowanie w wyraeniach logicznych omwione
zostanie tutaj wczeniej omwienie takie nie miaoby racji bytu z uwagi na konieczno poprzedzenia go omwieniem instrukcji warunkowego wykonania kodu
. Bez
moliwoci wybirczego wykonywania kodu trudno zaprezentowa realistyczne przykady zastosowania operatorw logicznych.
W jzyku HLA operator iloczynu logicznego ma posta znakw . Jest to operator
binarny i jako taki wymaga okrelenia dwch operandw; operandy te musz by poprawnymi wyraeniami czasu wykonania. Operator ten zwraca warto logiczn prawda
wtedy, kiedy oba operandy maj warto prawda. Oto przykad:
%& !":: #$$'# 
9& !2 ,!'3
9&$$2 #'3
(%3

Obie instrukcje  zostan wykonane jedynie wtedy, kiedy rwnoczenie rejestr EAX
bdzie mia warto wiksz od 0, a rejestr CH bdzie zawiera znak a. Jeli ktrykolwiek z tych warunkw nie bdzie speniony, obie instrukcje  zostan pominite.
Warto pamita, e operandy operatora  mog by dowolnymi poprawnymi wyraeniami logicznymi jzyka HLA nie musz to by wycznie operatory relacji. Oto
kilka poprawnych logicznych z operatorem iloczynu logicznego:

::"
$$$
$:: ,!
,;:: !

W jzyku HLA wykorzystywana jest metoda skrconego szacowania wartoci wyrae


operandw operatora logicznego . Ot jeli lewy operand ma warto fasz, to
operand prawy nie jest ju sprawdzany wyraenie logiczne natychmiast otrzymuje
warto fasz (co jest jak najbardziej poprawne, bo operator  daje warto prawda
wycznie dla dwu operandw o wartoci prawda). Std w ostatnim z zaprezentowanych
wyej wyrae najpierw sprawdzona zostanie warto logiczna zmiennej ; jeli
bdzie to warto
, test wartoci logicznej rejestru EAX zostanie pominity.

36

Asembler. Sztuka programowania

Nie sposb nie zauway, e wyraenie z operatorem , np. ,


jest wyraeniem logicznym (zwraca albo warto logiczn prawda, albo warto
fasz), wic wyraenie takie moe wystpowa w roli operandu innego wyraenia
z operatorem logicznym. Std poprawno nastpujcego wyraenia:
! ":: ,!  !:: !

Operator iloczynu logicznego cechuje si cznoci lewostronn, co oznacza, e w kodzie


wygenerowanym przez kompilator HLA ewaluacja (wartociowanie) wyraenia nastpuje
od strony lewej do prawej. Jeli rejestr EAX zawiera warto wiksz od zera, pozostae
operandy nie bd sprawdzane. Analogicznie, jeli EAX jest mniejszy od zera, ale EBX
jest rwny EAX, to sprawdzanie logicznej wartoci wyraenia ! zostanie pominite
cae wyraenie od razu otrzyma warto
.
Operator sumy logicznej w jzyku HLA reprezentowany jest znakami "". Podobnie, jak
operator iloczynu, operator sumy logicznej wymaga okrelenia dwch operandw bdcych poprawnymi wyraeniami logicznymi. Operator zwraca przy tym warto logiczn
prawda, jeli ktrykolwiek z operandw ma warto logiczn prawda. Rwnie
podobnie jak w przypadku operatora iloczynu stosowana jest metoda skrconej ewaluacji wyraenia jeli ju pierwszy operand ma warto logiczn prawda, operator
natychmiast zwraca warto prawda, niezalenie od wartoci drugiego operandu. Oto
przykady zastosowania operatora sumy logicznej:

<< "
$$$
$<< ,!
,;<< !

Podobnie jak operator  operator logicznej sumy cechuje si cznoci lewostronn,


wic w wyraeniach z wieloma operatorami "" ewaluacja przebiega od strony lewej do
prawej. Na przykad:
! "<< ,!  !<< !

Jeli powysze wyraenie zostaoby osadzone w wyraeniu logicznym instrukcji


, to
kod po klauzuli  zostaby wykonany tylko wtedy, kiedy rejestr EAX miaby warto
mniejsz od zera lub EBX nie byby rwny EAX bd rejestr ECX zawieraby warto
zero. Jeli ju pierwszy test daby warto , pozostae warunki nie byyby sprawdzane. Gdyby pierwszy warunek mia warto
, ale drugi , to etap szacowania
wartoci logicznej wyraenia ! zostaby pominity. Test zawartoci rejestru ECX
nastpiby jedynie w obliczu niespenienie wczeniejszych dwch wyrae.
Jeli w jednym wyraeniu logicznym wystpuj operatory iloczynu i sumy logicznej,
pierwszestwo przed operatorem sumy ma operator iloczynu. Wemy nastpujce wyraenie:
! "<< ,!  !:: !

W interpretacji HLA powyszemu wyraeniu rwnowane jest wyraenie nastpujce:


! "<<& ,!  !:: !'

Jeli rejestr EAX bdzie mia warto mniejsz od zera, reszta wyraenia nie bdzie
sprawdzana cao wyraenia otrzyma warto . Jeli jednak rejestr EAX bdzie

Rozdzia 1. Wstp do jzyka asemblerowego

37

zawiera warto wiksz od zera, to aby cao wyraenia otrzymaa warto ,
oba operandy operatora iloczynu musiayby mie warto .
Podwyraenia wykorzystujce operatory iloczynu i sumy logicznej mona grupowa
wedle wasnego uznania, otaczajc je nawiasami. Oto przykadowe wyraenie:
& ! "<< ,!  !':: !

Aby to wyraenie otrzymao warto logiczn prawda, rejestr ECX musi zawiera
warto zero oraz albo warto EAX musi by mniejsza od zera, albo rejestr EBX musi
zawiera warto rn od rejestru EAX. Szacowanie wyraenia przebiega wic odmiennie ni w wersji bez nawiasw.
Operator negacji logicznej ma w jzyku HLA posta znaku wykrzyknika ( ). Operandami operatora negacji mog by jednak wycznie rejestry i zmienne w pamici (np.
) operator negacji nie moe by bezporednio aplikowany do zoonych
wyrae logicznych. Aby wykona logiczn negacj wyraenia logicznego, naley to
wyraenie uj w nawiasy i cay nawias opatrzy przedrostkiem w postaci wykrzyknika:
& ! "'

Powysze wyraenie otrzymuje warto  wtedy, kiedy rejestr EAX ma warto
mniejsz od zera.
Operator logicznej negacji jest szczeglnie uyteczny w odniesieniu do wyrae zoonych angaujcych operatory logicznej sumy i logicznego iloczynu. W prostych wyraeniach, jak powysze, lepiej jest zazwyczaj bezporednio okreli stan logiczny wyraenia ni dodatkowo komplikowa go operatorem negacji.
W jzyku HLA programista moe te korzysta z operatorw bitowych " i , ale te rni
si znaczco od operatorw logicznych "" oraz . Szczegowe omwienie operatorw
bitowych i innych operatorw jzyka HLA znajduje si w dokumentacji kompilatora.

1.9.4. Instrukcja while


Skadni instrukcji   ilustruje rysunek 1.11.
Rysunek 1.11.
Skadnia instrukcji
while jzyka HLA

Wykonanie instrukcji   przebiega nastpujco: najpierw szacowana jest warto


logiczna wyraenia warunku ptli. Jeli ma ono warto fasz, sterowanie natychmiast przekazywane jest do kodu znajdujcego si za klauzul  . W przypadku

38

Asembler. Sztuka programowania

wartoci prawda wyraenia warunku, procesor przystpuje do wykonania ciaa ptli.


Po wykonaniu wszystkich instrukcji ciaa ptli nastpuje ponowne oszacowanie wartoci
logicznej wyraenia warunkowego. Caa procedura powtarzana jest a do momentu,
w ktrym wyraenie warunkowe ptli przyjmie warto logiczn fasz.
W ptli   sprawdzenie wartoci warunku wykonania ptli nastpuje podobnie jak
w jzykach wysokiego poziomu, czyli przed wykonaniem pierwszej instrukcji ciaa
ptli. Z tego wzgldu istnieje prawdopodobiestwo, e instrukcje ciaa ptli nie zostan
wykonane ani razu, jeli wyraenie warunku bdzie od pocztku miao warto
.
Poza tym warto pamita, e przynajmniej jedna z instrukcji ciaa ptli powinna modyfikowa warto wyraenia logicznego w przeciwnym przypadku bdziemy mieli
do czynienia z ptl nieskoczon.
Oto przykad ptli   w jzyku HLA:
9&"2'3
.# & "'(
 ()*)&+ +22'3
((&2'3
(.# 3

1.9.5. Instrukcja for


W jzyku HLA ptla for przybiera nastpujc posta:
%&   33
  '(
  
(%3

Instrukcja ptli
 odpowiada nastpujcej ptli  :
   3
.# &'(
  

  3
(.# 3

Wyraenie inicjalizujce moe by dowoln, pojedyncz instrukcj maszynow. Instrukcja ta zwykle inicjalizuje rejestr albo zmienn przechowywan w pamici, ktrej warto
decyduje o kontynuowaniu ptli (tzw. licznik ptli). Warunek to wyraenie logiczne
jzyka HLA w formacie takim jak dla instrukcji  . Warto tego wyraenia decyduje o podjciu kolejnej iteracji ptli i zwykle angauje licznik ptli. Instrukcja licznika to typowo instrukcja zwikszajca licznik ptli; odpowiednikiem tej instrukcji
jest instrukcja w ptli  , ktrej wykonanie zmienia warto logiczn warunku
wykonania ptli. Zwykle instrukcj t jest instrukcja jzyka HLA, na przykad .

Rozdzia 1. Wstp do jzyka asemblerowego

39

Oto przykad ilustrujcy rwnowano ptli


 i  :
%&9&"2'3 "3((&2''(
 ()*)&+ +22'3
(%3

// Analogiczna ptla for:


9&"2'3
.# & "'(
 ()*)&+ +22'3
((&2'3
(.# 3

1.9.6. Instrukcja repeat


Instrukcja    jzyka HLA wykorzystuje skadni prezentowan na rysunku
1.12. Programici jzykw C, C++ oraz Java powinni od razu zauway, e instrukcja
ta jest odpowiednikiem dostpnej w tych jzykach instrukcji   .
Rysunek 1.12.
Skadnia instrukcji
repeat..until
jzyka HLA

Test warunku zatrzymania ptli    odbywa si po zakoczeniu wykonywania ciaa ptli. Z tego wzgldu instrukcja (bd blok instrukcji) ciaa ptli zostanie
wykonana przynajmniej raz, niezalenie od wartoci pocztkowej wyraenia warunku
zatrzymania ptli. Warunek ten jest badany po raz pierwszy dopiero po zakoczeniu
pierwszej iteracji; jeli wyraenie ma warto
, ptla jest powtarzana2. Jeli warunek otrzyma warto , ptla jest zatrzymywana i sterowanie przekazywane jest
do instrukcji znajdujcych si za klauzul  .
Oto prosty przykad wykorzystania ptli   :
9&"2 !'3
 * 
 ()*)&+ ! +2 !2'3
 ),&2 !'3
)& ! "'3
2

Znaczenie warunku jest wic w jzyku HLA odwrotne ni warunku w analogicznej konstrukcji
(.# znanej z jzykw C, C++ i Java.

40

Asembler. Sztuka programowania

Jeli instrukcje ciaa ptli maj by wykonane przynajmniej raz, niezalenie od wartoci wyraenia warunku ptli, wtedy w miejsce ptli   lepiej zastosowa ptl #
   konstrukcja taka bdzie efektywniejsza.

1.9.7. Instrukcje break oraz breakif


Instrukcje $ i $
su do przedwczesnego przekazywania sterowania poza
ptl. Skadni obu instrukcji ilustruje rysunek 1.13.
Rysunek 1.13.
Skadnia instrukcji
break oraz breakif
jzyka HLA

Instrukcja $ powoduje bezwarunkowe przerwanie wykonywania ptli; instrukcja


$
uzalenia przekazanie sterowania poza ptl od spenienia warunku bdcego
wyraeniem logicznym. Wyjcie z ptli nastpuje wtedy wycznie w obliczu wartoci
 tego wyraenia.
Zastosowanie instrukcji $ oraz $
nie pozwala na przekazanie sterowania poza
ptle zagniedone. W jzyku HLA su do tego osobne instrukcje, jak %  
oraz  i 
. Szczegowe informacje na ten temat zawiera dokumentacja jzyka
HLA. Dalej, jzyk HLA udostpnia instrukcje !  oraz ! 
pozwalajce
na przystpienie do kolejnej iteracji ptli z pominiciem niewykonanych jeszcze instrukcji
ciaa ptli. Po szczegy odsyam Czytelnikw do stosownej dokumentacji.

1.9.8. Instrukcja forever


Skadni konstrukcji
 
 prezentuje rysunek 1.14.
Rysunek 1.14.
Skadnia instrukcji
forever jzyka HLA

Instrukcja
 tworzy ptl nieskoczon. Wewntrz takiej ptli mona jednak
umieci instrukcje $ bd $
celem przerwania ptli w wybranym momencie.
To chyba najczstszy ukad ptli
. Ilustruje go nastpujcy przykad:
%  
 ()*)&+6*.(

,  4.&9 8
("'-+'3
 (= &'3
, 4%& "'3
 ()*)&+6*.(
. 9,7 9 8
("+2'3
(%3

Rozdzia 1. Wstp do jzyka asemblerowego

41

1.9.9. Instrukcje try, exception oraz endtry


Instrukcje & !   & su do implementacji bardzo przydatnych blokw
obsugi wyjtkw. Skadnia instrukcji prezentowana jest na rysunku 1.15.
Rysunek 1.15.
Skadnia instrukcji
obsugi wyjtkw

Blok instrukcji &  & suy do ochrony wykonania instrukcji. Jeli wykonanie
instrukcji znajdujcych si pomidzy klauzul & a pierwsz klauzul ! ,
tworzcych tzw. blok chroniony, przebiegnie bez niespodzianek, sterowanie przekazywane jest do pierwszej instrukcji za klauzul  &. Jeli jednak w czasie wykonywania instrukcji bloku chronionego zdarzy si bd (wyjtek), wykonanie programu
jest przerywane, a sterowanie przekazywane jest do odpowiedniej klauzuli ! 
(skojarzonej z wyjtkiem, ktry wystpi). Kady wyjtek ma unikalny identyfikator
w postaci liczby cakowitej. Niektre z identyfikatorw wyjtkw zadeklarowane zostay
w pliku nagwkowym excepts.hhf biblioteki standardowej jzyka HLA, ale programista moe te definiowa wasne wyjtki. W momencie sprowokowania wyjtku system
porwnuje identyfikator zgoszonego wyjtku z identyfikatorami okrelonymi w klauzulach ! . Jeli wrd nich znajduje odpowiedni identyfikator, nastpuje wykonanie
instrukcji okrelonych w ramach klauzuli ! . Po zakoczeniu wykonywania tych
instrukcji sterowanie przekazywane jest do pierwszej instrukcji za klauzul  &.
Jeli wyjtek zostanie sprowokowany poza blokiem kodu chronionego (tzn. poza ramami
instrukcji &  &) albo jeli w ramach instrukcji &  & brak jest klauzuli
skojarzonej ze zgoszonym wyjtkiem, program jest awaryjnie zatrzymywany. Zatrzymaniu towarzyszy wyprowadzenie stosownego komunikatu na wyjcie programu.
Instrukcje &  & mona na przykad wykorzysta do ochrony programu przed
skutkami wprowadzenia niepoprawnych danych:

42

Asembler. Sztuka programowania


 * 
9&% 2>( = '3// Uwaga: zmienna GoodInteger musi by typu boolean
7
 ()*)&+6*.(

,  4.-+'3
 (= &'3
9&) 2>( = '3
 ! *& !?  '
 ()*)&+/ **.. 2.*.(
8


+2'3
 ! *& !;) @)@%A= '
 ()*)&+6  *

4 )2.*.(
8


+2'3
 (73
)&>( = '3

Zastosowana w powyszym programie ptla  pozwala na wykonywanie kodu


ciaa ptli tak dugo, jak dugo uytkownik podaje niepoprawne wartoci. Jeli z powodu
wprowadzenia niepoprawnej wartoci jej przypisanie do zmiennej '( % bdzie
niemoliwe (na przykad z racji umieszczenia we wprowadzonym niedozwolonych dla
liczb znakw albo wprowadzenia zbyt wielkiej wartoci), wykonany zostanie odpowiedni do rodzaju bdu blok instrukcji obsugi wyjtku. Obsuga wyjtkw polega tu
na wywietleniu stosownego komunikatu i przekazaniu sterowania poza instrukcj
&  &. Poniewa z racji wyjtku nie udao si w ramach bloku chronionego ustawi
wartoci  dla zmiennej '( %, ptla jest wykonywana ponownie. Jeliby jedna
w ramach bloku chronionego sprowokowany zosta inny ni obsugiwane wyjtek, program zakoczyby dziaanie po uprzednim wyprowadzeniu komunikatu o bdzie3.
W tabeli 1.4 zebrane zostay wyjtki, zdefiniowane w pliku excepts.hhf w czasie przygotowywania wydania niniejszej ksiki. Aktualn list zdefiniowanych w bibliotece
standardowej wyjtkw mona znale, zagldajc do pliku excepts.hhf doczonego
do posiadanej wersji oprogramowania kompilatora HLA.
Wikszo z tych wyjtkw dotyczy sytuacji, ktrych omawianie w niniejszym rozdziale
byoby przedwczesne. Zostay umieszczone w tabeli wycznie gwoli kompletnoci
omwienia. Kady z wyjtkw opisany jest szczegowo w dokumentacji HLA Reference
Manual dokumentacji biblioteki standardowej jzyka HLA; ostateczn wykadni jest
za sam kod rdowy biblioteki standardowej HLA. Najczciej wykorzystywanymi
wyjtkami s  ) *,  + +
,% oraz  -  %+
.
Omwienie bloku kodu chronionego podjte zostanie ponownie nieco pniej. Czytelnik
powinien kontynuowa edukacj w zakresie podstawowym, zadowalajc si na razie
szcztkowymi informacjami o obsudze wyjtkw.
3

Dowiadczony programista zastanawia si zapewne, dlaczego w powyszym kodzie do sterowania


przebiegiem ptli wykorzystywana jest zmienna typu ,  przecie mona by identyczny efekt
osign, stosujc instrukcj , 4%. Zastosowana konstrukcja ma uzasadnienie, ktre zostanie
przedstawione w dalszej czci ksiki.

Rozdzia 1. Wstp do jzyka asemblerowego

43

Tabela 1.4. Wyjtki zdefiniowane w pliku nagwkowym excepts.hhf


Identyfikator wyjtku

Znaczenie

!=@ %.

Prba zapisania zbyt dugiego acucha

!=( !

Prba odwoania do znaku o indeksie spoza acucha

!;) @)@%A=

Zbyt wielka warto dla danego typu zmiennej

! =?#

Zaangaowanie w operacji znaku spoza dopuszczalnego zakresu


(kod ASCI spoza zakresu od 0 do 127)

!?  

Niedozwolone znaki w konwersji acucha do wartoci numerycznej

!(B C( 

Odwoanie do pliku za porednictwem niepoprawnego uchwytu pliku

!B @* B)

Niemono otwarcia pliku (np. brak pliku o zadanej nazwie)

!B ? 

Niemono zamknicia pliku

!B 6 

Bd przy zapisie danych do pliku

!B A (

Bd przy odczycie danych z pliku

!D 4B)

Prba zapisania danych do pliku przy penym dysku

!(@%B

Prba odczytania bajta spoza koca pliku

!E 97 B)

Brak pamici do zaspokojenia dania alokacji

! 9*FD  %/011

Prba odwoania do pamici za porednictwem wskanika o wartoci NULL

!?B E 97

Bd przy operacji zwalniania pamici

!6(#F=

Zy format konwersji wartoci liczbowej do acucha

!FE7?9(159

Wiersz wywoania programu zawiera zbyt du liczb argumentw

!7#* ;

Prba operowania na dwch tablicach o rnych rozmiarach

!7)(

Prba odwoania do elementu spoza tablicy

!(D

Operacja na niepoprawnej wartoci daty

!(D B9

Bd konwersji acucha do daty (acuch zawiera niedozwolone znaki)

!F9 @ %.

Przepenienie w operacji manipulowania informacj o czasie

! B (

Bd instrukcji asercji

!! ) (,  

Prba wywoania metody klasy abstrakcyjnej

! ;

Prba odwoania si do niedozwolonego adresu pamici

! 45

Program dotar do punktu zatrzymania (przerwanie 3.)

!=  *

Program wykonywany jest z ustawionym znacznikiem wykonania


krokowego

!5 

Prba wykonania instrukcji charakterystycznej dla trybu nadzoru

! = 

Prba wykonania niedozwolonej instrukcji maszynowe

!)( 

Rejestr zawiera warto spoza zakresu okrelonego w instrukcji ,)(

! 

Wykonanie instrukcji  przy ustawionym znaczniku przepenienia

!D( 

Prba dzielenia przez zero bd inny bd dzielenia

!%D 9

Wyjtek operacji zmiennoprzecinkowej (patrz rozdzia powicony


obliczeniom arytmetycznym)

!%D7G 

Wyjtek operacji zmiennoprzecinkowej (patrz rozdzia powicony


obliczeniom arytmetycznym)

44

Asembler. Sztuka programowania

Tabela 1.4. Wyjtki zdefiniowane w pliku nagwkowym excepts.hhf cig dalszy


Identyfikator wyjtku

Znaczenie

!% ! A )

Wyjtek operacji zmiennoprzecinkowej (patrz rozdzia powicony


obliczeniom arytmetycznym)

!%(@* 

Wyjtek operacji zmiennoprzecinkowej (patrz rozdzia powicony


obliczeniom arytmetycznym)

!%@ %.

Wyjtek operacji zmiennoprzecinkowej (patrz rozdzia powicony


obliczeniom arytmetycznym)

!% 4?# 4

Wyjtek operacji zmiennoprzecinkowej (patrz rozdzia powicony


obliczeniom arytmetycznym)

!%0( %.

Wyjtek operacji zmiennoprzecinkowej (patrz rozdzia powicony


obliczeniom arytmetycznym)

!(C(

System operacyjny odrzuci niepoprawny uchwyt

! 4@ %.

System operacyjny zgosi przepenienie stosu

1.10. Biblioteka standardowa


jzyka HLA wprowadzenie
Jzyk HLA prezentuje si na tle tradycyjnego jzyka asemblerowego korzystnie dziki
dwm aspektom. Pierwszym jest skadnia jzyka HLA zapoyczajca elementy znane
z jzykw programowania wysokiego poziomu (jak struktury kontroli wykonania kodu czy deklaracje zmiennych). Dostpno tych elementw pozwala na efektywne wykorzystanie umiejtnoci przeniesionych z programowania wysokopoziomowego i tym
samym znacznie szybsz nauk jzyka asemblerowego. Drugim elementem stanowicym o przewadze HLA nad tradycyjnym asemblerem jest dostpno biblioteki HLA
Standard Library. Biblioteka standardowa jzyka HLA zawiera wiele prostych w uyciu
procedur jzyka asemblerowego realizujcych typowe zadania programistyczne ich
dostpno eliminuje konieczno samodzielnego pisania wszystkich, nawet tych najbardziej typowych, elementw programu. Dostpno biblioteki standardowej znosi jedn
z podstawowych trudnoci, w obliczu ktrych staj programici chccy pozna jzyk
asemblerowy trudno tkwic w koniecznoci samodzielnej implementacji zoonych
niekiedy procedur wejcia-wyjcia, niezbdnych w nawet najprostszych programach.
Brak standaryzowanej biblioteki wywoa powodowaby, e kady pocztkujcy programista powicaby mnstwo czasu na zaimplementowanie tak podstawowych operacji
jak wyprowadzanie napisw. Jej dostpno oznacza wic, e adept jzyka asemblerowego
moe skoncentrowa si na nauce samego jzyka, nie powicajc si od samego pocztku
zgbianiu tajnikw podsystemu wejcia-wyjcia danego systemu operacyjnego.
Dostpno rozmaitych procedur bibliotecznych to nie jedyna zaleta jzyka HLA. W kocu
biblioteki kodu asemblerowego to nie nowy wynalazek4. Jednak biblioteka standardowa
4

Popularna jest na przykad biblioteka UCR Standard Library dla programistw jzyka asemblerowego
procesorw 80x86.

Rozdzia 1. Wstp do jzyka asemblerowego

45

jzyka HLA to nie tylko sam kod procedur, ale rwnie wysokopoziomowy interfejs
wywoa tych procedur. W rzeczy samej jzyk HLA powsta gwnie z myl o moliwoci tworzenia zestaww procedur bibliotecznych wysokiego poziomu. w wysokopoziomowy interfejs wywoa, w poczeniu z wysokopoziomow natur wielu procedur, daje programicie niespodziewanie wielkie i rwnoczenie atwo dostpne
moliwoci.
Biblioteka standardowa jzyka HLA skada si z szeregu moduw przypisanych do
kilku kategorii. Cz z dostpnych moduw zawiera tabela 1.55.
Tabela 1.5. Wybrane moduy biblioteki standardowej HLA

Nazwa moduu

Funkcje

args

Procedury przetwarzania argumentw wiersza polecenia wraz z procedurami


pomocniczymi

conv

Procedury konwersji acuchw do wartoci rnych typw i konwersji odwrotnych

cset

Procedury operujce na zbiorach znakw

DateTime

Procedury manipulowania dat i czasem

excepts

Procedury obsugi wyjtkw

fileio

Procedury plikowych operacji wejcia-wyjcia

hla

Specjalne stae jzyka HLA i inne definicje

hll

Implementacja instrukcji znanych z jzykw wysokopoziomowych

Linux

Wywoania systemowe jdra systemu Linux (tylko w wersji HLA dla


systemu Linux)

math

Procedury implementujce obliczenia arytmetyczne o zwikszonej precyzji,


funkcje trygonometrycznych i inne funkcje matematyczne

memory

Procedury przydziau i zwalniania pamici wraz z procedurami pomocniczymi

misctypes

Definicje rozmaitych typw danych i operacji na tych typach

patterns

Biblioteka procedur dopasowywania wzorcw

rand

Implementacja generatora liczb pseudolosowych i procedur pomocniczych

stdin

Procedury obsugi wejcia

stdout

Procedury obsugi wyjcia

stdlib

Specjalny plik nagwkowy grupujcy wszystkie moduy biblioteki standardowej


jzyka HLA

strings

Biblioteka procedur manipulowania acuchami znakowymi

tables

Biblioteka procedur obsugi tablic asocjacyjnych

win32

Definicje staych wykorzystywanych w wywoaniach systemu Windows


(tylko w wersji HLA dla rodowiska Win32)

x86

Stae i definicje charakterystyczne dla procesora 80x86

Z racji cigego rozwoju biblioteki standardowej jzyka HLA niniejsza lista nie jest zapewne kompletna.
Aktualnej listy moduw naley szuka w dokumentacji jzyka HLA.

46

Asembler. Sztuka programowania

Cz z tych moduw doczeka si szczegowego omwienia w dalszej czci ksiki.


Tutaj skupimy si na najwaniejszych z punktu widzenia pocztkujcego programisty procedurach biblioteki standardowej HLA, zebranych w module   .

1.10.1. Stae predefiniowane w module stdio


Omwienie moduu    biblioteki standardowej naleaoby rozpocz od przedstawienia najczciej wykorzystywanych staych. Na przykad w nastpujcym kodzie:
()*)&+#82*
7=(+2'3

pojawia si staa  reprezentujca sekwencj znakw przejcia do nowego wiersza.


Identyfikator  nie jest w kontekcie programu HLA adnym sowem zarezerwowanym
jzyka HLA; jego zastosowanie nie ogranicza si te do wywoania    . Ot 
to jedynie staa, ktrej wartoci jest litera acuchowy odpowiadajcy sekwencji znakw
nowego wiersza (w systemie Windows sekwencja ta obejmuje znaki powrotu karetki
i wysuwu wiersza; w Linuksie to pojedynczy znak wysuwu wiersza).
Oprcz staej  implementacja podsystemu wejcia-wyjcia w bibliotece standardowej HLA zawiera definicje kilku innych przydatnych staych znakowych. Zostay one
wymienione w tabeli 1.6.
Tabela 1.6. Stae znakowe definiowane w module wejcia-wyjcia biblioteki standardowej HLA
Staa

Definicja

(, 

Znak dzwonka; wydrukowanie tego znaku objawia si wygenerowaniem dwiku przez


goniczek systemowy

(,

Znak cofania kursora

(,

Znak tabulacji

(%

Znak wysuwu wiersza

( 

Znak powrotu karetki

Z wyjtkiem  wszystkie zaprezentowane tu stae zdefiniowane s w przestrzeni


nazw    (std wymg poprzedzania nazw staych przedrostkiem   )6. Osadzenie
owych staych w przestrzeni nazw    pozwolio na uniknicie ewentualnych konfliktw z nazwami zmiennych definiowanymi przez programist. Nazwa , jako
uywana wyjtkowo czsto, nie zostaa osadzona w przestrzeni nazw    konieczno kadorazowego wpisywania     byaby bardzo uciliwa.

1.10.2. Standardowe wejcie i wyjcie programu


Wiele procedur wejcia-wyjcia biblioteki HLA jest prefiksowanych nazw    bd
  . Technicznie oznacza to, e nazwy tych procedur zdefiniowane zostay wewntrz
odpowiedniej przestrzeni nazw. W praktyce zastosowanie przedrostka stanowi rwnie sugesti co do pochodzenia danych (dane pobierane ze standardowego urzdzenia
6

Przestrzenie nazw omwione zostan w jednym z kolejnych rozdziaw.

Rozdzia 1. Wstp do jzyka asemblerowego

47

wejciowego,   ) bd ich przeznaczenia (dane kierowane do standardowego urzdzenia wyjciowego,   ). Najczciej urzdzeniem wejciowym jest klawiatura konsoli systemowej. Urzdzenie wyjciowe to zwykle ekran konsoli. W oglnoci wic instrukcje z przedrostkiem    bd   realizuj odczyty i zapisy danych z i do
urzdzenia konsoli.
Przy uruchamianiu programu z poziomu wiersza polece (zwanego w Linuksie powok)
mona dokona przekierowania strumieni danych wejciowych i wyjciowych do
urzdze innych ni domylne. Na przykad argument wywoania programu w postaci
 $.& powoduje przekierowanie standardowego wyjcia programu do pliku plik_wy.
Z kolei argument wywoania postaci  $. powoduje przypisanie standardowego
wejcia programu do pliku rdowego plik_we. Oto przykady przekierowania standardowego wejcia i wyjcia programu  % uruchamianego z poziomu wiersza
polece7:
 *=9 *)(
 *=9)*)!
 *=9 !)!

1.10.3. Procedura stdout.newln


Procedura    powoduje zapisanie do urzdzenia standardowego wyjcia sekwencji nowego wiersza. Wywoanie owej procedury jest rwnowane wywoaniu
   /01. Wywoanie    jest jednak niekiedy nieco wygodniejsze
bd bardziej czytelne. Oto przykad wywoania procedury:
() .&'3

1.10.4. Procedury stdout.putiN


Procedury biblioteczne    2,    3 oraz    4 wyprowadzaj na standardowe wyjcie programu pojedyncz warto, odpowiednio: 8-bitow,
16-bitow i 32-bitow, interpretowan jako liczba cakowita ze znakiem. Argumentem
wywoania moe by staa, rejestr bd zmienna w pamici rozmiar argumentu musi
jednak odpowiada rozmiarowi parametru formalnego procedury.
Omawiane procedury wyprowadzaj przekazan warto na standardowe wyjcie programu. Wyprowadzany napis reprezentujcy warto konstruowany jest z uyciem minimalnej liczby znakw pozwalajcych na dokadne odwzorowanie wartoci. Jeli przekazana argumentem wywoania procedury warto jest ujemna, napis zostanie poprzedzony
znakiem minusa. Oto kilka przykadw wywoa procedur    :
()*)&'3
()*)H&(!'3
()*)&;'3

Uwaga dla uytkownikw systemu Linux: w zalenoci od wartoci zmiennej rodowiskowej 5FC
nazw programu trzeba by moe poprzedzi znakami ./, np. I *=9 *)(.

48

Asembler. Sztuka programowania

1.10.5. Procedury stdout.putiNSize


Procedury    2- ,    3-  oraz    4-  zapisuj do
standardowego urzdzenia wyjciowego wartoci interpretowane jako liczby cakowite
ze znakiem a wic dziaaj podobnie jak procedury    . Tyle e procedury
   -  pozwalaj lepiej kontrolowa format wyprowadzanych napisw
programista moe odpowiednim argumentem wywoania procedury okreli minimaln
szeroko wyprowadzanego napisu. W przypadku kiedy wyprowadzana warto po konwersji bdzie zajmowaa mniejsz ni podano liczb znakw, brakujce znaki uzupeniane s znakami wypenienia znak wypenienia rwnie okrela si argumentem
wywoania procedury. Skadnia wywoania procedur    -  jest nastpujca:
()*)
&    2
2'3
()*)H
&  !"  2
2'3
()*)
&  #$  2
2'3

W miejsce parametru  


 mona przekaza sta, nazw rejestru albo nazw
zmiennej w pamici podany argument musi jednak odpowiada rozmiarem rozmiarowi parametru. Parametr  moe przyjmowa argumenty w postaci staych
cakowitych z zakresu od 256 do 256. Argumentem tego parametru moe by rwnie
zawarto rejestru bd warto zmiennej przechowywanej w pamici. Argumentem
parametru    powinien by pojedynczy znak.
Podobnie jak procedury     procedury    -  wyprowadzaj na
urzdzenie standardowego wyjcia napis reprezentujcy przekazan w wywoaniu warto
liczbow interpretowan jako liczb cakowit ze znakiem. W tej wersji programista
moe jednak okreli szeroko napisu okrela j jako minimaln liczb znakw, jak
powinien zajmowa napis. Jeli wywietlana warto zajmowa bdzie wicej znakw
(na przykad przy prbie wywietlenia wartoci 1234 w polu o szerokoci 2), to wyprowadzony napis zostanie stosownie poszerzony. Jednak w przypadku, gdy liczba znakw
w napisie jest mniejsza od zaoonego minimum, brakujce znaki s w kodzie procedury
uzupeniane znakami wypenienia. Kiedy wyprowadzana warto argumentu 
 jest liczb ujemn, napis zostanie wyrwnany w ramach wyprowadzanego pola do
lewej; warto dodatnia powoduje wyrwnywanie napisw do prawej.
Jeli warto bezwzgldna parametru  jest wiksza ni minimalna liczba
znakw potrzebnych do dokadnego reprezentowania wyprowadzanej wartoci, procedury    -  uzupeniaj napis znakami wypenienia, dodajc je z lewej
bd z prawej strony napisu (przed bd za znakow reprezentacj liczby). Znak wypenienia definiowany jest argumentem   . W zdecydowanej wikszoci
przypadkw znakiem tym jest znak spacji, jednak w sytuacjach szczeglnych konieczne
moe okaza si wypenienie innym znakiem. Naley tylko pamita, e argument parametru    powinien by wartoci znakow. W jzyku HLA stae znakowe
ujmowane s w znaki pojedynczego cudzysowu. W miejsce tego parametru mona te
wskaza omiobitowy rejestr.
Listing 1.4 prezentuje prosty program w jzyku HLA demonstrujcy sposb wykorzystania procedury    4-  w celu wywietlenia listy wartoci w formie
tabelarycznej.

Rozdzia 1. Wstp do jzyka asemblerowego

49

Listing 1.4. Wyprowadzenie kolumn wartoci liczbowych zastosowanie procedury stdout.puti32Size


*=9/)9 ?)9 3
J )( &+ (,##%+'

-3
??-3
, =/)9 ?)9 3
9&KH2'3
9&"2??'3
.# &"'(
%&?? '# 
 () .&'3
9&"2??'3
 (%3
 ()*)
&22$$'3
 ),&2'3
((&2??'3
 (.# 3
 () .&'3
(/)9 ?)9 3

1.10.6. Procedura stdout.put


Procedura    8 to najelastyczniejsza procedura wyprowadzania napisw na
wyjcie programu dostpna w module obsugi standardowego wyjcia. Procedura ta czy
funkcje wszystkich pozostaych procedur wyjcia standardowego, udostpniajc programicie elegancki i efektywny mechanizm wyprowadzania danych.
W najbardziej oglnej postaci skadnia wywoania procedury    prezentuje
si nastpujco:
()*)&
 %  '3

Lista argumentw wywoania procedury    moe zosta konstruowana ze


staych, rejestrw i zmiennych; kolejne argumenty oddziela si przecinkami. Procedura
wyprowadza na standardowe wyjcie wartoci wszystkich kolejnych argumentw wywoania. Jako e procedura ta bya ju wielokrotnie prezentowana w przykadach, Czytelnik
orientuje si, przynajmniej w zakresie podstawowym, co do sposobu jej wywoywania.
8

Tak naprawd ()*) to makrodefinicja, a nie procedura. Rozrnienie pomidzy makrodefinicj


a procedur wykracza jednak poza zakres niniejszego rozdziau; zostanie ono uwzgldnione w dalszej
czci ksiki.

50

Asembler. Sztuka programowania

Warto jedynie podkreli, e niniejsza procedura udostpnia programicie szereg waciwoci, ktre nie byy dotd prezentowane w przykadach. W szczeglnoci kady
z argumentw wywoania moe by zadany w jednej z dwch postaci:
 
 -


 moe by dowoln sta, rejestrem albo zmienn przechowywan w pamici.


W niniejszym rozdziale prezentowane byy argumenty w postaci literaw acuchowych
i zmiennych w pamici. Jak dotychczas wszystkie argumenty wywoania odpowiaday
pierwszej moliwej postaci argumentu. W postaci drugiej programista moe po dwukropku okreli minimaln szeroko napisu reprezentujcego warto szeroko
ta interpretowana jest podobnie jak w procedurach    - 9. Przykadowy
program z listingu 1.5 generuje wydruk podobny do tego tworzonego programem
5(), tyle e tutaj miejsce procedury    -  zaja procedura
   .
Listing 1.5. Demonstracja sposobu okrelenia szerokoci napisw w argumentach procedury stdout.put
*=9/)9 ?)9 3
J )( &+ (,##%+'

-3
??-3
, =/)9 ?)9 3
9&KH2'3
9&"2??'3
.# &"'(
%&?? '# 
 () .&'3
9&"2??'3
 (%3
 ()*)&-'3
 ),&2'3
((&2??'3
 (.# 3
 () .&'3
(/)9 ?)9 3

Procedura    obsuguje jednak wicej atrybutw. Bd one omawiane w kolejnych rozdziaach, w miar potrzeby ich wprowadzania do programw przykadowych.
9

W odrnieniu od procedur stdout.putiNSize nie da si tu okreli dowolnego znaku wypenienia


znakiem tym jest domylnie znak spacji. W obliczu koniecznoci zastosowania innego wypenienia
naley skorzysta z procedur stdout.putiNSize.

Rozdzia 1. Wstp do jzyka asemblerowego

51

1.10.7. Procedura stdin.getc


Procedura    % ! wczytuje pojedynczy znak z bufora urzdzenia standardowego
wejcia10. Znak ten umieszczany jest po wyjciu z procedury w rejestrze AL. Zastosowanie procedury ilustruje program z listingu 1.6.
Listing 1.6. Demonstracja dziaania procedury stdin.getc
*=9 #*)3
J )( &+ (,#%%+'

 ) -3
, = #*)3
// Ponisza ptla wykonywana jest dopty,
// dopki uytkownik potwierdza wykonanie kolejnej iteracji.
 * 
// Wyprowad 14 wartoci.
9&L2 ) '3
.# & ) "'(
 ()*)& ) -'3
 ),&2 ) '3
 (.# 3
// Zaczekaj, a uytkownik nacinie 't' albo 'n'.
 ()*)&22+674 4 8  8 &I'M-+'3
%  
 ( (1&'3
 (=  &'3
, 4%& $$'3
, 4%& $$'3
 ()*)&+5
.*.(
 ,$$2,$$-+'3
 (%3
 () .&'3
)& $$'3
( #*)3

10

Bufor to w tym kontekcie adniejsza nazwa tablicy.

52

Asembler. Sztuka programowania

W powyszym programie wywoanie procedury    6 suy do wymuszenia


przejcia do nowego wiersza strumienia wejciowego. Szczegowy opis tej procedury
znajduje si nieco dalej, w niniejszym rozdziale.

1.10.8. Procedury stdin.getiN


Procedury    % 2,    % 3 oraz    % 4 realizuj operacj wczytania
z urzdzenia standardowego wejcia odpowiednio: 8-bitowej, 16-bitowej i 32-bitowej
wartoci liczbowej cakowitej. Wczytane wartoci umieszczane s w rejestrach AL, AX
bd EAX. Niniejsze procedury stanowi standardowy sposb wczytywania liczb cakowitych ze znakiem do programw jzyka HLA.
Podobnie jak procedura    % !, procedury    %  wczytuj ze standardowego
wejcia sekwencj znakw. W sekwencji tej ignorowane s wszelkie pocztkowe znaki
odstpw (spacje, znaki tabulacji i tak dalej); reszta sekwencji (zawierajca cyfry poprzedzone opcjonalnym znakiem minusa) konwertowana jest do postaci liczbowej. W przypadku, kiedy sekwencja wejciowa zawiera znaki inne ni dozwolone lub wprowadzona
warto nie mieci si w zakresie liczbowym charakterystycznym dla danej procedury,
zgaszany jest wyjtek (mona go przechwyci, umieszczajc wywoanie procedury
w bloku kodu chronionego w instrukcji &  &). Procedura    % 2 obsuguje
liczby z zakresu od 128 do 127,    % 3 od 32 768 do 32 767; wartoci
wczytywane do programu za porednictwem procedury    % 4 musz za mieci
si w przedziale od 2 147 483 648 do 2 147 483 647.
Sposb wykorzystania owych procedur ilustruje listing 1.7.
Listing 1.7. Przykad wykorzystania wywoa stdin.getiN
*=9*)3
J )( &+ (,##%+'
-3
H-H3
-3
, =*)3
// Pobierz od uytkownika kilka liczb cakowitych rnej wielkoci.
 ()*)&+6*.(
 . 4
,  4.&

4 )N'-+'3
 (= &'3
9&2'3
 ()*)&+6*.(
. 4

,  4.&

4 )NHNHN'-+
'3
 (= H&'3
9&!2H'3
 ()*)&+6*.(

,  4.&

4 )((9(.'-+'3
 (= &'3

Rozdzia 1. Wstp do jzyka asemblerowego

53

9& !2'3
// Wywietl podane wartoci.
 ()*)
&
2
+@.*.(
 
,7-+222
+,.
, 4.-+2-22
+H,.
, 4.-+2H-22
+,.
, 4.-+2-2
'3
(*)3

Warto skompilowa i uruchomi powyszy program i sprawdzi, co si stanie, jeli wprowadzane liczby bd wykraczay poza dozwolony zakres albo cigi wartoci zawiera
bd niedozwolone znaki.

1.10.9. Procedury stdin.readLn i stdin.flushInput


Moment wywoania procedury    % ! czy    % 4 nie musi by tosamy z momentem wprowadzenia danych przez uytkownika. Biblioteka standardowa jzyka HLA
buforuje dane wprowadzane na standardowe wejcie, wczytujc jednorazowo cay
wiersz tekstu wprowadzanego na to wejcie. Wywoanie procedury wejcia moe wic
zosta zrealizowane za porednictwem operacji odczytu danych z bufora wejciowego
(o ile ten nie jest pusty). Cho buforowanie w oglnoci poprawia efektywno manipulowania danymi wejciowymi, niekiedy wprowadza zamieszanie, jak w poniszym
przykadzie:
()*)&+6*.(
 . 4
,  4.&

4 )N'-+'3
(= &'3
9&2'3
()*)&+6*.(
. 4

,  4.&

4 )NHNHN'-+'3
(= H&'3
9&!2H'3

Programista ma nadziej, e wykonanie powyszego kodu da nastpujcy efekt: program


wywietli monit o podanie liczby, zaczeka na wprowadzenie jej przez uytkownika,
wywietli kolejny monit i rwnie zaczeka na wprowadzenie liczby. W rzeczywistoci
program moe mie nieco inny przebieg. Jeli, na przykad, powyszy kod zostanie uruchomiony, a uytkownik w odpowiedzi na pierwszy monit wprowadzi acuch 123 456
program nie bdzie ju po wywietleniu drugiego monitu oczekiwa na wprowadzenie
danych procedura    % 3 odczyta po prostu drugi z wprowadzonych do bufora
wejciowego acuchw (456).
Procedury wejcia oczekuj na wprowadzenie tekstu przez uytkownika jedynie wtedy,
kiedy bufor wejciowy jest pusty. Dopki zawiera on jakiekolwiek znaki, procedury
wejcia ograniczaj si do odczytu z bufora. Mona to wykorzysta, konstruujc nastpujcy kod:

54

Asembler. Sztuka programowania


()*)&+6*.(
(. 
,7 4. -+'3
(= &'3
9& !2'3
(= &'3
9& !2# ;'3

Tutaj zezwala si wprost uytkownikowi na jednorazowe (w ramach pojedynczego


wiersza) wprowadzenie dwch liczb. Liczby te powinny zosta oddzielone jednym bd
kilkoma znakami odstpu. Pozwala to na zaoszczdzenie miejsca na ekranie. Tutaj
buforowanie danych wejciowych okazao si korzystne. Kiedy indziej jednak moe
by odwrotnie.
Na szczcie biblioteka standardowa jzyka HLA przewiduje dwie procedury sterujce
dziaaniem bufora standardowego urzdzenia wejciowego. S to procedury    6
oraz   
 ( . Pierwsza z nich usuwa z bufora wszystko, co zostao w nim
umieszczone wczeniej, i tym samym wymusza wprowadzenie przez uytkownika nowego wiersza danych. Druga po prostu usuwa ca zawarto bufora. Oczyszczenie bufora
powoduje, e przy nastpnym wywoaniu dowolnej z procedur wejcia, uytkownik
bdzie musia wprowadzi nowy wiersz danych. Procedur    6 wywouje
si zwykle bezporednio przez wywoaniem dowolnej procedury wejcia. Procedura
  
 ( wywoywana jest za typowo bezporednio po odczytaniu danych
z bufora wybran procedur wejcia.
Jeli w programie wykorzystywana jest procedura    6 i okae si, e
konieczne jest dwukrotne wprowadzenie danych, to naley zastanowi si nad wykorzystaniem w jej miejsce procedury   
 ( . W oglnoci ta ostatnia procedura, pozwalajca na oprnienie bufora przez kolejn operacj wejcia, jest wykorzystywana znacznie czciej. Konieczno zastosowania procedury    6
jest bardzo rzadka naley j stosowa wycznie tam, gdzie konieczne jest wymuszenie na uytkowniku wprowadzenia nowego, aktualnego wiersza danych.

1.10.10. Procedura stdin.get


Procedura    % czy w sobie przedstawione wczeniej procedury wejcia, udostpniajc ich funkcje za porednictwem pojedynczego wywoania. Procedura    %
jest przy tym nieco prostsza w uyciu ni    , poniewa jedynymi argumentami wywoania tej pierwszej s nazwy zmiennych (lub rejestrw), w ktrych maj
zosta umieszczone wczytane wartoci.
Przyjrzyjmy si ponownie przykadowi z poprzedniego punktu:
()*)&+6*.(
(. 
,7 4. -+'3
(= &'3
9& !2'3
(= &'3
9& !2# ;'3

Rwnowany przykad wykorzystujcy procedur    % wygldaby nastpujco:


()*)&+6*.(
(. 
,7 4. -+'3
(= &2# ;'3

Rozdzia 1. Wstp do jzyka asemblerowego

55

Jak wida, zastosowanie procedury    % moe program skrci i zwikszy jego


czytelno.
Naley przy tym pamita, e wywoanie procedury    % powoduje umieszczenie
wczytanych wartoci od razu we wskazanych zmiennych; adne z wczytanych wartoci
nie pojawi si w rejestrach, chyba e rejestry te wystpi na licie argumentw wywoania. Argumentami wywoania mog by zarwno nazwy zmiennych, jak i nazwy
rejestrw.

1.11. Jeszcze o ochronie wykonania


kodu w bloku try..endtry
Jak zapewne Czytelnik pamita, instrukcje &  & otaczaj blok kodu, ktrego
wykonanie moe potencjalnie sprowokowa wyjtki zakcajce dziaanie programu.
Wyjtki mog mie trzy rda: mog by zgaszane sprztowo (np. w przypadku dzielenia przez zero), generowane przez system operacyjny albo podnoszone wykonaniem
odpowiedniej instrukcji jzyka HLA. Programista moe przechwytywa i obsugiwa
sytuacje wyjtkowe, umieszczajc stosowny kod w ramach klauzuli ! . Typowy
przykad zastosowania instrukcji &  & ilustruje listing 1.8.
Listing 1.8. Przykad zastosowania bloku try..endtry
*=9 (*)3
J )( &+ (,##%+'3
 )-) H3
, = (*)3
7
 ()*)&+6*.(

,  4.,

4)-+'3
 (= &)'3
 ()*)&+6*.(
-+2)2'3
 ! *& !?  '
 ()*)&+6*.(
7 =
.  (
. 
4+'3
 ! *& !;) @)@%A= '
 ()*)&+6*.(

,8 
,7()
+'3
 (73
( (*)3

56

Asembler. Sztuka programowania

W jzyku HLA instrukcje znajdujce si za sowem &, a przed pierwsz klauzul


!  nosz miano instrukcji chronionych. Jeli podczas wykonywania takich
instrukcji zgoszony zostanie wyjtek, sterowanie zostanie przekazane do pierwszej
klauzuli !  skojarzonej z danym wyjtkiem, przeszukujc kolejne klauzule pod
ktem zgodnoci identyfikatora wyjtku zadeklarowanego ze zgoszonym11. Identyfikator wyjtku to po prostu 32-bitowa liczba. Std rwnie kada warto umieszczana
w nawiasach klauzuli !  powinna by wartoci 32-bitow. Predefiniowane
wartoci wyjtkw jzyka HLA wymienione s w pliku excepts.hhf. I cho byoby to niewtpliwie racym naruszeniem przyjtego powszechnie stylu programowania, w klauzulach !  dozwolone jest podawanie wprost wartoci numerycznych wyjtkw
bez korzystania z predefiniowanych nazw staych.

1.11.1. Zagniedone bloki try..endtry


Jeli w wyniku przeszukania klauzul !  nie nastpi dopasowanie identyfikatora
wyjtku, bdzie miao miejsce przeszukanie klauzul nadrzdnego bloku &  &,
w ktrym blok biecy jest zagniedony dynamicznie. Spjrzmy na przykad z listingu 1.9.
Listing 1.9. Zagniedanie instrukcji try..endtry
*=9 (*)3
J )( &+ (,##%+'3
 )-) H3
, = (*)3
7
7
 ()*)&+6*.(

,  4.,

4)-+'3
 (= &)'3
 ()*)&+6*.(
-+2)2'3
 ! *& !?  '
 ()*)&+6*.(
7 =
.  (
. 
4+'3
 (73
 ()*)&+( .74
*
*  
4 )+'3
 ! *& !;) @)@%A= '

11

W programie HLA identyfikator ten umieszczany jest w rejestrze EAX. Std po przekazaniu sterowania
do odpowiedniej klauzuli ! * mona odwoywa si do identyfikatora wyjtku, odwoujc si
do rejestru EAX.

Rozdzia 1. Wstp do jzyka asemblerowego

57

 ()*)&+6*.(

,8 
,7()
+'3
 (73
( (*)3

Na listingu 1.9 wida zagniedone dwa bloki instrukcji &  &. Jeli w ramach
wykonania instrukcji    % uytkownik wprowadzi warto wiksz od 4 miliardw
z kawakiem, procedura    % podniesie wyjtek  + +
,%. Kiedy wyjtek
ten zostanie przekazany do systemu wykonawczego HLA, nastpi przeszukanie klauzul
!  biecego bloku &  & (tego, w ktrym nastpio zgoszenie wyjtku;
w prezentowanym przykadzie jest to blok zagniedony). Jeli nie uda si dopasowa
identyfikatora wyjtku  + +
,% w biecym bloku &  &, system
wykonawczy HLA sprawdzi, czy biecy blok &  & nie zosta zagniedony
w innym bloku &  & (co akurat ma miejsce na listingu 1.9). W takim przypadku
system wykonawczy HLA przeszuka rwnie klauzule !  bloku zewntrznego
(nadrzdnego). Na listingu 1.9 w blok zawiera klauzul z odpowiedni wartoci identyfikatora, wic sterowanie przekazywane jest do pierwszej instrukcji umieszczonej za
klauzul ! / + +
,%0.
Po opuszczeniu bloku &  & system wykonawczy traktuje w blok jako nieaktywny i jeli teraz nastpi zgoszenie wyjtku, system wykonawczy HLA nie bdzie
przeszukiwa klauzul !  tego bloku12. Pozwala to na rnicowanie procedur
obsugi wyjtkw w rnych miejscach programu.
Jeli ten sam wyjtek obsuguj dwa bloki &  &, a jeden z tych blokw jest
zagniedony w bloku chronionym pierwszego, to w momencie zgoszenia wyjtku
podczas wykonywania wewntrznego bloku chronionego system wykonawczy HLA
przekae sterowanie do kodu obsugi wyjtku w wewntrznym bloku &  &.
Kod obsugi tego samego wyjtku w zewntrznym bloku jest ignorowany HLA nie
przekazuje sterowania do tego kodu.
W przykadzie z listingu 1.9 druga instrukcja &  & zostaa statycznie zagniedona w pierwszym bloku &  &13. Wczeniej wspomniano, e jeli biecy blok
&  & nie zawiera kodu obsugi zgoszonego wyjtku, nastpuje przeszukanie
klauzul !  kolejnych blokw &  &, w ktrych blok biecy zosta zagniedony dynamicznie. W przypadku zagniedenia dynamicznego zagniedenie nie wynika wprost ze struktury kodu rdowego. Sterowanie moe zosta przekazane z wntrza
bloku &  & do zupenie innego miejsca programu, niby to wynikao z samej
struktury kodu. Jeli w tamtym miejscu realizowany jest blok chroniony instrukcji
&  &, to mamy do czynienia z zagniedeniem dynamicznym. Zagniedenie dynamiczne mona zrealizowa na kilka sposobw, a najbardziej chyba intuicyjnym (i zapewne znanym Czytelnikowi z jzykw wysokiego poziomu) z nich jest wywoanie
12

13

Chyba e sterowanie zostanie wczeniej przekazane z powrotem do bloku 7 (7, na przykad
kiedy jest on umieszczony w ciele ptli.
Zagniedenie statyczne naley rozumie jako fizyczne, bo wynikajce wprost ze struktury kodu
rdowego, umieszczenie jednego bloku wewntrz drugiego. Kiedy mowa o zagniedaniu instrukcji,
zwykle chodzi o zagniedanie statyczne.

58

Asembler. Sztuka programowania

procedury. Kiedy wic w dalszej czci ksiki omawiany bdzie sposb pisania i wywoywania procedur w jzyku asemblerowym, naley pamita, e wywoanie procedury
z bloku kodu chronionego moe doprowadzi do dynamicznego zagniedenia blokw
&  & wystarczy, aby procedura rwnie zawieraa blok &  & (i aby
zosta on wykonany).

1.11.2. Klauzula unprotected bloku try..endtry


Wykonywanie instrukcji & powoduje zawsze zachowanie biecego rodowiska wyjtkw i przygotowanie systemu wykonawczego (na wypadek zgoszenia wyjtku) do przekazania sterowania do odpowiedniej klauzuli ! . Jeli program przebrnie przez
blok instrukcji chronionych, pierwotne rodowisko wyjtkw jest przywracane, a sterowanie przekazywane jest do pierwszej instrukcji znajdujcej si za klauzul  &.
Bardzo wan rol w tej procedurze ma ostatni jej etap, czyli przywrcenie pierwotnego rodowiska wyjtkw. W przypadku jego pominicia wszelkie kolejne wyjtki
powodowayby przekazanie sterowania do opuszczonego ju bloku &  &. Problem
ten ilustruje listing.1.10.
Listing 1.10. Niepoprawne opuszczenie bloku instrukcji try..endtry
*=9 (*)L3
J )( &+ (,##%+'

*)-) 3
, = (*)L3
// Ponisza ptla jest kontynuowana dopty, dopki uytkownik wprowadza
// nieprawidow liczb; wyjcie z ptli nastpuje w wyniku wykonania instrukcji break.
%  
7
 ()*)&+5(8
,  4.-+'3
 (= &*)'3
 ()*)&+6*.(
-+2*)2'3
, 43
 ! *& !;) @)@%A= '
 ()*)&+1
,8 
,7()
3*.
.*.(
 +'3
 ! *& !?  '
 ()*)&+?=
.  (
. 
43*.
.*.(
 +
'3
 (73
 (%3

Rozdzia 1. Wstp do jzyka asemblerowego

59

// Uwaga: poniszy kod znajduje si poza ptl i nie jest osadzony w bloku chronionym
// instrukcji try..endtry
 ()*)&+5(88

8 (
, -+'3
 (= &*)'3
 ()*)&+/.
,-+2*)2'3
( (*)L3

Niniejszy przykad z pozoru implementuje niezawodny, odporny na bdy system wprowadzania danych: wok bloku kodu chronionego rozcignita jest ptla wymuszajca
ponowne wprowadzenie danych przez uytkownika, jeli w poprzedniej prbie nie
udao si ich poprawnie odczyta. Pomys jest dobry; problem tkwi w jego nieprawidowej realizacji. Ot instrukcja $ powoduje opuszczenie ptli
 

bez przywrcenia poprzedniego stanu rodowiska wyjtkw. Z tego wzgldu, kiedy
program wykonuje procedur    % umieszczon poza ptl (a tym bardziej poza
blokiem kodu chronionego), system obsugi wyjtkw wci traktuje jej kod jako chroniony. Jeli wic przy okazji jego wykonania zgoszony zostanie wyjtek, sterowanie
zostanie przekazane z powrotem do stosownej klauzuli !  opuszczonego ju
przecie bloku &  &. Jeli identyfikatorem wyjtku bdzie  + +
,%
albo  ) *, wywietlony zostanie stosowny komunikat, a uytkownik
ponownie zmuszony bdzie do wprowadzenia liczby. Tego za programista raczej
nie przewidywa.
Przekazanie sterowania do nieodpowiedniego bloku &  & to tylko cz problemu. Kod z listingu 1.10 obarczony jest inn powan wad, zwizan ze sposobem
zachowywania i nastpnie przywracania przez system wykonawczy HLA rodowiska
wyjtkw. W szczeglnoci bowiem HLA zachowuje informacje o stanie systemu
wyjtkw w specjalnym obszarze pamici zwanym stosem. Jeli po wyjciu z bloku
&  & stan rodowiska wyjtkw nie zostanie przywrcony, informacje o tym
rodowisku pozostan na stosie; obecno na nim nadmiarowych danych moe za doprowadzi do bdnego dziaania programu.
Jest ju chyba jasne, e program nie powinien opuszcza bloku &  & z pominiciem etapu przywrcenia pierwotnego stanu rodowiska wyjtkw. Wiadomo, e
sposb wprowadzania danych zaprezentowany na listingu 1.10 jest niepoprawny, ale
z drugiej strony sama koncepcja wymuszania powtarzania operacji wprowadzania a
do skutku jest jak najbardziej suszna. Mona j zaimplementowa przy uyciu specjalnej klauzuli bloku &  &. Spjrzmy na kod z listingu 1.11.
Listing 1.11. Blok pozbawiony ochrony wewntrz bloku try..endtry
*=9 (*)3
J )( &+ (,##%+'

*)-) 3
, = (*)3

60

Asembler. Sztuka programowania


// Ponisza nieskoczona ptla wykonywana jest dopty, dopki uytkownik wprowadza
// niepoprawne dane. Wyjcie z ptli nastpuje w wyniku wykonania instrukcji break.
// Instrukcja ta, mimo e obecna wewntrz bloku try..endtry, znajduje si w bloku
// kodu niechronionego sygnalizowanego klauzul unprotected.
%  
7
 ()*)&+5(8
,  4.-+'3
 (= &*)'3
 ()*)&+6*.(
-+2*)2'3
)*  (
, 43
 ! *& !;) @)@%A= '
 ()*)&+1
,8 
,7()
3*.
.*.(
 +'3
 ! *& !?  '
 ()*)&+?=
.  (
. 
43*.
.*.(
 +
'3
 (73
 (%3
// Uwaga: poniszy kod znajduje si poza ptl i nie jest osadzony w bloku chronionym
// instrukcji try..endtry
 ()*)&+5(88

8 (
, -+'3
 (= &*)'3
 ()*)&+/.
,-+2*)2'3
( (*)3

Osignicie klauzuli  !  inicjuje operacj przywrcenia pierwotnego stanu


rodowiska wyjtkw. Oczywiste jest, e po przejciu do bloku kodu niechronionego
wykonanie kodu nie jest ju chronione na wypadek zgoszenia wyjtkw. Klauzula
 !  nie znosi jednak ochrony kodu realizowanej w dynamicznie zagniedonych zewntrznych blokach &  & klauzula  !  odnosi si jedynie
do tego bloku &  &, w ktrym zostaa umieszczona. Jako e na listingu 1.11
instrukcja przerywajca ptl, $, znajduje si za klauzul  ! , przekazanie
sterowania poza ptl odbywa si po uprzednim przywrceniu stanu wyjtkw.
Sowo  ! , jeli ju wystpuje w ramach instrukcji &, powinno znajdowa
si bezporednio za blokiem kodu chronionego. Musi wic poprzedza wszystkie klauzule ! .

Rozdzia 1. Wstp do jzyka asemblerowego

61

W obliczu zgoszenia wyjtku system wykonawczy HLA automatycznie przywraca


pierwotny stan rodowiska wykonania. Z tego wzgldu w ramach kodu obsugi wyjtku,
po klauzuli !  mona swobodnie korzysta z instrukcji $, nie obawiajc si
o negatywne efekty charakterystyczne dla niepoprawnego opuszczenia bloku &  &.
Z racji przywrcenia pierwotnego stanu wyjtkw w bloku niechronionym oraz w kodzie
obsugi wyjtku po klauzuli ! , wystpienie wyjtku w jednym z tych obszarw
powoduje natychmiastowe przekazanie sterowania do zewntrznego bloku &  &,
w ktrym blok biecy zosta dynamicznie zagniedony. W przypadku braku takiego
bloku program jest awaryjnie przerywany, a na standardowe wyjcie wyprowadzany
jest stosowny komunikat o bdzie.

1.11.3. Klauzula anyexception bloku try..endtry


Typowo instrukcji & towarzyszy szereg klauzul !  obsugujcych wszelkie
wyjtki, ktrych wystpienie w kodzie chronionym zdoa przewidzie programista.
Niekiedy to nie wystarcza konieczne jest wtedy zapewnienie obsugi wszystkich moliwych (a nie tylko przewidzianych) wyjtkw, aby program nie zosta przedwczenie
zakoczony. Jeli programista jest autorem caoci kodu bloku chronionego, powinien
by zdolny do przewidzenia wszystkich sytuacji wyjtkowych zwizanych potencjalnie
z wykonaniem bloku. Jeli jednak w bloku tym znajduj si wywoanie procedury bibliotecznej, wywoanie funkcji interfejsu systemu operacyjnego czy inne instrukcje, nie
w peni kontrolowane przez programist, przewidzenie wszystkich moliwych wyjtkw
moe by niemoliwe. Tymczasem zgoszenie wyjtku o identyfikatorze innym ni
identyfikatory podane w kolejnych klauzulach !  moe doprowadzi do zaamania
programu. Szczliwie jzyk HLA przewiduje umieszczenie w bloku &  &
klauzuli &! , do ktrej dopasowywane s wszystkie wyjtki, ktrych identyfikatorw nie uda si odpasowa do klauzul ! .
Klauzula &!  nie rni si wiele od klauzuli !  jedyna odmienno
tkwi w braku koniecznoci okrelania identyfikatora wyjtku (to oczywiste). Jeli obok
klauzul !  w bloku &  & znajduje si klauzula &! , powinna
ona by ostatni klauzul obsugi wyjtkw w bloku. Dopuszczalne jest naturalnie, aby
klauzula &!  bya jedyn klauzul obsugi wyjtkw w bloku &  &.
Po przekazaniu sterowania do klauzuli &!  identyfikator wyjtku umieszczany jest w rejestrze EAX. Identyfikator ten mona w ramach kodu obsugi wyjtku
sprawdza, dopasowujc obsug do przyczyny zgoszenia wyjtku.

1.11.4. Instrukcja try..endtry i rejestry


Kadorazowe wkroczenie do bloku &  & oznacza konieczno zachowania na
stosie 16 bajtw informacji o stanie rodowiska wyjtkw. Przywrcenie rodowiska
wyjtkw po opuszczeniu tego bloku (albo w wyniku osignicia klauzuli  ! )
wymaga odczytania wanie owych 16 bajtw. Do momentu zgoszenia wyjtku realizowanie kodu chronionego nie wpywa na zawarto adnych rejestrw. Sytuacja zmienia
si w momencie zgoszenia wyjtku w wyniku wykonania instrukcji kodu chronionego.

62

Asembler. Sztuka programowania

Po przejciu do klauzuli !  rejestr EAX zawiera identyfikator (numer) wyjtku.


Reszta rejestrw oglnego przeznaczenia zawiera wartoci nieokrelone. Poniewa
system operacyjny moe zgosi wyjtek w reakcji na bd sprztowy, nie powinno
si nawet zakada, e rejestry oglnego przeznaczenia zawiera bd po rozpoczciu
obsugi wyjtku wartoci, ktre znajdoway si w nich pierwotnie. Kod generowany przez
system HLA do obsugi wyjtkw moe by rny w rnych wersjach kompilatora,
wic poleganie na zawartoci rejestrw w kodzie obsugi wyjtkw jest co najmniej
ryzykowne.
Jako e po przejciu do bloku kodu obsugi wyjtku nie mona czyni adnych zaoe
co do zawartoci rejestrw (z wyjtkiem rejestru EAX), to jeli kod kontynuowany za
klauzul  & zakada obecno w rejestrach jakich konkretnych wartoci (np.
wartoci umieszczonych tam przed wkroczeniem do bloku kodu chronionego), naley te
wartoci przywrci samodzielnie. Zaniedbanie tego moe doprowadzi do bdnego
dziaania programu, przy czym bdy tego rodzaju s tym trudniejsze do wykrycia, e
sytuacje wyjtkowe z definicji zdarzaj si rzadko, co utrudnia odtworzenie i diagnostyk
bdu; dodatkowym utrudnieniem jest to, e nie zawsze zgoszenie wyjtku musi zmieni
warto konkretnego rejestru. Sposb rozwizania problemu zachowania wartoci rejestrw prezentuje nastpujcy fragment kodu:

 )9-3
O
9&"2 )9'3
%&9&"2 ,!'3 ,! 3 & ,!''(
*) #& ,!'3// Zachowanie wartoci rejestru EBX na wypadek wyjtku.
%  
7
 (= &'3
)*  (, 43
 ! *& !?  '
 ()*)&+/ (
..PQ3 *,)8*. -+'3
 (73
 (%3
**& ,!'3// Przywrcenie zawartoci rejestru EBX.
((& ,!2 !'3
((& !2 )9'3
(%3

Poniewa mechanizm obsugi wyjtkw powoduje potencjalne zmiany wartoci rejestrw i poniewa obsuga wyjtkw to proces stosunkowo nieefektywny, nie powinno si
stosowa instrukcji & w roli zwykej struktury sterujcej wykonaniem programu (na
przykad symulujc w bloku &  & dziaanie instrukcji wyboru znanych z jzykw
wysokiego poziomu, jak ! czy  ! ). Takie praktyki wpywaj ujemnie na wydajno programu; mog tez wprowadza niepodane, trudne do wykrycia i zdiagnozowania efekty uboczne wynikajce z zakcania zawartoci rejestrw.

Rozdzia 1. Wstp do jzyka asemblerowego

63

Dziaanie mechanizmu wyjtkw opiera si na zaoeniu, e rejestr EBP wykorzystywany jest wycznie w roli wskanika rekordw aktywacji (rekordy aktywacji
omawiane s w rozdziale powiconym procedurom). Standardowo programy HLA
wykorzystuj w rejestr wanie w tej roli. Warunkiem poprawnego dziaania programw jest wic unikanie modyfikowania zawartoci rejestru EBP. Jeli rejestr ten
zostanie uyty w roli rejestru oglnego przeznaczenia, na przykad w obliczeniach
arytmetycznych, obsuga wyjtkw systemu wykonawczego HLA nie bdzie dziaa
poprawnie, pojawi si te mog dodatkowe problemy. To samo tyczy si zreszt rejestru ESP jego rwnie nie naley wykorzystywa jako rejestru oglnego przeznaczenia.

You might also like