Thread View: pl.comp.lang.asm
13 messages
13 total messages
Started by Doleś
Fri, 03 Aug 2007 08:37
Wyświetlanie liczb od 90 do 100
Author: Doleś
Date: Fri, 03 Aug 2007 08:37
Date: Fri, 03 Aug 2007 08:37
31 lines
1966 bytes
1966 bytes
Mam niemały problem z moim programem, który pisałem na Linuksie. Zatem naskrobałem taki właśnie kod: format ELF executable segment readable executable _start: mov dx,90; od tej liczby zaczynam wyświetlać mov cx, 10; robię licznik dla pętli wyswietlanie: ;pętla wyświetlająca push cx ;wydaje mi się, że skoro będę używał funkcji sys_write push dx ; to muszę te rejestry odłożyć na stos bo będą zmodyfikowane mov eax, 4 mov ebx, 1 mov ecx,[edx] mov edx, 1 ; wg moich założeń znak powinien zostać wyświetlony int 80h xor ecx,ecx ;nie wiem po co ale zeruję rejestr ecx pop dx ;przywracam stare wartości pop cx inc dx ;zwiększam dx aby mieć koleją liczbę do wyświetlnia loop wyswietlanie mov eax, 1 int 80h Niestety po skompilowaniu tego program i uruchomieniu mam błąd "Naruszenie ochrony pamięci". Nie mam IQ na poziomie 180 więc nie wiem, gdzie popełniłem błąd, tym bardziej, że w moim mniemaniu napisałem dobry algorytm. Byłbym wdzięczny za pomoc.
Re: Wyświetlanie liczb od 90 do 100
Author: Kicer
Date: Fri, 03 Aug 2007 10:16
Date: Fri, 03 Aug 2007 10:16
50 lines
2484 bytes
2484 bytes
Doleś wrote: > Mam niemały problem z moim programem, który pisałem na Linuksie. Zatem > naskrobałem taki właśnie kod: > > format ELF executable > > segment readable executable > _start: > > mov dx,90; od tej liczby zaczynam wyświetlać > mov cx, 10; robię licznik dla pętli tworzysz 32 bitowy program używaj wiec mov edx,90 i analogicznie ecx > > wyswietlanie: ;pętla wyświetlająca > push cx ;wydaje mi się, że skoro będę używał funkcji sys_write > push dx ; to muszę te rejestry odłożyć na stos bo będą zmodyfikowane znowu edx i ecx :) > mov eax, 4 > mov ebx, 1 > mov ecx,[edx] ładujesz do ecx wartość z komórki pamieci o offcecie edx (za pierwszym razem jest to 90) względem segmentu danych, chyba nie o to chodzilo :) > mov edx, 1 ; wg moich założeń znak powinien zostać wyświetlony > int 80h nie wiem jak to jest z funkcjami w linuxie ale powolując się na: http://rudy.mif.pg.gda.pl/~bogdro/linux/przer80h_1.html śmiem twierdzić ze próbujesz zapisywać dane do pliku ;) > xor ecx,ecx ;nie wiem po co ale zeruję rejestr ecx niepotrzebne ;) > pop dx ;przywracam stare wartości > pop cx > inc dx ;zwiększam dx aby mieć koleją liczbę do wyświetlnia edx ecx edx > loop wyswietlanie > > mov eax, 1 > int 80h tu juz dobra funkcja :) > Niestety po skompilowaniu tego program i uruchomieniu mam błąd > "Naruszenie ochrony pamięci". Nie mam IQ na poziomie 180 więc nie wiem, > gdzie popełniłem błąd, tym bardziej, że w moim mniemaniu napisałem dobry > algorytm. Byłbym wdzięczny za pomoc. -- Michał Walenciak, gg: 3729519, mail: Kicer86 na gmail kropka com http://kicer.elsat.net.pl
Re: Wyświetlanie liczb od 90 do 100
Author: Doleś
Date: Fri, 03 Aug 2007 10:51
Date: Fri, 03 Aug 2007 10:51
54 lines
3110 bytes
3110 bytes
Kicer wrote: > Doleś wrote: > >> Mam niemały problem z moim programem, który pisałem na Linuksie. Zatem >> naskrobałem taki właśnie kod: >> >> format ELF executable >> >> segment readable executable >> _start: >> >> mov dx,90; od tej liczby zaczynam wyświetlać >> mov cx, 10; robię licznik dla pętli > > tworzysz 32 bitowy program używaj wiec mov edx,90 i analogicznie ecx >> >> wyswietlanie: ;pętla wyświetlająca >> push cx ;wydaje mi się, że skoro będę używał funkcji sys_write >> push dx ; to muszę te rejestry odłożyć na stos bo będą zmodyfikowane > > znowu edx i ecx :) > >> mov eax, 4 >> mov ebx, 1 >> mov ecx,[edx] > ładujesz do ecx wartość z komórki pamieci o offcecie edx (za pierwszym razem > jest to 90) względem segmentu danych, chyba nie o to chodzilo :) >> mov edx, 1 ; wg moich założeń znak powinien zostać wyświetlony >> int 80h > nie wiem jak to jest z funkcjami w linuxie ale powolując się na: > http://rudy.mif.pg.gda.pl/~bogdro/linux/przer80h_1.html > śmiem twierdzić ze próbujesz zapisywać dane do pliku ;) >> xor ecx,ecx ;nie wiem po co ale zeruję rejestr ecx > niepotrzebne ;) >> pop dx ;przywracam stare wartości >> pop cx >> inc dx ;zwiększam dx aby mieć koleją liczbę do wyświetlnia > edx ecx edx >> loop wyswietlanie >> >> mov eax, 1 >> int 80h > tu juz dobra funkcja :) >> Niestety po skompilowaniu tego program i uruchomieniu mam błąd >> "Naruszenie ochrony pamięci". Nie mam IQ na poziomie 180 więc nie wiem, >> gdzie popełniłem błąd, tym bardziej, że w moim mniemaniu napisałem dobry >> algorytm. Byłbym wdzięczny za pomoc. > Wielkie dzięki. Nie używałem rejestrów 32 bitowych bo sobie ubzdurałem, że to marnotractwo. Przyzwyczaiłem się nieco do książki "Assembler dla procesorów Intel. Vademecuum Profesjonalisty" a tam jest właśnie zdecydowana większość kodów napisana na rejestrach 16 bitowych, niemniej 32 też istnieją i to nawet w jednym programie. No cóż najwyraźniej łapię złe nawyki na początek :) Jeszcze raz dziękuję za pomoc.
Re: Wyświetlanie liczb od 90 do 100
Author: Wojciech Muła
Date: Fri, 03 Aug 2007 11:36
Date: Fri, 03 Aug 2007 11:36
13 lines
1592 bytes
1592 bytes
Doleś wrote: > Wielkie dzięki. Nie używałem rejestrów 32 bitowych bo sobie ubzdurałem, > że to marnotractwo. Przyzwyczaiłem się nieco do książki "Assembler dla > procesorów Intel. Vademecuum Profesjonalisty" a tam jest właśnie > zdecydowana większość kodów napisana na rejestrach 16 bitowych, niemniej > 32 też istnieją i to nawet w jednym programie. Już to kiedyś pisałem na pl.comp.programming: współczesne książki do asemblera opisują jakieś starocie sprzed 20 lat; szkoda na nie kasy, lepiej kupić sobie piwo i przy jego pomocy przyswajać manuale Intela, względnie AMD. w.
Re: Wyświetlanie liczb od 90 do 100
Author: Remek
Date: Fri, 03 Aug 2007 12:40
Date: Fri, 03 Aug 2007 12:40
25 lines
1479 bytes
1479 bytes
Użytkownik "Doleś" napisał: > push cx ;wydaje mi się, że skoro będę używał funkcji sys_write > push dx ; to muszę te rejestry odłożyć na stos bo będą zmodyfikowane > mov ecx,[edx] .......... > pop dx ;przywracam stare wartości > pop cx Modyfikujesz ecx i edx, a przywracasz tylko cx i dx. Nie widzisz tu niekonsekwencji? > mov dx,90 ......... > mov ecx,[edx] Do ecx usiłujesz załadować dane z pod adresu dx=90 + nieokreślone wartości w górnej połówce edx. Nic dziwnego, że się sypie. -- Pozdrawiam Remek K7S5A, Duron 1,1 Windows98 SE, IE6, OE6
Re: Wyświetlanie liczb od 90 do 100
Author: Doleś
Date: Fri, 03 Aug 2007 13:06
Date: Fri, 03 Aug 2007 13:06
5 lines
1218 bytes
1218 bytes
Wybacz, ale po prostu nie do końca jeszcze rozumiem znaczenie [] w Asemblerze. Czy to jest jakis odpowiednik operatora wyłuskania z C/C++ czy mam to sobie tłumaczyć jako "operator odwołania się do elementu zapisanego w TYM adresie" ?
Re: Wyświetlanie liczb od 90 do 100
Author: Remek
Date: Fri, 03 Aug 2007 19:06
Date: Fri, 03 Aug 2007 19:06
18 lines
1483 bytes
1483 bytes
Użytkownik "Doleś" napisał: > Wybacz, ale po prostu nie do końca jeszcze rozumiem znaczenie [] w > Asemblerze. W takim razie zacznij od jakiejś książki na ten temat, albo wpisz w Google "asembler" i poczytaj. Jeśli nie rozumiesz języka, to jak chcesz pisać w nim programy? > czy mam to sobie tłumaczyć jako "operator odwołania się do elementu > zapisanego w TYM adresie"? Mniej więcej o to chodzi. W [...] jest adres, pod którym siedzą jakieś dane. -- Pozdrawiam Remek K7S5A, Duron 1,1 Windows98 SE, IE6, OE6
Re: Wyświetlanie liczb od 90 do 100
Author: Bogdan (bogdro)
Date: Sun, 05 Aug 2007 17:03
Date: Sun, 05 Aug 2007 17:03
33 lines
2461 bytes
2461 bytes
Doleś pisze: > > Wybacz, ale po prostu nie do końca jeszcze rozumiem znaczenie [] w > Asemblerze. Czy to jest jakis odpowiednik operatora wyłuskania z C/C++ > czy mam to sobie tłumaczyć jako "operator odwołania się do elementu > zapisanego w TYM adresie" ? Tak, nawiasy kwadratowe to dereferencja, jak gwiazdka przy '*ptr' w C/C++, jesli 'ptr' to wskaźnik. Używasz kompilatora FASM, a w nim nazwa zmiennej gra rolę wskaźnika, czyli mov eax, zmienna == 'eax = &zmienna' w C/C++ mov eax, [zmienna] == 'eax = *&zmienna' w C/C++ Jako że * i & się "znoszą", ostatnie wyrażenie to po prostu 'eax=zmienna', czyli odczyt zawartości pamięci wskazywanej przez wskaźnik o nazwie 'zmienna'. Co do marnotrawstwa - wyobraź sobie, że używanie rejestrów 16-bitowych w Linuksie to marnotrawstwo :) Jako że program jest domyślnie 32-bitowy, używanie rejestrów 16-bitowych powoduje dodanie po 1 bajcie (66h) do kazdej instrukcji z nich korzystającej. Algorytm ogólnie masz dobry - wyświetlanie, pętla, zachowywanie rejestrów. Rzecz w tym, że liczby tak nie wyświetlisz. Funkcja EAX=4 wyświetla ciąg znaków, więc musisz najpierw liczbę przerobić na ciąg znaków. Zajrzyj do http://rudy.mif.pg.gda.pl/~bogdro/linux/linux04.html -- Pozdrawiam/Regards - Bogdan (Linux & FreeDOS) Kurs asemblera x86 (DOS & Linux): http://rudy.mif.pg.gda.pl/~bogdro Grupy dyskusyjne o asm: pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32 Rozmawiaj bezpiecznie: www.JabberPL.org Surfuj anonimowo: tor.eff.org
Re: Wyświetlanie liczb od 90 do 100
Author: Doleś
Date: Sun, 05 Aug 2007 18:23
Date: Sun, 05 Aug 2007 18:23
127 lines
3329 bytes
3329 bytes
Teraz napisałem ten program i działa poprawnie (użyłem Twojego - Bogdan - algorytmu).Mianowicie kod źródłowy jest taki: > format ELF executable > entry _start > segment readable executable > > lf = 10 > stdout = 1 > sys_write = 4 > > > > _start: > > mov eax, 90 > > wyswietlaj: > call _pisz_ld > > call _nwln > > add eax, 1 > cmp eax, 101 > jb wyswietlaj > > > mov eax, 1 > xor ebx, ebx > int 80h > > > > > > _pisz_ld: > > > > pushfd > push ecx > push edx > push eax > push esi > > xor esi, esi > mov ecx, 10 > > ._pisz_ld_petla: > xor edx, edx > div ecx > > or dl, "0" > mov [_pisz_bufor+esi], dl > inc esi > > test eax, eax > jnz ._pisz_ld_petla > > ._pisz_ld_wypis: > mov al, [_pisz_bufor+esi-1] > call _pisz_z > > dec esi > jnz ._pisz_ld_wypis > > pop esi > pop eax > pop edx > pop ecx > popfd > > ret > > > _pisz_z: > > push eax > push ebx > push ecx > push edx > > mov [_pisz_bufor+39], al > > mov eax, sys_write > mov ebx, stdout > > lea ecx, [_pisz_bufor+39] > mov edx, 1 > int 80h > > pop edx > pop ecx > pop ebx > pop eax > > ret > > > _nwln: > > > push eax > > mov al, lf > call _pisz_z > > pop eax > ret > > > > segment readable writeable > > _pisz_bufor: times 40 db 0 Tylko, że nie jestem ani trochę zadowolony z tego programu. Bo to co za sztuka przepisać czyiś kod i zmienić nieco kilka linijek ? Jakoś nie bardzo udowodniłem sobie iż potrafię. A to, że wcześniejszym sposobem nie wyświetlę liczby to zauważyłem. Albo miałem 10 razy w nowej linni znak "Z" albo coś skopałem w kodzie i miałem w każdej lini jakiś śmieć (w sensie dziwny znak np "]" a potem "^"). Myślałem sobie żeby taką liczbę jak np 92 wyświetlić jako ciąg znaków ASCII "9" i "2" a potem tylko odpowiednio operatorem [] inkrementować drugi element ciągu czyli tę wspomianą dwójkę. Tylko jak bym potem załatwił sprawę zamiany mojej liczby dwucyfrowej na trzycyfrową ? Byłoby dużo grzebaniny. Niemniej nie jestem usatysfakcjonowany tym powyższym kodem, bo jakby nie patrzeć to nie mój wytwór.
Re: Wyświetlanie liczb od 90 do 100
Author: Bogdan (bogdro)
Date: Mon, 06 Aug 2007 13:52
Date: Mon, 06 Aug 2007 13:52
49 lines
3190 bytes
3190 bytes
Doleś pisze: > Teraz napisałem ten program i działa poprawnie (użyłem Twojego - Bogdan > - algorytmu).Mianowicie kod źródłowy jest taki: [...] > Tylko, że nie jestem ani trochę zadowolony z tego programu. Bo to co za > sztuka przepisać czyiś kod i zmienić nieco kilka linijek ? Jakoś nie > bardzo udowodniłem sobie iż potrafię. A to, że wcześniejszym sposobem > nie wyświetlę liczby to zauważyłem. Albo miałem 10 razy w nowej linni > znak "Z" albo coś skopałem w kodzie i miałem w każdej lini jakiś śmieć > (w sensie dziwny znak np "]" a potem "^"). Myślałem sobie żeby taką > liczbę jak np 92 wyświetlić jako ciąg znaków ASCII "9" i "2" a potem > tylko odpowiednio operatorem [] inkrementować drugi element ciągu czyli > tę wspomianą dwójkę. Tylko jak bym potem załatwił sprawę zamiany mojej > liczby dwucyfrowej na trzycyfrową ? Byłoby dużo grzebaniny. Niemniej nie > jestem usatysfakcjonowany tym powyższym kodem, bo jakby nie patrzeć to > nie mój wytwór. Ja bym też nie był usatysfakcjonowany. Dlatego zachęcam do nauki i zrozumienia samego algorytmu, jest przecież opisany. Jeśli wolisz, możesz uzyć prostszego: dla liczb 16-bitowych wygląda on tak: 1) podziel liczbę przez 10 000 i wyświetl iloraz 2) resztę z 1) podziel przez 1000 i wyświetl iloraz 3) resztę z 2) podziel przez 100 i wyświetl iloraz 4) resztę z 3) podziel przez 10 i wyświetl iloraz 5) wyświetl resztę z 4) Dla liczb 32-bitowych dzielenie zaczyna się od miliarda i też schodzi po 1 zerze na krok. Wyświetlanie ilorazu, który za każdym razem jest tylko 1 cyfrą 0-9, jest proste: wystarczy do niego dodać kod ASCII zera, o tak: add al, '0' po czym użyć funkcji 4 przerwania 80h, którą już znasz, z tym, że do ECX ładujesz adres zmiennej zawierajacej cyfrę: mov [cyfra], al ... mov eax, 4 ... mov ecx, cyfra ... int 80h -- Pozdrawiam/Regards - Bogdan (Linux & FreeDOS) Kurs asemblera x86 (DOS & Linux): http://rudy.mif.pg.gda.pl/~bogdro Grupy dyskusyjne o asm: pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32 Rozmawiaj bezpiecznie: www.JabberPL.org Surfuj anonimowo: tor.eff.org
Re: Wyświetlanie liczb od 90 do 100
Author: Wiktor S.
Date: Sun, 12 Aug 2007 12:44
Date: Sun, 12 Aug 2007 12:44
9 lines
1205 bytes
1205 bytes
> Wielkie dzięki. Nie używałem rejestrów 32 bitowych bo sobie > ubzdurałem, że to marnotractwo. Generalnie w trybie 32-bitowym używa się 32-bitowych rejestrów, a 16-bitowych tylko, gdy zachodzi konkretna potrzeba ;-) -- Azarien
Re: Wyświetlanie liczb od 90 do 100
Author: Wiktor S.
Date: Sun, 12 Aug 2007 12:49
Date: Sun, 12 Aug 2007 12:49
42 lines
2411 bytes
2411 bytes
Bogdan (bogdro) wrote: > Doleś pisze: >> >> Wybacz, ale po prostu nie do końca jeszcze rozumiem znaczenie [] w >> Asemblerze. Czy to jest jakis odpowiednik operatora wyłuskania z >> C/C++ czy mam to sobie tłumaczyć jako "operator odwołania się do >> elementu zapisanego w TYM adresie" ? > > Tak, nawiasy kwadratowe to dereferencja, jak gwiazdka przy '*ptr' w > C/C++, jesli 'ptr' to wskaźnik. Używasz kompilatora FASM, a w nim > nazwa zmiennej gra rolę wskaźnika, czyli > > mov eax, zmienna == 'eax = &zmienna' w C/C++ > mov eax, [zmienna] == 'eax = *&zmienna' w C/C++ > > Jako że * i & się "znoszą", ostatnie wyrażenie to po prostu > 'eax=zmienna', czyli odczyt zawartości pamięci wskazywanej przez > wskaźnik o nazwie 'zmienna'. > > Co do marnotrawstwa - wyobraź sobie, że używanie rejestrów > 16-bitowych w Linuksie to marnotrawstwo :) Jako że program jest > domyślnie 32-bitowy, używanie rejestrów 16-bitowych powoduje dodanie > po 1 bajcie (66h) do kazdej instrukcji z nich korzystającej. VETO :-) mov eax,10 to B8 0A 00 00 00 mov ax,10 to 66 B8 0A 00 czyli mimo wszystko o bajt mniej ;-) ale mimo wszystko należy używać rejestrów 32-bitowych, chyba że zachodzi uzasadniona okoliczność, by uczynić inaczej. disclaimer: heksy z pamięci, nie bić jeśli nie jest to B8 ;-) -- Azarien
Re: Wyświetlanie liczb od 90 do 100
Author: Bogdan (bogdro)
Date: Sun, 12 Aug 2007 13:59
Date: Sun, 12 Aug 2007 13:59
55 lines
3134 bytes
3134 bytes
Wiktor S. pisze: > Bogdan (bogdro) wrote: >> Doleś pisze: >>> >>> Wybacz, ale po prostu nie do końca jeszcze rozumiem znaczenie [] w >>> Asemblerze. Czy to jest jakis odpowiednik operatora wyłuskania z >>> C/C++ czy mam to sobie tłumaczyć jako "operator odwołania się do >>> elementu zapisanego w TYM adresie" ? >> >> Tak, nawiasy kwadratowe to dereferencja, jak gwiazdka przy '*ptr' w >> C/C++, jesli 'ptr' to wskaźnik. Używasz kompilatora FASM, a w nim >> nazwa zmiennej gra rolę wskaźnika, czyli >> >> mov eax, zmienna == 'eax = &zmienna' w C/C++ >> mov eax, [zmienna] == 'eax = *&zmienna' w C/C++ >> >> Jako że * i & się "znoszą", ostatnie wyrażenie to po prostu >> 'eax=zmienna', czyli odczyt zawartości pamięci wskazywanej przez >> wskaźnik o nazwie 'zmienna'. >> >> Co do marnotrawstwa - wyobraź sobie, że używanie rejestrów >> 16-bitowych w Linuksie to marnotrawstwo :) Jako że program jest >> domyślnie 32-bitowy, używanie rejestrów 16-bitowych powoduje dodanie >> po 1 bajcie (66h) do kazdej instrukcji z nich korzystającej. > > VETO :-) > > mov eax,10 to B8 0A 00 00 00 > mov ax,10 to 66 B8 0A 00 No dobra, tego przypadku nie rozważałem. Niemniej, jeśli dałoby się mov ax, dword 10 żeby wielkość stałej była taka sama, to byłoby o 1 bajt więcej. :) Ale racja, punkt dla Ciebie :) Dodam jeszcze, że jak się adresuje 16-bitowo w kodzie 32-bitowym, to dochodzi kolejny bajt (67h). > czyli mimo wszystko o bajt mniej ;-) > ale mimo wszystko należy używać rejestrów 32-bitowych, chyba że zachodzi > uzasadniona okoliczność, by uczynić inaczej. Oczywiście, jeśli jest wygodne, lepsze, bardziej czytelne lub ma jakiekolwiek inne zalety, to można. Jednak jeśli szukamy wydajności, to zazwyczaj należy unikać rejestrów cząstkowych w ogóle. -- Pozdrawiam/Regards - Bogdan (Linux & FreeDOS) Kurs asemblera x86 (DOS & Linux): http://rudy.mif.pg.gda.pl/~bogdro Grupy dyskusyjne o asm: pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32 Rozmawiaj bezpiecznie: www.JabberPL.org Surfuj anonimowo: tor.eff.org
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads