Sprawozdanie nr 2
Adrian Brociek
Paweł Zemsta
Grupa 21A
Symulacja działania 8051 - arytmetyka 16-to bitowa:
MUL (mnożenie), DIV(dzielenie).
Opis:
Akumulator - jest rejestrem roboczym, najbardziej uniwersalnym ponieważ może być
argumentem wielu rozkazów, w których użycie innego rejestru nie jest możliwe. Nie
powinien być on używany do przechowywania danych w dłuższych sekwencjach programu,
gdy prawdopodobnie będzie potrzebny do bieżących operacji w kolejnych rozkazach.
Rejestr B jest rejestrem pomocniczym, który ma specjalne zastosowanie w operacjach
mnożenia i dzielenia (nie może być w nich zastąpiony innym rejestrem). Adresowany jest on
bitowo.
DATA - dyrektywa DATA przydziela do specyfikowanej nazwy obszar wewnętrznej pamięci
RAM. Wyrażenie numeryczne musi być z zakresu 0 do 255. Symbol definiowany dyrektywą nie
może być powtórnie użyty w programie.
PROG SEGMENT CODE - Definiuje segment o nazwie PROG w klasie pamięci CODE, czyli
w pamięci programu. Wszystko co pojawi się w tym segmencie będzie umieszczone w jego
pamięci . Po zdefiniowaniu nazwy segmentu należy go wybrać, używając dyrektywy RSEG.
CSEG AT nr powoduje, że napisany niżej kod ma być umieszczony w pamięci programu
począwszy od podanego adresu nr .
RSEG nazwa - rozpoczyna segment zdefiniowany przy pomocy PROG SEGMENT CODE (w
przypadku naszego programu ma on nazwę PROG). Od tego momentu, znajdujący się
poniżej kod zostanie umieszczony w pamięci programu. Raz rozpoczęty segment jest
ważny do czasu rozpoczęcia nowego.
JMP nazwa powoduje przemieszczenie się (skok) do miejsca oznaczonego jako nazwa .
MUL AB służy do mnożenia. Ma zawsze te same ustalone argumenty akumulator A oraz
rejestr B. Wynik mnożenia jest wartością 16-bitową B|A (młodszy bajt w A).
DIV AB służy do dzielenia. Podobnie jak rozkaz mnożenia ma ustalone takie same argumenty -
akumulator A oraz rejestr B. Wynik
ADD A,dana dodaje wartość z komórki o adresie zastąpionym tekstem dana do
Akumulatora, bez przeniesienia.
ADDC A,dana dodaje wartość z komórki o adresie zastąpionym tekstem dana do
Akumulatora, z uwzględnieniem przeniesienia.
MOV gdzie,skąd kopiuje wartość z komórki o adresie zastąpionym tekstem skąd do komórki
o adresie zastąpionym tekstem gdzie .
SUBB A,dana - odjęcie od wartości zapisanej w Akumulatorze wartość komórki pamięci dana
Jeżeli dana>A to nastąpi pożyczka 1 z zewnątrz, co zostanie zasygnalizowane zmianą flagi cy
na 1 . Jeżeli flaga cy była ustawiona na 1 , to odejmowana jest także pożyczka wykonana
przez poprzednie wywołanie odejmowania (jeżeli takowe nastąpiło).
CLR C wyzerowanie przeniesienia (będzie to najmłodszy bit wyniku.
DJNZ B,gdzie dekrementacja rejestru B i przejście do etykiety gdzie , jeśli po dekrementacji
wartość będzie niezerowa.
CPL C - odwrócenie przeniesienia.
END - dyrektywa musi być umieszczona w ostatniej linii programu zródłowego, jest warunkiem
zakończenia programu.
Mnożenie dwóch liczb 16-bitowych:
Rozkaz mnożenia, którego pierwszym argumentem jest zawsze akumulator, a drugim rejestr B
zapisujemy w postaci:
MUL AB
Mnożenie 16-bitowe dwóch wartości 16-bitowych daję w wyniku wartość 32-bitową.
Dla przykładu rozważmy mnożenie liczby 28872 x 13538 co da wynik 390869136. Ponieważ
podczas wykonywania tej operacji, będziemy korzystać zarówno z dodawania jak i odejmowania,
najpierw przekształćmy wyrażenie na system szesnastkowy: 70C8h x 34E2h.
Bajt 4 Bajt 3 Bajt 2 Bajt 1
70 C8
* 34 E2
= B0 90
62 E0
28 A0
+ 16 C0
= 17 4C 30 90
Powyższa siatka posłuży nam do zrozumienia tego procesu. Niebieski obszar reprezentuje
oryginalne dwie wartości 16-bitowe. Zielony obszar zawiera pośrednie obliczenia pobrane
poprzez mnożenie każdych bajtów wartości pierwotnych. Z kolei szary fragment siatki wskazuje
na naszą ostateczną odpowiedz, otrzymaną poprzez zsumowanie kolumn w zielonym obszarze, z
uwzględnieniem przeniesienia.
Najpierw mnożymy C8h przez E2h (1 bajty z obu liczb), a wynik umieszczamy bezpośrednio
poniżej. Następnie mnożymy 70h przez E2h (2 bajt z górnej liczby i 1 bajt dolnej liczby). Ten
wynik umieszczamy w taki sposób, aby kończył się w kolumnie z 2 bajtem. Następnie trzeba
pomnożyć C8h przez 34h (1 bajt górnej liczby i 2 bajt dolnej liczby), ponownie zapisując wynik
jak podczas ostatniego mnożenia. Wreszcie, mnożymy 70h przez 34h (2 bajty z obu liczb) i
umieszczamy odpowiedz w taki sposób, aby kończyła się w kolumnie z 3 bajtem.
Proces wykonywany w asemblerze będzie identyczny.
Bajt 4 Bajt 3 Bajt 2 Bajt 1
R6 R7
* R4 R5
= R0 R1 R2 R3
Nasza pierwsza liczba zostanie zawarta w R6 oraz R7, natomiast druga w R4 i R5. Wynik
mnożenia trafi do R0,R1,R2 i R3. Każdy z rejestrów przechowuje 8-bitów, tak więc cztery
rejestry pozwolą na otrzymanie 32-bitowego wyniku. Nasz program będzie się składał z czterech
następujących kroków:
I. Mnożenie przez R5 R7, pozostawienie 16-bitowego wyniku w R2 i R3.
II. Mnożenie przez R5 R6, dodanie 16-bitowego wyniku do R1 i R2.
III. Mnożenie przez R4 R7, dodanie 16-bitowego wyniku do R1 i R2.
IV. Mnożenie przez R4 R6, dodanie 16-biotwego wyniku do R0 i R1.
Kod programu:
PROG SEGMENT CODE ;definiuje segment nazwie PROG w klasie pamięci CODE
DanaL DATA 20h ;przechowuje młodszy bajt wprowadzanej liczby
DanaH DATA 21h ;przechowuje starszy bajt wprowadzanej liczby
Dana2L DATA 22h ;przechowuje młodszy bajt wprowadzanej drugiej liczby
Dana2H DATA 23h ;przechowuje starszy bajt wprowadzanej drugiej liczby
Wynik_bajt1 DATA 33h ;przechowuje pierwszy bajt wyniku
Wynik_bajt2 DATA 32h ;przechowuje drugi bajt wyniku
Wynik_bajt3 DATA 31h ;przechowuje trzeci bajt wyniku
Wynik_bajt4 DATA 30h ;przechowuje czwarty bajt wyniku
CSEG AT 0 ;kod programu będzie umieszczony w jego pamięci począwszy od adresu 0
JMP mul16_16 ;skok do miejsca oznaczonego etykietą mul16_16
RSEG PROG ;rozpoczyna segment, od którego, znajdujący się poniżej kod zostanie
umieszczony w pamięci programu
;W oknie pamięci Memory 1 zapisujemy nasze dane. Do komórki o adresie D:0x20 wpisujemy
młodszy bajt pierwszej liczby, a tuż obok pod adres D:0x21 starszy bajt danej liczby. Kolejną
liczbę zapisujemy pod adresem D:0x22 młodszy bajt i D:0x23 starszy bajt.
mul16_16:
;Mnożenie R5 przez R7
MOV A,Dana2L ;skopiowanie wartości z komórki o adresie zastąpionym tekstem Dana2L do
akumulatora A. W zakładce Sys widzimy właśnie tę zmianę wartość a=0xe2.
MOV B,DanaL ;skopiowanie wartości z komórki o adresie zastąpionym tekstem DanaL do
rejestru B. Zmiana widoczna w zakładce Sys b=0xc8
MUL AB ;mnożenie wartości z akumulatora przez wartość z rejestru B. W rejestrze B zostanie
zapisany starszy bajt wyniku b=0xb0, zaś w akumulatorze młodszy bajt a=0x90
MOV Wynik_bajt2,B ;skopiowanie wartości z rejestru B do komórki o adresie zastąpionym
tekstem Wynik2. Komórka o adresie 0x32h przyjęła wartość B0.
MOV Wynik_bajt1,A ;skopiowanie wartości z akumulatora A do komórki o adresie zastąpionym
tekstem Wynik1. Komórka o adresie 0x33h przyjęła wartość 90.
;Mnożenie R5 przez R6
MOV A,Dana2L ;skopiowanie wartości z komórki o adresie zastąpionym tekstem Dana2L do
akumulatora A. W zakładce Sys widzimy właśnie tę zmianę wartość a=0xe2.
MOV B,DanaH ;skopiowanie wartości z komórki o adresie zastąpionym tekstem DanaH do
rejestru B. Zmiana widoczna w zakładce Sys b=0x70.
MUL AB ;mnożenie wartości z akumulatora przez wartość z rejestru B. W rejestrze B zostanie
zapisany starszy bajt wyniku b=0x62, zaś w akumulatorze młodszy bajt a=0xe0.
ADD A,Wynik_bajt2 ;dodanie do akumulatora A wartości z komórki o adresie zastąpionym
tekstem Wynik_bajt2. E0+B0=190 w akumulatorze pozostanie młodszy bajt wyniku, czyli
wartość 90. Zaś nasza 1 spowoduje ustawienie wartości 1 na fladze cy.
MOV Wynik_bajt2,A ;skopiowanie wartości z akumulatora A do komórki o adresie
zastąpionym tekstem Wynik_bajt2. Komórka o adresie 0x32h przyjmie wartość 90.
MOV A,B ;skopiowanie wartości z rejestru b do akumulatora. Zarówno akumulator jak i rejestr
b przyjmą wartość 0x62.
ADDC A,#00h ;dodanie do akumulatora A wartości 0, z dodaniem wartości flagi cy, czyli 1
b=0x63. Po dodaniu nastąpi wyzerowanie flagi cy.
MOV Wynik_bajt3,A ;skopiowanie wartości z akumulatora A do komórki o adresie zastąpionym
tekstem Wynik_bajt3. Komórka o adresie 0x31h przyjmie wartość 63.
MOV A,#00h ;załadowanie do akumulatora wartości 0x00.
ADDC A,#00h ;dodanie do akumulatora A wartości 0, z dodaniem wartości flagi cy. Flaga cy
jednak była pusta miała wartość 0, więc wartość akumulatora nie uległa zmianie.
MOV Wynik_bajt4,A ;skopiowanie wartości z akumulatora A do komórki o adresie
zastąpionym tekstem Wynik_bajt4. Komórka o adresie 0x30h przyjmie wartość 00.
;Mnożenie R4 przez R7
MOV A,Dana2H ;skopiowanie wartości z komórki o adresie zastąpionym tekstem Dana2H do
akumulatora A. W zakładce Sys widzimy właśnie tę zmianę wartość a=0x34.
MOV B,DanaL ;skopiowanie wartości z komórki o adresie zastąpionym tekstem DanaL do
rejestru B. Zmiana widoczna w zakładce Sys b=0xc8.
MUL AB ;mnożenie wartości z akumulatora przez wartość z rejestru B. W rejestrze B zostanie
zapisany starszy bajt wyniku b=0x28, zaś w akumulatorze młodszy bajt a=0xa0.
ADD A,Wynik_bajt2 ;dodanie do akumulatora A wartości z komórki o adresie zastąpionym
tekstem Wynik_bajt2. A0+90=130 w akumulatorze pozostanie młodszy bajt wyniku, czyli
wartość 30. Zaś nasza 1 spowoduje ustawienie wartości 1 na fladze cy.
MOV Wynik_bajt2,A ;skopiowanie wartości z akumulatora A do komórki o adresie zastąpionym
tekstem Wynik_bajt2. Komórka o adresie 0x32h przyjmie wartość 30.
MOV A,B ;skopiowanie wartości z rejestru b do akumulatora. Zarówno akumulator jak i rejestr
b przyjmą wartość 0x28.
ADDC A,Wynik_bajt3 ;dodanie do akumulatora wartości z komórki 0x31, z dodaniem wartości
flagi cy. 28+63+1=8C. Po dodaniu nastąpi wyzerowanie flagi cy.
MOV Wynik_bajt3,A ;skopiowanie wartości z akumulatora A do komórki o adresie zastąpionym
tekstem Wynik_bajt3. Komórka o adresie 0x31h przyjmie wartość 8C.
MOV A,#00h ;załadowanie do akumulatora wartości 0x00.
ADDC A,Wynik_bajt4 ;dodanie do akumulatora wartości z komórki 0x30, z dodaniem wartości
flagi cy. Każda z komórek miała jednak wartość 0, więc wartość akumulatora nie ulegnie
zmianie.
MOV Wynik_bajt4,A ; skopiowanie wartości z akumulatora A do komórki o adresie
zastąpionym tekstem Wynik_bajt4. Komórka o adresie 0x30h przyjmie wartość 00.
;Mnożenie R4 przez R6
MOV A,Dana2H ;skopiowanie wartości z komórki o adresie zastąpionym tekstem Dana2H do
akumulatora A. W zakładce Sys widzimy właśnie tę zmianę wartość a=0x34.
MOV B,DanaH ;skopiowanie wartości z komórki o adresie zastąpionym tekstem DanaH do
rejestru B. Zmiana widoczna w zakładce Sys b=0x70.
MUL AB ;mnożenie wartości z akumulatora przez wartość z rejestru B. W rejestrze B zostanie
zapisany starszy bajt wyniku b=0x16, zaś w akumulatorze młodszy bajt a=0xc0.
ADD A,Wynik_bajt3 ;dodanie do akumulatora A wartości z komórki o adresie zastąpionym
tekstem Wynik_bajt2. C0+8C=14C w akumulatorze pozostanie młodszy bajt wyniku, czyli
wartość 4C. Zaś nasza 1 spowoduje ustawienie wartości 1 na fladze cy.
MOV Wynik_bajt3,A ; skopiowanie wartości z akumulatora A do komórki o adresie
zastąpionym tekstem Wynik_bajt3. Komórka o adresie 0x31h przyjmie wartość 4C.
MOV A,B ;skopiowanie wartości z rejestru b do akumulatora. Zarówno akumulator jak i rejestr
b przyjmą wartość 0x16.
ADDC A,Wynik_bajt4 ;dodanie do akumulatora wartości z komórki 0x30, z dodaniem wartości
flagi cy. 16+0+1=17. Po dodaniu nastąpi wyzerowanie flagi cy.
MOV Wynik_bajt4,A ; skopiowanie wartości z akumulatora A do komórki o adresie
zastąpionym tekstem Wynik_bajt4. Komórka o adresie 0x30h przyjmie wartość 17.
END ;zakończenie wykonywania programu
Po wykonaniu programu do końca, w komórkach o adresach od D:0x30 do D:0x33 zawarty
zostanie ostateczny wynik z mnożenia.
Dzielenie dwóch liczb 16-bitowych:
Rozkaz dzielenia DIV AB (argumentami zawsze akumulator i rejestr B). 16-biotwe dzielenie to
dzielenie 16-biotwej wartości przez inną 16-bitową wartość. Zwraca 16-bitowy iloraz oraz 16-
bitową resztę.
Jednak w programie poniżej odejmowanie wykonamy z wykorzystaniem rozkazów dodawania i
odejmowania.
Dzielenie 16-bitowe dwóch wartości 16-bitowych daję w wyniku wartość 16-bitową.
Dla przykładu rozważmy dzielenie liczby 28872 / 13538 co da nam wynik 2. Ponieważ podczas
wykonywania tej operacji, będziemy korzystać zarówno z dodawania jak i odejmowania,
najpierw przekształćmy wyrażenie na system szesnastkowy: 70C8h / 34E2h.
W oknie pamięci Memory 1 zapisujemy nasze dane. Do komórki o adresie D:0x20 wpisujemy
młodszy bajt pierwszej liczby, a tuż obok pod adres D:0x21 starszy bajt danej liczby. Kolejną
liczbę zapisujemy pod adresem D:0x22 młodszy bajt i D:0x23 starszy bajt.
Kod programu:
PROG SEGMENT CODE ;definiuje segment nazwie PROG w klasie pamięci CODE
DanaL DATA 20h ;przechowuje młodszy bajt wprowadzanej liczby
DanaH DATA 21h ;przechowuje starszy bajt wprowadzanej liczby
Dana2L DATA 22h ;przechowuje młodszy bajt wprowadzanej drugiej liczby
Dana2H DATA 23h ;przechowuje starszy bajt wprowadzanej drugiej liczby
WynikL DATA 30h ;przechowuje młodszy bajt wyniku
WynikH DATA 31h ;przechowuje starszy bajt wyniku
CSEG AT 0 ;kod programu będzie umieszczony w jego pamięci począwszy od adresu 0
JMP div16_16 ;skok do miejsca oznaczonego etykietą div16_16
RSEG PROG ;rozpoczyna segment, od którego, znajdujący się poniżej kod zostanie umieszczony
w pamięci programu
div16_16:
CLR C ;wyczyszczenie początkowego przeniesienia.
MOV WynikL,#00h ;wyczyszczenie komórki o adresie 0x30h (wyzerowanie).
MOV WynikH,#00h ;wyczyszczenie komórki o adresie 0x31h (wyzerowanie).
MOV B,#00h ;wyczyszczenie rejestru pomocniczego B. Będziemy w nim przechowywać ilość
przesuniętych w lewo bitów.
div1:
INC B ;Zwiększenie licznika dla każdego przesunięcia w lewo (b=0x01h).
MOV A,Dana2L ;przesunięcie aktualnego dzielnika (młodszy bajt) z komórki o adresie
zastąpionym tekstem Dana2L do akumulatora A. W zakładce Sys widzimy właśnie tę zmianę
wartość a=0xe2.
RLC A ;przesunięcie młodszego bajtu w lewo. Pod wartość akumulatora A wpisujemy wartość A *
2, w naszym przykładzie przyjmie wartość 0xc4. 9bit wyniku zostanie wpisany do flagi cy.
MOV Dana2L,A ;zapisanie nowo uzyskanego dzielnika w komórce o adresie zastąpionym tekstem
Dana2L (młodszy bajt).
MOV A,Dana2H ;przesunięcie aktualnego dzielnika (starszy bajt) z komórki o adresie
zastąpionym tekstem Dana2H do akumulatora A. W zakładce Sys widzimy właśnie tę zmianę
wartość a=0x34.
RLC A ; przesunięcie starszego bajtu w lewo. Pod wartość akumulatora A wpisujemy wartość A
* 2, w naszym przykładzie przyjmie wartość 0x68. Do uzyskanego wyniku zostanie dodana wartość z
flagi cy, co spowoduje zmianę wartości akumulatora na 0x69. Flaga cy zostanie wyzerowana.
MOV Dana2H,A ;zapisanie nowo uzyskanego dzielnika w komórce o adresie zastąpionym tekstem
Dana2H (starszy bajt).
JNC div1 ; Powtarzamy segment od etykiety div1, do momentu aż wskaznik przeniesienia zostanie
ustawiony od starszego bajtu.
;po zakończeniu wykonywania div1, wartość komórki 0x22 przyjmie wartość 10, a do komórki o
adresie 0x23 zostanie przypisana wartość A7.
;przesunięcie dzielnika w prawo
div2:
MOV A,Dana2H ;przesunięcie dzielnika (starszy bajt) z komórki o adresie zastąpionym tekstem
Dana2H do akumulatora A. W zakładce Sys widzimy właśnie tę zmianę wartość a=0xa7.
RRC A ;przesunięcie starszego bajtu w prawo. Pod wartość akumulatora A wpisujemy wartość A /
2, w naszym przykładzie przyjmie wartość 0xd3. Reszta wyniku zostanie zapisana do flagi cy.
MOV Dana2H,A ;zapisanie nowo uzyskanego dzielnika w komórce o adresie zastąpionym tekstem
Dana2H (starszy bajt).
MOV A,Dana2L ;przesunięcie dzielnika (młodszy bajt) z komórki o adresie zastąpionym tekstem
Dana2L do akumulatora A. W zakładce Sys widzimy właśnie tę zmianę wartość a=0x10.
RRC A ;przesunięcie starszego bajtu w prawo. Pod wartość akumulatora A wpisujemy wartość
A / 2, w naszym przykładzie przyjmie wartość 0x88, z uwzględnieniem przeniesienia ze starszego
bitu. Wartość flagi cy zostanie wyzerowana.
MOV Dana2L,A ;zapisanie nowo uzyskanego dzielnika w komórce o adresie zastąpionym tekstem
Dana2L (młodszy bajt).
CLR C ;wyczyszczenie przeniesienia. Flaga cy przyjmie wartość 0.
MOV 07h,DanaH ;stworzenie zapasowej kopii dywidendy starszego bajtu w komórce o adresie
0x07h.
MOV 06h,DanaL ;stworzenie zapasowej kopii dywidendy młodszego bajtu w komórce o adresie
0x06h.
MOV A,DanaL ;przesunięcie dzielnika (młodszy bajt) z komórki o adresie zastąpionym tekstem
Dana2L do akumulatora A. W zakładce Sys widzimy właśnie tę zmianę wartość a=0x88.
SUBB A,Dana2L ;Odjęcie młodszego bajtu od akumulatora A.
MOV DanaL,A ;zapisanie nowo uzyskanego dzielnika w komórce o adresie zastąpionym tekstem
DanaL (młodszy bajt).
MOV A,DanaH ;przesunięcie dzielnika (starszy bajt) z komórki o adresie zastąpionym tekstem
Dana2L do akumulatora A. W zakładce Sys widzimy właśnie tę zmianę wartość a=0x40.
SUBB A,Dana2H ;odjęcie starszego bajtu od akumulatora A.
MOV DanaH,A ;zapisanie nowo utworzonego starszego bajtu w miejsce dzielnika starszego bajtu.
JNC div3 ; Powtarzamy segment od etykiety div1, do momentu aż wskaznik przeniesienia zostanie
ustawiony od starszego bajtu. Jeżeli flaga przeniesienia cy nie jest ustawiona, to wynikiem będzie 1.
MOV DanaH,07h ;W przeciwnym razie, gdy wyniki przyjmie wartość 0, musimy zapisać kopię
dzielnika, aby cofnąć odejmowanie.
MOV DanaL,06h
;Podczas wykonywania programu wykonywanie rozkazu DJNZ B,div2 spowoduje wywołanie
dodatkowo dwóch etykiet div2.
div3:
CPL C ;odwrócenie przeniesienia.
MOV A,WynikL ;skopiowanie wartości z komórki o adresie zastąpionym tekstem WynikL do
akumulatora A.
RLC A ;przesunięcie przeniesienia flagi cy do tymczasowego wyniku.
MOV WynikL,A ; skopiowanie wartości z akumulatora A do komórki o adresie zastąpionym
tekstem WynikL.
MOV A,WynikH ;skopiowanie wartości z komórki o adresie zastąpionym tekstem WynikH do
akumulatora A.
RLC A ;przesunięcie przeniesienia flagi cy do tymczasowego wyniku.
MOV WynikH,A ; skopiowanie wartości z akumulatora A do komórki o adresie zastąpionym
tekstem WynikH.
DJNZ B,div2 ;dekrementacja rejestru pomocniczego B i przejście do etykiety div2, jeśli wartość
rejestru B po dekrementacji nie będzie zerowa.
MOV Dana2H,05h ;przeniesienie wyniku do komórki o adresie zastąpionym tekstem Dana2H.
MOV Dana2L,04h ;przeniesienie wyniku do komórki o adresie zastąpionym tekstem Dana2L.
END ;zakończenie wykonywania programu
Po wykonaniu programu do końca, w komórce o adresie D:0x30 zawarty jest ostateczny wynik z
dzielenia.
Podczas pisania sprawozdania korzystałem z następujących pomocy:
http://www.8052.com/mul16
http://www.8052.com/div16
http://staff.iiar.pwr.wroc.pl/antoni.sterna/lab_51/programowanie_51.pdf
Wyszukiwarka
Podobne podstrony:
Sprawozdanie03 Brociek ZemstaSprawozdanie05 Brociek ZemstaPoprawa sprawozdanie01 Brociek Zemstasprawozdanie felixa2Sprawozdanie Konduktometriazmiany w sprawozdaniach finzemstaErrata do sprawozdania2009 03 BP KGP Niebieska karta sprawozdanie za 2008rid&657Sprawozdanie nr 3 inzSprawozdanie FundacjaBioEdu2007Sprawozdanie Ćw 2czechow zemstawięcej podobnych podstron