Zaloguj się, aby obserwować  
UthersonL

Programowanie - pytania, problemy, przykłady programów

1812 postów w tym temacie

Dnia 27.02.2009 o 21:32, Jan Czarny napisał:

Właśnie zastanawia mnie czemu mówi się , że napisane w asemblerze programy chodzą najwydajniej
, a i tak się pisze aplikacje w innych językach programowania ?

Bo samo w takowym programowanie trwa dłużej i jest już dość leciwy (dodatkowo działa tylko na x86, nie da się go przenieść na inną architekturę), generalnie można go zdaje się łączyć z kodem w C, ale ten też do współczesnych języków się nie zalicza. Dlatego też korzysta się z języków wysokopoziomowych C# czy Javy, co prawda programy dłużej liczą/bardziej obciążają kompa ale za to dużo szybciej powstają. Zaś stosować się asemblera nadal stosuje, np w sterownikach, ze względu na konieczność niskopoziomowej komunikacji z sprzętem).

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 27.02.2009 o 21:32, Jan Czarny napisał:

Zacząłem od C++ , bo jeśli znam C++ to znam /php/ C# i inne języki pochodne

Słusznie. Tyle, że te języki wywodzą się tak naprawdę od C - i to jego składnia to 95% C++, 90% Javy i ponad 80% pozostałych opartych na składni tego pierwszego.
C++ dodał do C tylko słowa kluczowe głównie związane z obiektami: operator, class, public, protected, private.

Dnia 27.02.2009 o 21:32, Jan Czarny napisał:

Właśnie zastanawia mnie czemu mówi się , że napisane w asemblerze programy chodzą
najwydajniej, a i tak się pisze aplikacje w innych językach programowania ?

Dam Ci wyjaśnienie na przykładzie, który sam kiedyś robiłem. Potrzebny mi był wybór systemu operacyjnego uruchamianego przy starcie komputera, tak aby ani nie trzeba było tworzyć dodatkowej ukrytej partycji. Żeby to wykonać musiałem zrobić menu wybierające start z jednej z 4 partycji w samym sektorze rozruchowym z którego na cel uruchamiania można przeznaczyć było tylko 384 bajty. Z tego sam kod ładujący boot sektor partycji musiał zajmować ok. 150 bajtów. Zostało więc na interaktywne menu ok. 200 bajtów.
Nie można było skorzystać z żadnych funkcji standardowych C ponieważ one korzystają w najprymitywniejszej wersji korzystają z funkcji DOS, którego w tym momencie jeszcze nie ma lub nigdy nie ma (uruchamiajac np. Linuxa). Trzeba więc było stworzyć własne procedury drukujące tekst na ekranie korzystające z procedur samego BIOSa.
Tak więc w tym wypadku assembler był jedynym możliwym rozwiązaniem. Kiedy zrobiłem procedury i samą pętlę interakcji z klawiaturą i ekranem, to okazało się, że brakuje kilkunastu bajtów. Musiałem więc rozwinąć wszelkie procedury do postaci liniowej, żeby zlikwidować wywołania procedury uruchamianych tylko z jednego miejsca kodu.

Kod jest długi, bardzo trudny w zrozumieniu i bawiłem się w jego robienie i poprawianie dobre 2-3 tygodnie. Mozna użyć tylko tylu zmiennych ile się zmieści w kodzie, albo w kilku rejestrach procesora. Nie można było skorzystać z debuggera ponieważ nie da się uruchomić debuggera kiedy w kompie nie ma niemal nic. Wszelkich błędów trzeba było się domyślać i własną głową zastępować debugger.
To samo co poniżej zapisane w języku C zajmuje 5 linijek i pisze się to w dosłownie 2-3 minuty. Ale za to za żadne Chiny nie da się zapisać tak małego i zwartego kodu w języku C lub jakimkolwiek innym kompilowanym (tłumaczonym na assembler).

;Interaktywny Master Boot Record 1.1
;Autor: (c)Copyright Olamagato, 1998

;Po wczytaniu przez BIOS głównego sektora rozruchowego do pamięci
;program kopiuje się spod adresu sector do mvsector, aby nie
;przeszkadzać w następnych operacjach dyskowych.
;
;Po tym rysuje w górnej części ekranu menu utworzone z istniejących w
;tablicy partycji pozycji. Jest przy tym kasowana ewentualna aktywność
;jednej ze stref. Tekst dla poszczególnych pozycji jest brany z
;obszaru danych IMBR (który jest wypełniany przez program instalujący
;XFDISK).
;
;Następnie oczekuje na wybranie przez użytkownika z klawiatury jednej
;z pozycji oraz wciśnięcie Enter. Wybrana strefa jest ustawiana jako
;aktywna. Następnie program zapisuje (bez sprawdzania poprawności)
;zawartość zmodyfikowanego głównego sektora rozruchowego i wczytuje
;odpowiedni sektor rozruchowy uruchamianej strefy.

;Ta wersja IMBR pozwala na uruchamianie kilku wersji tego samego systemu
;operacyjnego (na pewno Microsoftu), jednak jest obciążona wadą zapisu MBR
;podczas startu.
;Uwaga. Program powoduje alarm BIOS o zapisie głównego sektora rozruchowego.
;Należy tę opcję wyłączyć lub pozwalać na zapis.

.286

descsize equ 24 ;rozmiar opisu strefy w bajtach (w tym '\0')
sector    equ 7c00h ;położenie wczytywanych sektorów
mvsector equ 0600h ;położenie przesuniętego kodu
ptable    equ 01beh ;ofset położenia tabl. stref w sekto-rze
flagptable equ 01feh ;offset znacznika tablicy partycji
bootflag equ 0aa55h

;kolejne pola opisu stref
ptactive equ 0 ;aktywność partycji: 0 - nie, 80h - tak
pth    equ 1 ;nr głowicy
ptcs    equ 2 ;numer cylindra i sektora
pttype    equ 4 ;typ partycji

bioschar equ 10h ;numery obsługi serwisów BIOS
biosdsk    equ 13h
bioskey    equ 16h

setmode    equ 0 ;funkcje obsługi ekranu znakowego BIOS
setcursor equ 1
setcurpos equ 2
rdcur    equ 3
rdcharx    equ 8
setcharx equ 9
setchar    equ 0ah
setchartty equ 0eh
rdvideo    equ 0fh

readkey    equ 10h ;jw. ale klawiatury
kbhit    equ 11h
up    equ 72 ;kody klawiszy
down    equ 80

vheight    equ 25 ;domyślne parametry ekranu
vwidth    equ 80
hidcur    equ 0ffffh

cr    equ 13 ;kody znaków
lf    equ 10

csegment segment
    assume cs:csegment, ds:csegment

;używa: ax,cx,si,di,sp,ds,es,ss
movestart: ;przenosi kod od start do końca pod adres mvsector '0
    cld
    xor ax,ax ;ax = 0
    mov ss,ax ;segment stosu = 0h
    mov sp,sector ;stos poniżej wczytanego sektora
    push ax ;rejestry segmentowe ustawiane na 0000h '1
    pop es ;'0
    push ax ;'1
    pop ds ;'0
    sti    ;pozwolenie na przerywanie
    mov si,sector
    mov di,mvsector
    push si ;zdjęcie najpierw mvsector, potem sector '2
    push di ;stos: zapis do późniejszego wykorzystania '1
    mov cx,endsector - movestart
    rep movsb ;kopiowanie obszaru od movestart do endboot
        ;pod adres mvsector
    jmp (start - sector + mvsector) ;skok do przesun. kodu
;=============================================================================
;używa: ax,bx,cx
start:    mov ah,rdvideo
    int bioschar ;al - tryb, ah - szer., bh - strona
    mov bl,ah    ;bl - szer.
    mov ah,rdcur
    int bioschar
    push cx    ;stos: zapisany typ kur-sora '3
hidecursor: mov cx,hidcur ;usunięcie kursora
    mov ah,setcursor
    int bioschar
    xor dx,dx    ;dh = dl = 0
    mov ah,setcurpos ;ustawienie kursora w lg rogu ekranu
    int bioschar
