🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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
#1402
Author: Doleś
Date: Fri, 03 Aug 2007 08:37
31 lines
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
#1403
Author: Kicer
Date: Fri, 03 Aug 2007 10:16
50 lines
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
#1404
Author: Doleś
Date: Fri, 03 Aug 2007 10:51
54 lines
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
#1405
Author: Wojciech Muła
Date: Fri, 03 Aug 2007 11:36
13 lines
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
#1407
Author: Remek
Date: Fri, 03 Aug 2007 12:40
25 lines
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
#1408
Author: Doleś
Date: Fri, 03 Aug 2007 13:06
5 lines
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
#1409
Author: Remek
Date: Fri, 03 Aug 2007 19:06
18 lines
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
#1410
Author: Bogdan (bogdro)
Date: Sun, 05 Aug 2007 17:03
33 lines
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
#1411
Author: Doleś
Date: Sun, 05 Aug 2007 18:23
127 lines
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
#1412
Author: Bogdan (bogdro)
Date: Mon, 06 Aug 2007 13:52
49 lines
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
#1406
Author: Wiktor S.
Date: Sun, 12 Aug 2007 12:44
9 lines
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
#1413
Author: Wiktor S.
Date: Sun, 12 Aug 2007 12:49
42 lines
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
#1414
Author: Bogdan (bogdro)
Date: Sun, 12 Aug 2007 13:59
55 lines
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