"Vytvorte program v assembleri, ktorý zo zdrojového súboru zistí počet 10tich ľubovoľných znakov z ASCII sady a na obrazovku vypíše ich počet. Meno zdrojového súboru si program vyžiada a načíta z klávesnice. "
Velmi pekne vopred dakujem za nejake rady. Mam aj nejaky kod, od spoluyiakov o rocnik vzysie, ale niesom si istz ci to robi to co ma alebo nie.
Toto mi dali:
Kód: Vybrat vše
.Model SMALL
.STACK 100H
;------------------------------------------------
.DATA
zac DB 'Zadajte zdrojovy subor: $'
error DB 'V nacitanom retazci s vyskytla chyba.',10
DB 'Skontrolujte vstupny subor.',10
DB 'Skontrolujte delenie nulou.',10
DB '$' ;Cybove hlasenie pri citany
autor DB ' Autor: unknow ',10
DB ' Kruzok: 02 , AIAP ,3.roc $'
znaky DB 13,13
DB '$' ;Znaky urcujuce novy riadok vo vyslednom subore
zadanie DB 128 dup(0)
DB '$' ;Pamat rezervovana na nacitanie zadania
vysledo DB 10 dup(0)
DB '$' ;Pamat rezervovana na vyseledne retazce po aritmetickych operaciach
znak DB 1 dup(?)
DB '$' ;Pamat na presuvanie znaku (aritmetyckeho)
cislo1_s DB 0,0,0,0,0,'$' ;Pamat na 1. cislo v asci tvare
cislo2_s DB 0,0,0,0,0,'$' ;Pamat na 1. cislo v asci tvare
vysledok_s DB 0,0,0,0,0,'$' ;Pamet na vysledne cislo v asci tvare
vysledok_d Dw 0h ;Pamat na vysledok v 16b tvare
cislo1_d Dw 0h ;Pamat na prve cislo v 16b tvare
cislo2_d Dw 0h ;Pamat na druhe cislo v 16b tvare
subor DB 128 dup (?) ; sem chcem ulozit adresu suboru ktory chcem otvorit
;-------------------------------------------------------------------------------------------------------------------------------------
zdroj dw ?
ROZSAH DW ?
RIADOK DB 0AH
DB 0DH
DB '$'
Buffer DB 128 dup (?) ; buffer na ukladanie dat
.code
;-----------------------------------------------------------------------------------------------------------------------
Nacitajc PROC;=============Procedura ktora nacita jednotlive znaky prikaladu zo zadania
mov si, offset di ;funguje ako prenos adresi v nacitanom retazci-zadani,v di je adresa aktualneho znaku za =
mov al, [si] ;vlozi prvy znak z retazca
mov cislo1_s[0], al ;ulozi tento znak do premennej
inc si ;presunie sa na dalsi znak
mov al,[si] ;ulozi tento znak do premennej
mov cislo1_s[1], al
inc si
mov cl, [si] ;do registra cl vlozi mieto na ktorom je znak aritmetyckej operacie (-,*)
inc si
mov al, [si]
mov cislo2_s[0], al
inc si
mov al, [si]
mov cislo2_s[1], al
inc si
inc si
inc si
inc si
mov di, offset si ;nacita zaciatok dalsieho prikladu zo zaciatku
ret
ENDP;=============Procedura ktora nacita jednotlive znaky prikaladu zo zadania
;-------------------------------------------------------------------------------------------------------------------
odcitanie proc
call nuluj ;Zavola proceduru na vynulovanie vysledku
mov bx, offset cislo1_s ;vlozi adresu 1 cisla v asci tvare pred prevodom
call prevod ;Zavola proceduru na prevod cisla z asci tvaru na 16b tvar
mov cislo1_d, dx ;ulozi vysledok prevodu na miesto cislo1_d
mov bx, cislo1_d ;vlozi do registra bx cislo v 16b formate
add vysledok_d,bx ;pripocita k vysledku cislo v reg. bx
mov bx, offset cislo2_s ;vlozi adresu 2 cisla v asci tvare pred prevodom
call prevod ;Zavola proceduru na prevod cisla z asci tvaru na 16b tvar
mov cislo2_d, dx ;ulozi vysledok prevodu na miesto cislo2_d
mov bx, cislo2_d ;prenesie prelozene cislo na bx
sub vysledok_d,bx ;pripocita k vysledku cislo v reg. bx
call prevod1 ;Zavola proceduru na prevod vysledku 16b tvaru do asci tvaru
call vysledok ;Zavola proceduru na spracovanie vysledku
ret
ENDP ;=============Procedura ktora scita dve cisla v 16b formate
;-------------------------------------------------------------------------------------------------------------------------------
Nasobenie PROC ;=============Procedura ktora vydeli dve cisla v 16b formate
call nuluj ;Zavola proceduru na vynulovanie vysledku
mov bx, offset cislo1_s ;vlozi adresu 1 cisla v asci tvare pred prevodom
call prevod ;Zavola proceduru na prevod cisla z asci tvaru na 16b tvar
mov cislo1_d, dx ;ulozi vysledok prevodu na miesto cislo1_d
mov bx, cislo1_d ;vlozi do registra bx cislo v 16b formate
add vysledok_d, bx ;do vysledku vlozi delenec v 16 b formate
mov bx, offset cislo2_s ;vlozi adresu 2 cisla v asci tvare pred prevodom
call prevod ;Zavola proceduru na prevod cisla z asci tvaru na 16b tvar
mov cislo2_d, dx ;ulozi vysledok prevodu na miesto cislo2_d
mov bx, cislo2_d ;vlozi do registra bx cislo v 16b formate
cmp bx, 0 ;Porovna ci nieje vlozene cislo 0
je ERRo ;ak je o napise chybove hlasenie
mov ax, vysledok_d ;do registra ax vlozi delenec
MUL bl ;videli registre ax/bx
xor ah, ah ;vynuluje zvysok po deleni
mov vysledok_d, ax ;ulozi vysledok po deleni
call prevod1 ;Zavola proceduru na prevod vysledku 16b tvaru do asci tvaru
jmp X ;ak je vsetko v poriadku skoci na x
ERRo : call chyba ;spusti chybove hlasenie
X: call vysledok ;Zavola proceduru na spracovanie vysledku
ret
ENDP;=============Procedura ktora vydeli dve cisla v 16b formate
;--------------------------------------------------------------------------------------------------------------------------------
Vysledok PROC;=============Procedura ktora Spracuje vysledok
mov si, offset vysledo ;do registra si vlozi zaciatok retazca vysledo
mov al, cislo1_s[0]
mov [si], al ;na prve miesto ulozi prvu cislicu prveho cisla pocitaneho prikladu
inc si
mov al, cislo1_s[1]
mov [si], al ;na druhe miesto ulozi druhu cislicu 1 cisla pocitaneho prikladu
inc si
mov cl, znak
mov [si], cl ;na tretie miesto ulozi znamienko prenesene pomocou znaku
inc si
mov al, cislo2_s[0]
mov [si], al ;na dalsie miesto ulozi prvu cislicu druheho cisla pocitaneho prikladu
inc si
mov al, cislo2_s[1]
mov [si], al ;na dalsie miesto ulozi druhu cislicu druheho cisla pocitaneho prikladu
inc si
mov al, 061 ;vlozi znak = za cisla
mov [si], al
inc si
mov al, vysledok_s[0]
mov [si], al ;na dalsie miesto ulozi prvu cislicu vysledku pocitaneho prikladu
inc si
mov al, vysledok_s[1]
mov [si], al ;na dalsie miesto ulozi druhu cislicu vysledku pocitaneho prikladu
inc si
mov al, vysledok_s[2]
mov [si], al ;na dalsie miesto ulozi tretiu cislicu vysledku pocitaneho prikladu
inc si
mov al, znaky
mov [si],al ;na dalsie miesto vlozi znaky oddelujuce jednotlive prikady (enter)
mov bx, zdroj ;nacita file haldle otvoreneho suboru
mov dx, offset vysledo ;vlozi adresu takto poskaldaneho retazca vysledo do registra dx
mov cx, 10 ;nacita 10 b tohto registra
mov ah, 40h ;Instrukcia:zapise 10 b do suboru na 0 miesto od zaciatku suboru
int 21h ;volanie funkcie dosu
mov ah, 09h ;Instrukcia:Vypise retazec vysledo na obrazovku konzoly
int 21h ;volanie funkcie dosu
ret
ENDP;=============Procedura ktora Spracuje vysledok
;------------------------------------------------------------------------------------------------------------------------
Chyba PROC;=============Procedura ktora vypise chybove hlasenie
mov dx, offset error ;adresa textu chyboveho hlasenia
mov ah, 09h ;Instrukcia:Vypise retazec error
int 21h ;volanie funkcie dosu
ret
ENDP;=============Procedura ktora vypise chybove hlasenie
;--------------------------------------------------------------------------------------------------------------------------
Nuluj PROC;=============Procedura ktora vynuluje vysledky
mov vysledok_s[0], 0
mov vysledok_s[1], 0
mov vysledok_s[2], 0 ;Na vsetky vysledky vlozi 0
mov vysledok_s[3], 0
mov vysledok_s[4], 0
mov vysledok_d, 0h
ret
ENDP;=============Procedura ktora vynuluje vysledky
;----------------------------------------------------------------------------------------------------------------------
Prevod PROC near;=============Procedura ktora prevedie ASCII c. na 16bit. cislo
;v BX musi byt offset adresy cisla na prevod
xor dx, dx ;vynuluje register dx
mov cx, 10 ;do registra cx vlozi 10
Nacitaj: mov al, byte ptr[bx] ;vlozi prvy byt z registra bx do al
sub al, "0" ;odpocita 0 od cisla v al
cmp al, 10 ;porovna ci vznikol prenos
jnc skonci ;ak nie skonci
inc bx ;ak ano pokracuje vykona prenos do vyzsieho radu
push bx
mov bx, dx ;vlozi dalsiu cislicu
mov dx, 0
push cx ;uvolni miesto v zasobniku a potom na toto miesto zapise
Pridaj: add dx, bx ;pripocita k vyzsiemu radu obsah registra bx
loop pridaj ;odpocita jednotku a porovnava z nulou
mov bh, ch
pop cx ;ulozi 16 bit cislo do pamete aprdchadzajuce mieto uvolni
mov bl, al
add dx, bx
pop bx ;ulozi 16 bit cislo do pamete aprdchadzajuce mieto uvolni
jmp short nacitaj
Skonci: ret ;Vysledok sa nachadza v DX .
ENDP;=============Procedura ktora prevedie ASCII c. na 16bit. cislo
;................................................................................................................................................................
Prevod1 PROC near;=============Procedura ktora prevedie 16bit. cislo na ASCII cislo
;bx-sustava, ax-cislo
mov ax, vysledok_d ;cislo v 16 bit formate
xor si, si ;vynuluje register si
lea dx, vysledok_s ;prenos efektivnej adresi
mov bx, 10 ;vlozi sustavu (desiatkova)
push ax ;posunie cislo v zasobniku
xor cx, cx ;vynuluje register ccx
wn0: xor dx, dx ;vynuluje register dx
div bx ;deli registrom bx
push dx ;posunie cislo v zasobniku (skoci na dalsi bit)
inc cx
test ax, ax ;logicky porovna dva registre
jnz wn0 ;ak to nieje nula presun dalsi bit
wn2: pop dx ;ulozi hodnotu na zasobniku a zasobnik ukazuje spet na povodne miesto
or dl, '0' ;porovnava ci je vlozne cislo 0 alebo 9
cmp dl, '9'
jbe wn3 ;ak je cislo mensie ako 9 ukonci premenu
add dl, 7 ;ak nieje vykona prenos do dalsieho radu
wn3: mov vysledok_s[si], dl ;ulozenie vysledku
inc si
loop wn2 ;odcita jednotku a porovna z 0
pop ax ;ulozi hodnotu na zasobniku a zasobnik ukazuje spet na povodne miesto
ret
ENDP ;=============Procedura ktora prevedie 16bit. cislo na ASCII cislo
;-----------------------------------------------------------------------------------------------------------------------------------------
start:mov ax,@data ; zakladna adresa datoveho segmentu
mov ds,ax ; daj to do ds
mov ah,09h
mov dx,offset zac
int 21h
ZADAJ: mov ah,01h
int 21h
CMP AL,0DH
JE DALSI_RIADOK2
MOV SI,OFFSET SUBOR
ADD SI,ROZSAH
MOV [SI],AL
INC ROZSAH
JMP ZADAJ
DALSI_RIADOK2: MOV AX,@DATA ;PRESUNIE NA NOVY RIADOK
MOV DX,OFFSET RIADOK
MOV AH,09H
INT 21H
otvor_subor:
mov dx,OFFSET subor ; daj adresu file do dx
mov al,2 ; pristupovy mod - read and write
mov ah,3Dh ; funkcia 3Dh -open a file
int 21h ; zavolalo sa prerusenie
mov zdroj,ax ; uloz subor handle1 na neskor
NACITAJ_ZNAK: mov dx,offset Buffer ; daj adresu bufferu do dx
mov bx,zdroj ; daj handle1 do bx
mov cx,128 ; pocet bytov na citanie
mov ah,3Fh ; funkcia 3Fh - citaj zo suboru
int 21h ; zavolalo sa prerusenie
;=========Nacitanie zaciatku suboru.
mov dx, offset subor ;vlozenie retazca z adresou nazvu suboru do dx
mov al, 1 ;nastavenie suboru ,iba zapis
mov ah, 3dh ;Instrukcia:Otvorenie suboru
int 21h ;Vola funkciu dosu
mov zdroj,ax ;ulozi file handle otvoreneho suboru
;=========Rozhodovanie.
xor si, si ;vynuluje si
mov di, offset buffer ;adresu zaciatku zadania da do si
znovu: call nacitajc ;zavola proceduru na nacitanie prave pocitaneho prikladu
cmp cl, 045 ;porovna ci je v zadani prikladu znak -
mov znak, cl ;ulozi znak ktory tam je na miesto v pamati z nazvom znak
je odc ;ak je v cl znak - vykona skok na navestie scitaj
jmp A ;ak nie preskoci odcitanie
odc: call odcitanie ;zavola proceduru Na odcitanie dvoch cisel
jmp hodnot ;po scitany skoci na hodnotenie
A: cmp cl, 042 ;porovna ci je v zadani prikladu znak *
je nas ;ak je vykona proceduru ktora vynasobi 2 cisla
jmp B ;ak nie preskoci delenie
nas: call Nasobenie ;zavola proceduru Nasobenie.
jmp hodnot ;po deleni preskoci na hodnotenie
B: call chyba ;ak v zadani nieje ani + ani / zavola chybovu proceduru
jmp Shuttdown ;a skonci program
;=========Hodnotenie-vyber prikladov.
hodnot: mov bh, [di] ;nacita adresu prave zadavaneho prikaldu
cmp bh, 0 ;porovna ci nieje koniec retazca
je Shuttdown ;porovna a ak je 0 ukoci program
jmp znovu ;ak nieje nula skoci na dalsi priklad
;=========Ukoncenie programu. + autor
Shuttdown:
mov dx, offset autor ;ulozi adresu autorskeho textu do dx
mov ah, 09h ;Instrukcia:vypise na obrazovku retazec autor
int 21h ;Vola funkciu dosu
mov ax, 4c00h ;instrukcia na koniec programu
int 21h ;Vola funkciu dosu
END start ;koniec suboru pre asembler (1. instrukcia je na navesti start)