cls:    mov al,' '
    mov bl,17h
    mov cx,vwidth*(vheight+1)
    mov ah,setcharx
    int bioschar

;używa: +ax,+bx,cx,dx,si,di
info:    mov si,offset infotext + mvsector
    call print ;wydrukowanie winietki programu
    mov ah,rdcur
    int bioschar

;=============================================================================
menucur: push dx ;stos: zapisana pozycja kursora menu '4

;drukuje wszystkie 4 pozycje tekstów opisów stref w kolejnych wierszach
;używa: +ax,+bx,cx,dl,si
    mov cl,4
    mov di,offset ptinfo + mvsector
    mov bp,offset tablica + mvsector
ptshow:
    xor al,al
    mov [bp],al ;zerowanie znacznika aktywności wszystkich stref
    cmp [bp+pttype],al
    je shownext ;nie wyświetlać gdy typ == 0
    mov si,di
    call print ;ax,bx,si
shownext: mov si,offset crlf + mvsector
    call print
    add di,descsize
    add bp,16
    dec cl
    jnz ptshow

;ustawienie jednorazowych warunków początkowych    
menu:    ;cl = 0, bieżąca pozycja menu; ch - nowa pozycja menu
    mov ch,cl ;
    mov di,cx ;di - znacznik wyświetlania lub kasowania
    inc di ;di = 1

;Rysuje zaznaczenie pozycji menu lub usuwa je
;używa: ax,bx,dx,si
showitem: mov cl,ch
menuitem: and ch,3 ;obcięcie nowej poz. menu do 0..3
    pop dx ;ściągnięcie poz. kursora dla menu '3
    push dx ;i wstaw. dla kolejnego przebiegu '4
    add dh,cl ;dodaje nr pozycji do kursora pocz. menu
    mov ah,setcurpos
    int bioschar ;bh,dx
    mov si,descsize - 1

;Robi inwersję n znaków w wieszu od pozycji kursora
;si - ilość znaków do odwrócenia (>0), ustawiony kursor
;używa: ax,bl,bh (= 0),dx,si
invs:    ;odwraca n znaków od bieżącej pozycji kursora
    push cx ;przechowanie pozycji menu '5
invnext: mov ah,rdcur ;odczyt pozycji kursora
    int bioschar
    inc dl    ;przesunięcie kursora na prawo
    mov ah,rdcharx ;odczyt znaku i atrybutu
    int bioschar ;al - znak, ah - atrybut
    mov bl,ah
    and ah,88h ;pozostawienie bitów bright i flash
    rol bl,4 ;zamiana połówek bajtu
    and bl,77h ;usunięcie najstarszych bitów połówek
    or bl,ah ;ah - odwrócony atrybut znaku
    mov cx,1
    mov ah,setcharx ;zapis znaku i zmodyf. atrybutu
    int bioschar
    mov ah,setcurpos ;zapis nowej pozycji kursora
    int bioschar

    dec si
    jnz invnext ;odwracamy kolejny znak, aż do wyczer-pania si
    pop cx ;odzyskujemy pozycję kursora menu '4

    ;di = 1 dla jednego przebiegu
    dec di ;zliczamy przebiegi
    jnz showitem; teraz nastąpi rysowanie nowej pozycji
    inc di ;wybrana pozycja jest już narysowana
    inc di ;di = 2 (mazanie menu w kolejnym przejściu)

;Odczyt klawiatury i reakcje na naciśnięcie klawiszy Up, Down, Enter
;cały kbnext używa: ax,bh(= 0),dx, bp (przy wyjściu)
;używa: ax
kbnext:    mov ah,readkey
    int bioskey ;ah - kod klawisza, al - znak lub 0 lub 0e0h
    cmp al,cr
    je wybierz ;wciśnięty Enter - obliczamy i wczytu-jemy

    cmp al,0h ;kod kl. zwykłej
    je scankey ;znak z numerycznej
    cmp al,0e0h ;kod kl. rozszerzonej
    jne kbnext
        ;znak z rozszerzonej
scankey: ;kody klawiatury (nie ASCII)
    cmp ah,up
    je wgore
    cmp ah,down
    jne kbnext ;nie zmieniamy menu, wczyt. kolejny znak

