• Nie Znaleziono Wyników

Programowanie komputera

N/A
N/A
Protected

Academic year: 2021

Share "Programowanie komputera"

Copied!
14
0
0

Pełen tekst

(1)

1

Programowanie komputera

Program jest algorytmem przetwarzania danych zapisanym w sposób zrozumiały dla komputera. Procesor rozumie wyłącznie rozkazy zapisane w kodzie maszynowym (ciąg 0 i 1).

Ponieważ jest to zapis bardzo trudny do zrozumienia dla człowieka już na początku ery komputerów stworzono język symboliczny, w którym rozkazom procesora, rejestrom, miejscom w pamięci przyporządkowano nazwy symboliczne. Instrukcja pisana przez programistę nie wyglądała już tak:

001 01 10010 lecz np. tak:

add A, wzrost

Był to zapis bardziej zrozumiały dla człowieka lecz instrukcje te nie są bezpośrednio zrozumiałe dla procesora – on ostatecznie rozumie tylko ciągi zer i jedynek. Program zapisany w języku asembler musi być przetłumaczony na kod maszynowy, musi przy tym spełniać ścisłe reguły składni danego języka.

Program napisany w języku asembler jest wciąż bliższy konstrukcji maszyny (odzwierciedla jej konstrukcję, zasoby sprzętowe, listę rozkazów) niż sposobowi myślenia o problemach przez człowieka i sposobami wyrażania rozwiązań tych problemów. Stąd obserwujemy gwałtowny rozwój nowych języków programowania tzw. wysokopoziomowych, dedykowanych do rozwiązywania określonych klas problemów. Programy napisane w takich językach przed wykonaniem przez procesor muszą być tłumaczone (kompilowane lub interpretowane) na język maszynowy.

Pisanie programów w języku asembler pozwala bliżej zapoznać się z działaniem procesora, poznać jego możliwości i ograniczenia. Czasami wymagane jest połączenie programu napisanego w języku wysokopoziomowym z funkcją napisaną w języku asembler aby spełnić krytyczne wymagania dotyczące wykorzystania zasobów komputera lub szybkości realizacji programu.

Struktura programu typu program.com

; program według modelu tiny

name "mycode" ; nazwa pliku wyjściowego (maksymalnie 8 znaków) org 100h ; początek programu od adresu IP = 100h

; kod programu

ret ; koniec programu i powrót do systemu operacyjnego.

msg db "press any key..." ; deklaracje zmiennych

(2)

2

Struktura programy typu program.exe

; program wykonywalny wielosegmentowy.

data segment

; tutaj umieszczamy deklaracje danych ends

stack segment

dw 128 dup(0) ; określenie wielkości stosu ends

code segment

start: ; początek programu

; ustawienie wartości rejestrów segmentowych:

mov ax, data mov ds, ax mov es, ax

; kod programu

mov ax, 4c00h ; zakończenie programu i powrót do system operacyjnego.

int 21h ends

end start ; ustawienie punktu startu programu i koniec instrukcji w assemblerze.

Program w assemblerze składa się z dyrektyw kompilatora, instrukcji, deklaracji zmiennych i stałych.

Dyrektywa kompilatora nie jest tłumaczona na kod wynikowy – określa tylko jak ma przebiegać kompilacja i jak zarządzać kodem wynikowym. Dyrektywa ORG 100h w programach typu .com określa, że instrukcje programu powinny zaczynać się od adresu 100h w segmencie kodu. Pierwsze 256 B (100h) zarezerwowane są dla potrzeb systemu operacyjnego w celu komunikacji z programem ( np. przekazanie parametrów uruchomienia programu). Dyrektywy mogą sterować warunkową kompilacją programu, definiować makroinstrukcje i in.

Zmienne określają miejsce przechowywania danych i ich typ. Dane te mogą znajdować się w rejestrach procesora, ale ze względu na ograniczoną liczbę rejestrów, miejscem ich przechowywania jest głównie pamięć operacyjne. Procesor korzysta z pamięci operacyjnej podając adres komórki z którą chce się skontaktować. Adresy są długimi liczbami binarnymi (np. 20 bitów) i ze względów praktycznych podczas deklaracji zmiennych adresom komórek przyporządkowuje się nazwy symboliczne. Określa się również typ zmiennych, który

(3)

3 decyduje o tym jak dużo miejsca zajmuje zmienna w pamięci oraz jakie operacje można na niej wykonywać. Będziemy korzystać ze zmiennych o długości 1 bajtu i 1 słowa (2 bajty).

nazwa DB wartość ; deklaracja zmiennej o długości 1B nazwa DW wartość ; deklaracja zmiennej o długości 2B

nazwa jest dowolnym ciągiem liter i cyfr zaczynającym się od litery, duże i małe litery nie są rozróżniane. Można zadeklarować zmienną bez podania nazwy lecz tracimy możliwość bezpośredniego odwołania się do zmiennej za pośrednictwem nazwy.

Wartość początkowa zmiennej może być określona w systemie binarnym, dziesiętnym, szesnastkowym, w postaci kodu ASCII. Można też nie podawać wartości początkowej (zmienne nie zainicjalizowana) pisząc znak ?.

Przykłady:

Zm1 DB 8 ; zapis dziesiętny

Zm2 DW 1234h, 0A5A5h ; zapis szesnastkowy Zm3 DB 01011100b ; zapis binarny

Zm4 DB ‘A’ ; kod ASCII

Zm5 DB ‘Witaj’, 0 ; ciąg znaków ASCII zakończony 0

Zm6 DW ? ; zmienna bez podanej wartości początkowej Zmienna typu WORD zajmuje dwa bajty. Stosowana jest zasada, że młodszy bajt zapisywany jest pod niższym adresem w pamięci. Poniższe dwie deklaracje są równoważne:

Zm DW 1234h Zm DB 34h, 12h

Wartość szesnastkowa rozpoczynająca się znakiem A..F musi być poprzedzona 0.

Można również oprócz pojedynczych zmiennych deklarować tablice. Tablicą nazywamy zmienną złożoną z określonej liczby elementów jednakowego typu. Dostęp do elementów tablicy uzyskujemy korzystając z indeksu elementu przechowywanego w rejestrze indeksowym. Jeśli wartości elementów tablicy się powtarzają możemy skorzystać z operatora DUP.

Przykłady:

Tab1 DB 1, 2, 3, 4, 5 ; tablica 5-elementowa zawiera liczby 1-5 Tab2 DB ‘Hello’ , 0 ; tablica zawiera napis zakończony 0 Tab3 DB 48h, 65h, 6Ch, 6Fh, 00h ; zapis równoważny Tab2

Tab4 DB 10 DUP (?) ; tablica 10-elementowa nie zainicjalizowana Tab5 DB 10 DUP (0) ; tablica 10-elementowa o wartościach 0 Tab6 DB 5 DUP (0,1) ; tablica 10-elementowa o wartościach 0,1,0,1 … Uwaga: DW nie może być używane przy deklaracji napisów.

Możemy dokonywać podglądu zmiennych podczas pracy symulatora otwierając okienko variables (przycisk vars).

(4)

4 Możliwy jest wybór typu zmiennej (byte, word, dword, qword, tword), ilości elementów zmiennej, sposobu interpretacji wyświetlanych danych (hex, bin, octal, signed, unsigned, ASCII). Dostępna jest również edycja zawartości pamięci danych podczas pracy symulatora.

Rodzaje instrukcji wykonywanych przez mikroprocesor Instrukcje transferu (przesłania danych)

Instrukcje obliczeniowe - arytmetyczne

- logiczne

- operacji na bitach - przesunięć i rotacji Instrukcje sterujące - skoki

- skoki warunkowe - pętle

- procedury

- operacje na rejestrach specjalnych

(5)

5

Instrukcje Arytmetyczne i Logiczne

Instrukcje arytmetyczne i logiczne działają na rejestr statusowy (rejestr znaczników –ang. Flags)

Rejestr ten ma 16 bitów, każdy nazywany jest znacznikiem (flag) i może przyjmować wartości 1 lub 0.

Znacznik przeniesienia - Carry Flag (CF) – ustawiany jest na 1 kiedy wystąpi przeniesienie dla liczb bez znaku, np. kiedy dla argumentów 8-bitowych dodamy 255 + 1. Gdy nie ma przeniesienia bit ten jest ustawiony na 0.

Znacznik zera - Zero Flag (ZF) – ustawiany na 1 kiedy wynik jest zero. Dla wartości różnej od zera bit ten ustawiany jest na 0.

Znacznik znaku - Sign Flag (SF) – ustawiany na 1 gdy wynik jest ujemny. Gdy wynik jest dodatni – ustawiany jest na 0. Znacznik ten przyjmuje wartość najbardziej znaczącego bitu wyniku.

Znacznik nadmiaru - Overflow Flag (OF) – ustawiany na 1 kiedy wystąpi przepełnienie dla liczb ze znakiem, np. kiedy dodamy 100 + 50 (wynik nie jest w przedziale -128...127).

Znacznik parzystości - Parity Flag (PF) – ustawiany jest na 1 kiedy wynik posiada parzystą liczbę jedynek, a na 0 kiedy liczba bitów o wartości jeden w wyniku jest nieparzysta. Uwaga:

analizowane jest tylko 8 bitów wyniku nawet gdy wynik jest 16-bitowy!

Znacznik przeniesienia pomocniczego - Auxiliary Flag (AF) – ustawiany na 1 kiedy wystąpi przeniesienie z bitu 3 na 4 (nibble-4 bity).

Znacznik zezwolenia na przerwania maskowalne - Interrupt enable Flag (IF) – kiedy ustawiony jest na 1 CPU przyjmuje przerwania od urządzeń zewnętrznych.

Znacznik kierunku - Direction Flag (DF) – znacznik ten wykorzystywany przez instrukcje przetwarzające łańcuchy znaków, kiedy znacznik ustawiony jest na 0 znaki przetwarzane są do przodu, kiedy ma wartość 1 – kierunek przetwarzania jest odwrotny.

Poznamy trzy grupy instrukcji arytmetycznych i logicznych.

Grupa pierwsza: ADD, SUB, CMP, AND, TEST, OR, XOR Wykorzystywane są następujące rodzaje argumentów:

(6)

6 REG, memory

memory, REG REG, REG

memory, immediate REG, immediate

REG:AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.

memory: [BX], [BX+SI+7], zmienna, itd...

immediate: 5, -24, 3Fh, 10001101b, itd...

Po wykonaniu operacji wynik przechowywany jest w pierwszym argumencie. Rozkazy CMP i TEST ustawiają tylko znaczniki nie zapisując wyniku operacji (wykorzystywane są do podejmowania decyzji podczas wykonywania program – skoki warunkowe i wywołanie podprogramów).

Instrukcje te działają tylko na następujące znaczniki: CF, ZF, SF, OF, PF, AF.

ADD – dodaje drugi operand do pierwszego.

SUB - odejmuje drugi operand od pierwszego.

CMP - odejmuje drugi operand do pierwszego lecz nie zapisuje wyniku odejmowania, ustawia tylko znaczniki.

AND – iloczyn logiczny pomiędzy parami bitów dwóch operandów. Stosowane są zależności:

1 AND 1 = 1 1 AND 0 = 0 0 AND 1 = 0 0 AND 0 = 0

Jak widzimy wynik jest równy 1 tylko wtedy, gdy oba bity są 1.

TEST – działa tak samo jak AND ale ustawia tylko znaczniki.

OR - suma logiczna pomiędzy parami bitów dwóch operandów. Stosowane są zależności:

1 OR 1 = 1 1 OR 0 = 1 0 OR 1 = 1 0 OR 0 = 0

Jak widzimy wynik jest równy 1 jeśli przynajmniej jeden bit argumentów jest równy 1.

XOR – Suma rozłączna (eXclusive OR) pomiędzy parami bitów dwóch operandów. Stosowane są zależności:

1 XOR 1 = 0 1 XOR 0 = 1 0 XOR 1 = 1 0 XOR 0 = 0

Jak widzimy wynik jest równy 1 kiedy bity argumentów różnią się.

(7)

7 Druga grupa: MUL, IMUL, DIV, IDIV

Wykorzystywane są następujące rodzaje argumentów:

REG memory

REG:AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.

memory: [BX], [BX+SI+7], zmienna, itd.

Instrukcje MUL i IMUL działają tylko na znaczniki: CF, OF

Kiedy wynik przekracza zakres operandów znaczniki ustawiane są na 1, w przeciwnym przypadku na 0.

Dla instrukcji DIV i IDIV znaczniki są niezdefiniowane.

MUL – mnożenie liczb bez znaku:

kiedy operand jest typu byte: AX = AL * operand.

kiedy operand jest typu word: (DX AX) = AX * operand.

