Asembler czytanie z bufora

0

czesc,

mam nastepujacy problem, mam w buforze jakis ciag znakow oddzielony spacja, chce 1 czesc do spacji wpisac do jednej zmiennej i dodac znak na koncu, a 2 czesc po spacji wpisac do 2 zmiennej i dodac znak na koncu.

Przykładowy fragment kodu:

bufor db 100 dup('$')
zmienna1 db 50 dup('$')
zmienna2 db 50 dup('$') 

; tutaj wykonuje operacje pobrania do bufora ciagu znakow
; przykladowo mam w bufor == "Ala Ola"
; chce wpisac do zmienna1 AlaX, a do zmienna2 OlaX
 

Robilem to tak, ze przechodzilem po kolei po kazdym znaku bufora az do jego zakonczenia wpisujac kolejne znaki do odpowiednich zmiennych.
Wszystko dzialal, mam w zmiennych to co chce poza dodawaniem znaku X na koncu, do 1 zmiennej dodaje tak jak chce na koniec, a do zmiennej 2 ZAWSZE dodaje mi ten znak zamiast na ostatniej pozycji to na 1. Czyli zamiast OlaX mam za kazdym razem Xla, zamazuje dodatkowo 1 znak.

Probowalem juz wielu rzeczy, wlacznie z osobna procedura ktora przechodzi na sam koniec zmiennej2 zeby dopisac tam znak X ale za kazdym razem X laduje na 1 znaku, nadpisujac go.

Nie mam pojecia dlaczego tak sie dzieje, bylbym wdzieczny za pomoc

0

Tutaj kod:

init:	
	mov	ax, seg bufor
	mov	es,ax
	mov	si,offset bufor                  ; pod si adres 1 znaku argumentow 
	mov	di,offset zmienna1
	xor	cx,cx	
	mov	cl,byte ptr es:[liczba_znakow]   ; cx = ilosc znakow
p1:	
	push cx
	mov	al,byte ptr es:[si]
	cmp al, 32                  ; czy spacja? 
	jnz dalej
		mov byte ptr es:[di], 'X'     ; dodaje X na koniec 1 zmiennej 
                mov	di,offset zmienna2	; jesli tak to zapisujemy 2 czesc do 2 bufora 
              	jmp kont
				
	dalej:
	mov	byte ptr es:[di],al 	
	inc	di
	kont: 
	inc	si   	
	pop	cx
	loop	p1                            ; petla do skonczenia znakow z bufora 
        mov byte ptr es:[di], 'X'     ; dodanie X na koniec zmiennej2, to wlasnie tutaj nie dziala i dodaje na 1 pozycje 
	
	
ret  
0

Nie mam windowsa przy sobie, machnołem Ci coś takiego ale na linuxie:


segment .data
	napis db "Ala Ola ", 0Ah, 0h 

segment .bss
	buf1 resb 20
	buf2 resb 20

segment .text
        global  _start

_start:
	push napis	;napis na stos
	call strlen	;sprawdz dlugosc stringu znak do \0

	push eax	;dlugosc na stos
	push napis	;napis na stos
	call wypisz	;wyswietl

	push napis	;napis na stos
	push buf1	;tablica na stos
	call zamiana_x_spacja	
	push eax	;zachowujemy sobie gdzie skonczylismy zeby nie ucieklo
	
	push buf1	;wyswietlamy co przerobilismy
	call strlen	;dlugosc
	
	push eax	;glugosc na stos
	push buf1	;tablica na stos
	call wypisz	;wyswietlamy tablicę

	
	;gdzie skonczylismy jest na stosie
	push buf2	;drugi buf na stos
	call zamiana_x_spacja

	push buf2	;dlugosc 2 buf'a
	call strlen

	push eax	
	push buf2
	call wypisz	;wyswietlamy 2 buf'a

	call zakoncz	;konczymy