wdol:    inc ch ;zmiana nowej pozycji
    jmp short menuitem ;mazanie aktualnej pozycji menu

wgore:    dec ch ;zmiana nowej pozycji
    jmp short menuitem ;mazanie aktualnej pozycji menu
;koniec kbnext

;=============================================================================
;używa: ax,bp,cl
wybierz: ;jeśli wybrana poz. jest strefą ładuje jej bootsector
    xor ah,ah
    mov al,cl ;cl - aktualny numer strefy
    shl al,4
    add ax,offset tablica + mvsector ;ax = tablica + cl * 16
    mov bp,ax
    cmp byte ptr [bp+pttype],0 ;robi powrót gdy brak par-tycji
    je kbnext
    pop dx ;zdjęcie pozycji kursora ze stosu '3
    add dh,5 ;kursor wiersz poniżej menu
    mov ah,setcurpos
    int bioschar
    pop cx ;odtworzony pierwotny typ kursora '2
    mov ah,setcursor
    int bioschar ;odtwarza wygląd kursora
savetpart:
;    mov bx,mvsector
    pop bx ;bufor zapisu: mvsector '1
    mov dx,80h ;head = 0 ;set disk
    mov cx,1 ;cylinder = 0 ;sector = 1
    mov ax,301h ;save disk ;sectors = 1
    mov [bp],dl ;wstawienie aktywności dla wybranej strefy
    int biosdsk ;zapis tablicy partycji na dysku
loadboot:
;    mov bx,sector
    pop bx ;bufor odczytu: sector '0
    mov cx,[bp+ptcs] ;set cylinder, sector
    mov dh,[bp+pth] ;set head
    mov si,5 ;maksymalna ilość powtórzeń odczytu
load:
    mov ax,201h ;read disk ;sectors = 1
    int biosdsk
    jc resetdsk
    cmp word ptr ds:[flagptable+sector],bootflag
    je runboot
resetdsk: xor ah,ah ;reset disk
    int biosdsk
    dec si
    jnz load

    ;wyświetla komunikat błędu i wpada w martwą pętlę
    mov si,offset rderrinfo + mvsector
    call print
haltloop: jmp short haltloop

runboot: ;uruchamia wczytany pod adres sector program bootstart.
    mov di,sp
    push di ;'1
     ret ;'0
;***PROCEDURY****************************************************
;drukuje na ekranie tekst od kursora (jako terminal)
;si - adres łańcucha tekstowego, ustawiony kursor
;używa: ax,bl,bh (= 0),si
pnext:
;    mov bl,7 ;kolor biały (tylko dla trybu graficznego)
    mov ah,setchartty
    int bioschar
print:    lodsb
    cmp al,0
    jnz pnext
    ret

;***DANE********************************************************
rderrinfo: db cr, lf, lf, 'READ ERROR: '
infotext: db 'Multistart MBR 1.1'
crlf:    db cr, lf, 0

ptinfo:
    db ' System strefy nr 1 ',0 ;descsize dup (0)
    db ' System strefy nr 2 ',0 ;descsize dup (0)
    db ' System strefy nr 3 ',0 ;descsize dup (0)
    db ' System strefy nr 4 ',0 ;descsize dup (0)

;***TABLICA PARTYCJI********************************************
    org ptable
tablica:
    db 4*16 dup (0ffh)
bflag:    dw bootflag
    org 512
endsector:
    public movestart, infotext, ptinfo, tablica

csegment ends
    end movestart
;Copyright Olamagato 1998

Teraz już chyba rozumiesz dlaczego nie pisze się w asemblerze, czyli w tekstowym odpowiedniku kodu maszynowego procesora. Jak dla czegoś tak małego trzeba się było tak rozpisać, to prościej wymyślić język, który będzie tłumaczony na assembler (lub od razu na kod maszynowy).