IMUL – mnożenie liczb ze znakiem:

kiedy operand jest typu byte: AX = AL * operand.

kiedy operand jest typu word: (DX AX) = AX * operand.

DIV – dzielenie liczb bez znaku:

kiedy operand jest typu byte: AL = AX / operand

AH = reszta z dzielenia (moduł) kiedy operand jest typu word: AX = (DX AX) / operand

DX = reszta z dzielenia (moduł)

IDIV – dzielenie liczb ze znakiem:

kiedy operand jest typu byte: AL = AX / operand

AH = reszta z dzielenia (moduł).

kiedy operand jest typu word: AX = (DX AX) / operand

DX = reszta z dzielenia (moduł).

(8)

8 Trzecia grupa: INC, DEC, NOT, NEG

Wykorzystywane są następujące rodzaje argumentów:

REG memory

REG:AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.

memory: [BX], [BX+SI+7], zmienna, itd.

INC, DEC Instrukcje te działają tylko na następujące znaczniki:

ZF, SF, OF, PF, AF.

NOT Instrukcja nie zmienia żadnego znacznika!

NEG Instrukcje ta działa tylko na następujące znaczniki:

CF, ZF, SF, OF, PF, AF.

NOT – Neguje każdy bit operandu.

NEG – Zamienia liczbę na ujemną (w systemie U2). Zamienia każdy bit argumentu na przeciwny i dodaje do wyniku 1.

(9)

9

Sterowanie pracą programu

Umożliwia podejmowanie decyzji w oparciu o określone warunki.

Skoki bezwarunkowe

Skok bezwarunkowy polega na wpisaniu nowej wartości do licznika rozkazów po napotkaniu instrukcji skoku. Podstawową instrukcją umożliwiającą przeniesienie sterowania do innego punktu programu oznaczonego etykietą jest JMP o następującej składni:

JMP etykieta

Ażeby zadeklarować etykietę w programie podajemy jej nazwę, a po niej dwukropek ":". Oto przykłady prawidłowych nazw etykiet:

label1:

label2:

a:

Etykieta może być zadeklarowana w osobnej linii lub przed dowolną instrukcją, np.:

x1:

mov AX, 1

x2: mov AX, 2

Przykłady wykorzystania instrukcji JMP:

org 100h

mov ax, 5 mov bx, 2 jmp calc back: jmp stop calc:

add ax, bx jmp back stop:

ret

Instrukcja JMP pozwala przenieść sterowanie do przodu lub do tyłu, w dowolne miejsce wewnątrz segmentu.

(10)

10

Skoki warunkowe bliskie

Warunkiem wykonania skoku jest wartość wybranego znacznika. Wartość znaczników w rejestrze stanu jest ustalana w wyniku ostatniej operacji arytmetycznej lub logicznej (nie są zmieniane np.

podczas przesyłania danych). Pozwalają przenieść sterowanie przy spełnieniu określonych warunków.

Podzielone są na trzy grupy: pierwsza testuje pojedyncze znaczniki, druga testuje liczby ze znakiem, a trzecia – liczby bez znaku.

Instrukcje skoku warunkowego testujące pojedyncze znaczniki

Instrukcja Opis Warunek Instrukcja przeciwna

JZ , JE Jump if Zero (Equal). ZF = 1 JNZ, JNE

JC , JB, JNAE Jump if Carry (Below, Not Above Equal). CF = 1 JNC, JNB, JAE

JS Jump if Sign. SF = 1 JNS

JO Jump if Overflow. OF = 1 JNO

JPE, JP Jump if Parity Even. PF = 1 JPO

JNZ , JNE Jump if Not Zero (Not Equal). ZF = 0 JZ, JE

JNC , JNB, JAE Jump if Not Carry (Not Below, Above Equal). CF = 0 JC, JB, JNAE

JNS Jump if Not Sign. SF = 0 JS

JNO Jump if Not Overflow. OF = 0 JO

JPO, JNP Jump if Parity Odd (No Parity). PF = 0 JPE, JP

Można zauważyć, że niektóre instrukcje o różnych nazwach działają tak samo, są one kodowane za pomocą tych samych kodów maszynowych.

Instrukcje te są dwubajtowe – pierwszy bajt zawiera kod rozkazu, a drugi określa zakres skoku od - 128 do +127 bajtów).

(11)

11 Instrukcje skoku warunkowego dla liczb ze znakiem

Instrukcja Opis Warunek Instrukcja przeciwna

JE , JZ

Jump if Equal (=).

Jump if Zero. ZF = 1 JNE, JNZ

JNE , JNZ Jump if Not Equal (<>).

Jump if Not Zero. ZF = 0 JE, JZ

JG , JNLE Jump if Greater (>).

Jump if Not Less or Equal (not <=).

ZF = 0 and SF = OF

JNG, JLE

JL , JNGE Jump if Less (<).

Jump if Not Greater or Equal (not >=). SF <> OF JNL, JGE

JGE , JNL Jump if Greater or Equal (>=).

Jump if Not Less (not <). SF = OF JNGE, JL

JLE , JNG Jump if Less or Equal (<=).

Jump if Not Greater (not >).

ZF = 1 or SF <> OF

JNLE, JG

Instrukcje skoku warunkowego dla liczb bez znaku

Instrukcja Opis Warunek Instrukcja przeciwna

JE , JZ

Jump if Equal (=).

Jump if Zero. ZF = 1 JNE, JNZ

JNE , JNZ Jump if Not Equal (<>).

Jump if Not Zero. ZF = 0 JE, JZ

JA , JNBE Jump if Above (>).

Jump if Not Below or Equal (not <=).

CF = 0 and ZF = 0

JNA, JBE

JB , JNAE, JC

Jump if Below (<).

Jump if Not Above or Equal (not >=).

Jump if Carry.

CF = 1 JNB, JAE, JNC

(12)

12 JAE , JNB, JNC

Jump if Above or Equal (>=).

Jump if Not Below (not <).

Jump if Not Carry.

CF = 0 JNAE, JB

JBE , JNA Jump if Below or Equal (<=).

Jump if Not Above (not >).

CF = 1 or ZF = 1

JNBE, JA

Dla porównania wartości numerycznych używana jest instrukcja CMP która działa jak instrukcja SUB lecz nie zapisuje wyniku odejmowania tylko ustawia odpowiednio znaczniki.

Przykłady użycia instrukcji CMP i skoków warunkowych:

include "emu8086.inc"

org 100h

mov AL, 25 ; ustaw AL na 25.

mov BL, 10 ; ustaw BL na 10.

cmp AL, BL ; porównaj AL - BL.

je equal ; skocz jeśli AL = BL (ZF = 1).

putc 'n' ; program w tym miejscu jeśli AL <> BL, jmp stop ; wyświetla 'n' i skacze do stop.

equal: ; jeśli program osiągnie to miejsce

putc 'y' ; oznacza to, że AL = BL, więc wyświetlane jest 'y'.

stop:

ret ; koniec programu.

Instukcje pętli

Instrukcja Loop et jest przykładem instrukcji warunkowej, która zmniejsza zawartość rejestru CX o 1, sprawdza, czy zawartość tego rejestru jest różna od 0 i jeśli tak - wykonuje skok do miejsca oznaczonego etykietą et, w przeciwnym razie procesor przechodzi do następnej po loop instrukcji.

mov CX, 10 //ustawienie licznika powtórzeń pętli et:

ciąg instrukcji do wykonania w pętli loop et

(13)

13

Instrukcja Operacja i warunek skoku Instrukcja przeciwna

LOOP zmniejsz CX, skocz do etykiety jeśli CX nie równa się zero. DEC CX and JCXZ

LOOPE zmniejsz CX, skocz do etykiety jeśli CX nie równa się zero i (ZF = 1). LOOPNE

LOOPNE zmniejsz CX, skocz do etykiety jeśli CX nie równa się zero i (ZF = 0). LOOPE

LOOPNZ zmniejsz CX, skocz do etykiety jeśli CX nie równa się zero i ZF = 0. LOOPZ

LOOPZ zmniejsz CX, skocz do etykiety jeśli CX nie równa się zero i ZF = 1. LOOPNZ

JCXZ skocz do etykiety jeśli CX jest równe zero. OR CX, CX and JNZ

Instrukcje pętli wykorzystują rejestr CX do zliczania liczby powtórzeń. Jest to rejestr 16-bitowy, stąd liczba powtórzeń ograniczona jest do 65535. Można organizować pętle zagnieżdżone zapamiętując rejestr CX na stosie instrukcją push CX i odzyskując zawartość kiedy pętla lokalna się kończy za pomocą pop CX, np.:

org 100h

mov BX, 0 ; całkowity licznik przeskoków do etykiet.

mov CX, 5 k1: add BX, 1 mov AL, '1' mov AH, 0Eh int 10h push CX mov CX, 5 k2: add BX, 1 mov AL, '2' mov AH, 0Eh int 10h push CX mov CX, 5 k3: add BX, 1 mov AL, '3' mov AH, 0Eh int 10h

loop k3 ; pętla wewnętrzna.

pop CX

loop k2 ; pętla środkowa.

pop CX

loop k1 ; pętla zewnętrzna.

ret

(14)

14 BX zlicza całkowitą liczbę przeskoków do etykiet. Domyślnie symulator wyświetla zawartość rejestru w postaci szesnastkowej – klikając podwójnie w rejestr możemy wyświetlać zawartość rejestru w postaci rozszerzonej, w różnych systemach liczenia.

Po zakończeniu programu w rejestrze BX zapisana jest wartość 155 = 125 + 25 + 5 125 razy wykonała się pętla wewnętrzna, 25 razy środkowa i 5 razy zewnętrzna.

W przeciwieństwie do instrukcji JMP instrukcje skoków warunkowych i pętli pozwalają przenieść sterowanie o 127 bajtów do przodu i 128 bajtów do tyłu – skoki względne (pamiętajmy, że instrukcje w kodzie maszynowym mają długość od 1 do 6 bajtów)

Możemy łatwo obejść to ograniczenie w następujący sposób:

Bierzemy z tabeli przeciwny rozkaz skoku warunkowego i podajemy adres skoku do etykiety label_x.

Używamy instrukcji JMP do przeskoczenia do pożądanej lokalizacji.

Definiujemy etykietę label_x: zaraz za instrukcją JMP.

Etykieta label_x: musi być unikalna w całym programie.

Przykład:

include "emu8086.inc"

org 100h mov AL, 5 mov BL, 5

cmp AL, BL ; porównanie AL - BL.

; je equal ; rozkaz 2-bajtowy jne not_equal ; skok, jeśli AL <> BL (ZF = 0).

jmp equal ; skok w dowolne miejsce w segmencie not_equal:

add BL, AL sub AL, 10 xor AL, BL jmp skip_data

db 256 dup(0) ; 256 bytes skip_data:

putc 'n' ; jeśli AL <> BL,

jmp stop ; wyświetlamy 'n' i skok do etykiety stop.

equal: ; jeśli AL = BL putc 'y' ; wyświetlamy 'y'.

stop:

ret

Cytaty

Powiązane dokumenty

Zapis rozpoczyna się w sposób typowy dla bloku przedsionkowo­komorowego II stopnia typu I, po którym zamiast skrócenia widać wydłużenie odstępu PQ, czyli od razu

d) Bez niego czuję się odcięty/odcięta od świata. Czy rodzice lub znajomi skarżyli się kiedykolwiek, że poświęcasz im za mało czasu, bo zbytnio pochłania Cię komputer?. a)

Instrukcja Loop et jest przykładem instrukcji warunkowej, która zmniejsza zawartość rejestru CX o 1, sprawdza, czy zawartość tego rejestru jest różna od 0 i jeśli tak

1) Minory początkowe macierzy A wtedy i tylko wtedy wszystkie są dodatnie, gdy jest to prawdą dla K. Rzeczywista macierz symetryczna jest ujemnie określona wtedy i tylko.. wtedy,

czania” istoty ludzkiej... O osobiei która jest dzieckiem 221 Powiedzenie „Będziemy mieli dziecko” jest sądem mówiącym o osobie. Jesteśmy partnerem wobec osoby,

Jednak język programowania wysokiego poziomu nie jest jasny dla komputera, który rozumie jedynie ciągi zer i jedynek. Dlatego musimy posłużyć się aplikacją,

Podsumowując, należy bardzo sceptycznie ocenić szansę sukcesu budowy w Polsce sześciu reaktorów AP1000 lub EPR, a wątpliwość te po- tęguje fakt, że nikt, nigdzie nie kre-

W przypadku złożenia rezygnacji przez członka Rady Nadzorczej albo wygaśnięcia mandatu członka Rady Nadzorczej z innej przyczyny Zarząd niezwłocznie zwołuje