zamiana_x_spacja:
	push ebp
	mov ebp,esp
	push esi
	push edi
	push ecx
	push ebx

	mov esi, dword [ebp+08h]	; buf
	mov edi, dword [ebp+0Ch]	;napis
	petla:
		mov cl, [edi]		;najpierw kopjujemy
		mov [esi],cl		;
		inc esi			;inkrementacja
		inc edi
		cmp cl,' '		;sprawdzamy ze spacja
		jnz petla		;jesli nie jedziemy dalej
		mov [esi-1],byte 'X'	;za daleko? wpiszmy o jeden bajt wczensiej (poniewaz inkrementowalismy)
		mov [esi], byte 0	; znak 0 zeby nam strlen dzialal

	mov eax,edi ;zwracamy przez eax adres gdzie skonczylismy
	pop ebx
	pop ecx
	pop edi
	pop esi
	pop ebp
	ret 8


strlen:
	push ebp
	mov ebp,esp
	push ebx
	push ecx
	
	mov ebx, dword [EBP+08h]
	xor eax,eax
	sprawdz:
		mov cl,[ebx]
		inc eax
		inc ebx	
		cmp cl,0
		jne sprawdz
	
	pop ecx
	pop ebx
	pop ebp
	ret 4
wypisz: 
	push ebp
	mov ebp, esp
	push eax
	push ebx

        mov eax, 4
        mov ebx, 1
	mov ecx, dword [ebp+08h]
	mov edx, dword [ebp+0Ch]
	int 80h

	pop eax
	pop ebx
	pop ebp
	ret 8

zakoncz:
        mov     eax, 1
        xor     ebx, ebx
        int     0x80

 

Interesujace jest dla Ciebie "funkcja" zamiana_x_spacja. Pamietaj ze w twoim przypadku potrzebujesz zakonczyc string do wywietlenia znakiem $. Jak coś dodatkowo pytaj ;)

0

Dzięki wielkie!

Mam jeszcze pytanie z innej beczki, mianowicie przy czytaniu z pliku. Chce przeczytac caly plik, od poczatku do samego konca, zrobilem to w petli z loopem gdzie do cxa laduje dlugosc pliku, ale jestem przez to ogarniczony jedynie do 2^16 bajtowych plikow. Jak czytac sewencyjnie caly plik az do konca, nie znajac jego rozmiaru?
Wiem, ze po poprawnym wczytaniu przerawniem 3Fh dosowym do cf laduje 0, w przypadku bledu jest to 1. Czy mozna zrobic petle, ktora konczy cf == 1, wtedy przeczytam caly plik? Ewentualnie jakas inna metoda na to.

Dziekuje raz jeszcze o pomoc!

0

@Edit

Sprawdzilem petle z tym CF, wpada w nieskonczona petla, ktora czyta caly plik do ostatniego znaku a potem czyta ten ostatni znak w nieskonczonosc, czyli to nie zadziala. Sa jakies inne sposoby?

0

zrobilem to w petli z loopem gdzie do cxa laduje dlugosc pliku, ale jestem przez to ogarniczony jedynie do 2^16 bajtowych plikow

Użyj ECX.

Tylko nie wiem jak pod twoim asemblerem (TASM?) zapisać LOOP by używał ECX zamiast CX.
Spróbuj loop dword, loop dword ptr, loopd, w ostateczności zamień na dec/cmp/jnz.

czyli to nie zadziala
Zadziała, tylko coś źle robisz.

0

Tzn, aby sprawdzić czy doszliśmy do końca pliku, należy porównać liczbę bajtów, którą chciałeś odczytać od tej ile w rezultacie odczytałeś.

mov ah,3fh
mov dx, offset bufor ;bufor
mov bx,uchwyt		;uchwyt pliku
mov cx,wielkosc	;ilość bajtów do odczytania
int 21h
jc blad			;CF=1, błąd
cmp ax,cx		;nie ma błędu sprawdzamy ile odczytalismy
jb Odczyt_zakonczony	;różnica, czyli koniec pliku
 

Nie wiem jak jest w przypadku, plików wiekszych niż te 64K, nie mam jak sprawdzić. Ale możliwe, że uchwyt pliku tworzy się poprzez jakiś es:bx, co było by wielce korzystne. Niestety nie mogę znaleźć takiej informacji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1