Jednak mimo to assemblery nigdy nie znikną. A to dlatego, że kiedy powstaje nowy procesor, którego kod nie jest zgodny z dotychczasowymi CPU, to trzeba napisać w nim na innym procesorze programy tak podstawowe jak BIOS, program asemblera (zamieniającego tekst asm na kod maszynowy (np. .bin), jakiś pierwszy kompilator pozwalający przekompilować jakiś istniejący kod systemu operacyjnego napisanego w C oraz sterowniki urządzeń. Dopiero wtedy cokolwiek można na komputerze z nowym CPU uruchomić.
Oczywiście dla każdego procesora jest osobny język assemblera. Bez assemblera nie da się użyć żadnego nowego procesora, albo trzeba skorzystać ze starszego komputera generującego kod dla nowego CPU. I tak się dzisiaj robi, żeby uniknąć robienia wszystkiego od początku dla każdego CPU.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 27.02.2009 o 22:04, sig. napisał:

Bo samo w takowym programowanie trwa dłużej i jest już dość leciwy (dodatkowo działa
tylko na x86, nie da się go przenieść na inną architekturę)

Sig. Assembler nie może być leciwy bo jest to tekstowy odpowiednik kodu maszynowego CPU. Assembler jest więc tak nowy jak nowy jest model procesora. Np. Assemblery dla Phenoma czy Core 7 to są zupełne nówki. A ich jedyna starość polega na zgodności w dół ze starym kodem procesora Intel 8086/80386.

A co do języka C, to jest on całkiem efektywnym zamiennikiem assemblera i trzeba z niego przechodzić na assembler tylko wtedy kiedy jest bardzo istotne w jakich rejestrach procesora są trzymane jakie dane lub do użycia rozkazów we/wy takich jak IN i OUT. Gdybym chciał przetłumaczyć kod z wcześniejszego posta na C, to kod źródłowy zająłby kilka linijek, a kod wykonywalny ok. 500-600 bajtów. W assemblerze zmieściłem go w 380 bajtów. 500 do prawie 400, to nie aż tak dużo. W normalnych przypadkach opłaca się narzut tej 1/5 kodu więcej za skrócenie kodowania o 1000%. Dlatego C będzie aktualny jeszcze przez 20-30 lat - jak nie dłużej.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Kalkulator w C

#include <stdio.h>
#include <stdlib.h>


int main(int argc, char *argv[])
{
int x,y;
printf("Wpisz liczbe x:");
scanf("%i",&x);
printf("Wpisz liczbe y:");
scanf("%i",&y);
printf("x+y=%i\n",x+y);
printf("x-y=%i\n",x-y);
printf("x*y=%i\n",x*y);
printf("x/y=%i\n",x/y);
if (y==0) {
printf("Nie mozna dzielic przez zero!\n");}

system("PAUSE");
return 0;
}


Teraz pytanie - dlaczego kiedy dzielę przez zero wywala mnie z programu? coś jest źle wpisane?

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 03.03.2009 o 15:49, Deejay napisał:

Teraz pytanie - dlaczego kiedy dzielę przez zero wywala mnie z programu?

Bo twój program najpierw dzieli przez zero (i go wywala), a dopiero później wyświetla komunikat. Musisz stworzyć warunek

if (y==0) {
printf("Nie mozna dzielic przez zero!\n");}
else
printf("x/y=%i\n",x/y);

Wtedy program najpierw sprawdzi czy dzieli przez zera - jeśli tak - wyświetli komunikat i pominie dzielenie, jeśli nie - podzieli i wyświetli wynik.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Niedawno zacząłem pracę z Ada no i natrafiłem na pierwsze problemy. Po wpisaniu poleceń max(...) i min (...) przy próbie kompilacji pojawia się ""Max" is undefined" i ""Min" is undefined". Jak rozumiem, nie podałem odpowiednich bibliotek na początku programu. I tu prośba do Was:

1)Czy to właśnie o to chodzi?
2)Czy moglibyście podać stronę ze spisem bibliotek i opisem do nich?

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Wiecie panowie guru Olomagato i Sig od programowania że Jan Czarny to małolat ? Jednak zadziwia mnie on swoimi wyczynami, dobry jest. Ambitny typ z niego ;).

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 06.03.2009 o 11:27, TetraGramaton napisał:

Wiecie panowie guru Olomagato i Sig od programowania że Jan Czarny to małolat ? Jednak
zadziwia mnie on swoimi wyczynami, dobry jest. Ambitny typ z niego ;).


Jeśli wierzyć informacjom podanym przez niego na gramsajcie to w tym roku skończy on 16 lat... Każdy kiedyś zaczynał, np. ja również zaczynałem w tym wieku i nie widzę w odpowiadaniu na jego pytania niczego złego (nawet, jeśli mogą być dla niego na razie nieco niezrozumiałe). Jeśli mimo tylu przeciwności jego wciąż to kręci, to naprawdę godne podziwu.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Teraz , chwila odpoczynku od c++ i php :) [Tu już ładnie jadę :P ]

Zastanawiam się czy ma sens krycie nazw plików

bo
http://localhost/wot.php

czy
http://localhost/index.php?sw=two

jest tym samym , zawsze widzimy kod źródłowy tego pliku :)

zatem

jeżeli dane będą trzymane w sesji , a skrypt zabezpieczony przed zabójczymi kombinacjami [niebezpieczne dane na wejściu ] :P (mam kilka patentów na sprawdzanie tego :P )


Pytanie od siebie co warto div z iframe , czy frame ?
i Czy warto trzymać dane w sesji czy w SQL (Najbardziej używane)
i czy ma sens czyszczenie zmiennych przed zamknięciem skryptu ?


Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Czy ktoś się orientuje jak ustawić direcx''a w Code::Blocks ?
Ściągnąłem najnowszego DX SDK nov2008, zainstalowałem na K:\DXsdk
Włączam codeblocka, robię Create New Project, wybieram Direct/X project i dochodzę do momentu gdzie jest takie coś jak na obrazku1. Jak dam dalej, to wyskakuje obrazek2, a jak ręcznie mu wpisze K:\ to mówi że dobra ścieżka, ale nie może znaleźć plików DXa

20090313180739

20090313180755

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

A nie powinieneś w tej ścieżce wpisać K:\DXsdk? Musisz podać ścieżkę do miejsca, w którym znajdują się katalogi "include" i "lib".

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 13.03.2009 o 20:06, Treant napisał:

A nie powinieneś w tej ścieżce wpisać K:\DXsdk? Musisz podać ścieżkę do miejsca, w którym
znajdują się katalogi "include" i "lib".

Ops, wpisuje K:\DXsdk (błąd w poście :]). W środku są lib, include, template, samples itp (K:\DXsdk\lib, DXsdk\include) Ale niezależnie co mu tam wpisze wyskakuje ze nie ma plików DXa.

Może ściągnę VC++2008 express, może tam zadziała, szkoda tylko że trzeba na C instalować(nie licząc kilkunastu mb które mogę na innym) :/

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 31.03.2009 o 16:23, Robak 007 napisał:

Jeżeli pozwolisz, zadam Ci jeszcze jedno pytanie. Mogę wiedzieć, w jakim wieku Ty zacząłeś
naukę programowania?


Na przełomie 15 i 16 roku życia :) Czemu pytasz?

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 31.03.2009 o 21:46, Vilmar napisał:

> Jeżeli pozwolisz, zadam Ci jeszcze jedno pytanie. Mogę wiedzieć, w jakim wieku Ty
zacząłeś
> naukę programowania?

Na przełomie 15 i 16 roku życia :) Czemu pytasz?

Głównie z czystej ciekawości. Pytam także po to, aby porównać wiek w którym ty rozpocząłeś naukę programowania z wiekiem w którym ja zamierzam rozpocząć (tzn. najpierw zamierzam - tak jak poradziłeś - posiedzieć w edytorach) :)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 31.03.2009 o 23:02, Jan Czarny napisał:

Czy mi się zdaje ,że PHP jest bardziej swobodne od c++ w zastosowaniu (braknie mi słów


Nie, nie zdaje ci sie. Jest bardziej "swobodne".

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Utwórz konto lub zaloguj się, aby skomentować

Musisz być użytkownikiem, aby dodać komentarz

Utwórz konto

Zarejestruj nowe konto na forum. To jest łatwe!


Zarejestruj nowe konto

Zaloguj się

Masz już konto? Zaloguj się.


Zaloguj się
Zaloguj się, aby obserwować