Stránka 1 z 1

Assembler-8086

Napsal: stř 12. led 2005, 23:51
od kovino
Caute chlapi, mam jeden pre mna dost velky problem, mam spravit nasledovny program:

Najdite pocet zapornych prvkov hlavnej diagonaly matice A(M,N), ak je matica ulozena po riadkoch a prvky matice su 16 bit cisla so znamienkom.

Ma to byt pre procak typu 8086. Neviem si s tym rady, viem, je to roboty na par hodin, ale nejaky frajer co to ma v malicku sa tu mozno najde. Inak tu je program, ktory zisti pocet zapornych prvkov v celej matici, ja potrebujem len na hlavnej diagonale, tak ak by sa na to niekto mrkol a upravil to, ak sa da, tak mu vopred velmi dakujem. Upraveny program moze dat sem na forum alebo poslat mi ho na mail, este raz vdaka, ja som v koncoch.

prog segment
.386
assume cs: prog, ds: prog
org 100h
vtext macro xx ;makro na vypis textu
mov ah,9 ;funkcia dosu na vypis textu na obrazovku
mov dx,offset xx ;adresa vypisu
int 21h ;volanie funkcie
endm ;koniec makra
vznak macro xx ;makro na vypis znaku
mov ah,2 ;funkcia dosu na vypis znaku na obrazovku
mov dl,xx ;nastavenie textu vypisu
int 21h ;volanie funkcie
endm ;koniec makra

zac: ;zaciatok programu
mov ax,3 ;zmazanie obrazovky
int 10h
vtext uvod ;vypis uvodu programu
call nacm ;nacitanie poctu riadkov v matici
mov m,ax ;odlozenie do pamate
call nacn ;nacitanie poctu stlpcov v matici
mov n,ax ;odlozenie do pamate
mov stlpec,1 ;nastavenie na prvy riadok
mov cx,n ;nastavenie pocitadla na pocet riadkov
mov si,0 ;nastavenie na prvy prvok v matici
dalst:
push cx ;odlozenie pocitadla
mov cx,m ;nastavenie pocitadla na pocet prvkov v stlpci
mov riadok,1 ;nastavenie na prvy riadok
dalx:
push cx ;odlozenie pocitadla stlpcov
call nacx ;nacitanie x
mov mat+[si],ax ;ulozenie ax do matice
add si,2 ;nastavenie na dalsie cislo
inc riadok ;nastavenie na dalsi stlpec
pop cx ;obnovenie pocitadla stlpcov
loop dalx ;dalsie_cislo
pop cx ;obnovenie pocitadla
inc stlpec ;nastavenie na dalsi riadok
loop dalst ;dalsi riadok
call vypis_maticu ;vypisanie matice
call najdi_kladne ;najdenie poctu poczap prvkov
vtext otdal ;vypis otazky o pokracovani
dalmat:
mov ah,8 ;funkcia dosu pre nacitanie znaku bez echa
int 21h ;volanie funkcie
cmp al,'a' ;je to znak a?
jz nmat ;ano, skok na zaciatok
cmp al,'A' ;je to znak A?
jz nmat ;ano, skok na zaciatok
cmp al,'n' ;je to znak n?
jz koniec ;ano, skok na koniec
cmp al,'N' ;je to znak N?
jz koniec ;ano, skok na koniec
jmp dalmat ;dalsi znak
nmat:
vznak al ;vypis znaku na obrazovku
jmp zac ;skok na zaciatok
koniec:
vznak al ;vypis znaku na obrazovku
vtext zaver ;vypis zaveru
mov ax,4c00h ;ukoncenie programu
int 21h ;volanie funkcie

nacm: ;podprogram pre nacitanie poctu riadkov
vtext nacm1 ;vypis uvodu nacitania m
call nuluj_buffer ;nulovanie buffera
mov si,0 ;nastavenie na prvy znak
vstm:
call nacitaj_znak ;nacitanie znaku
inc si ;nastavenie na dalsi znak
cmp al,13 ;bol enter?
jz testm ;ano, skok na test
cmp si,2 ;boli zadane 2 znaky?
jz testm ;ano skok na test
jmp vstm ;dalsi znak
testm:
call prevod_do_ax ;prevod cisla z buffera do ax
cmp ax,0 ;je cislo zaporne alebo rovne 0?
jbe zlem ;ano, skok na opatovne zadanie
cmp ax,10 ;je cislo vacsie ako 10?
jg zlem ;ano, skok na opatovne zadanie
retn ;navrat
zlem:
vtext nacm2 ;vypis upozornenia na rozsah
jmp nacm ;skok na dalsie nacitanie

nacn: ;podprogram pre nacitanie poctu stlpcov
vtext nacn1 ;vypis uvodu nacitania m
call nuluj_buffer ;nulovanie buffera
mov si,0 ;nastavenie na prvy znak
vstn:
call nacitaj_znak ;nacitanie znaku
inc si ;nastavenie na dalsi znak
cmp al,13 ;bol enter?
jz testn ;ano, skok na test
cmp si,2 ;boli zadane 2 znaky?
jz testn ;ano skok na test
jmp vstn ;dalsi znak
testn:
call prevod_do_ax ;prevod cisla z buffera do ax
cmp ax,0 ;je cislo zaporne alebo rovne 0?
jbe zlen ;ano, skok na opatovne zadanie
cmp ax,10 ;je cislo vacsie ako 10?
jg zlen ;ano, skok na opatovne zadanie
retn ;navrat
zlen:
vtext nacn2 ;vypis upozornenia na rozsah
jmp nacn ;skok na dalsie nacitanie

nacx: ;podprogram pre nacitanie x
push si ;odlozenie si
push cx ;odlozenie cx
nacxz:
vtext nacx1 ;vypis uvodu nacitania x
mov ax,riadok ;aktualny riadok
call decwr ;vypis
vtext nacx2 ;vypis stredu nacitania x
mov ax,stlpec ;aktualny stlpec
call decwr ;vypis
vtext nacx3 ;vypis zaveru nacitania
call nuluj_buffer ;nulovanie buffera
mov si,0 ;nastavenie na prvy znak
vstx:
call nacitaj_znak ;nacitanie znaku
inc si ;nastavenie na dalsi znak
cmp al,13 ;bol enter?
jz testx ;ano, skok na test
cmp si,7 ;bolo zadanych 7 znakov?
jz testx ;ano skok na test
jmp vstx ;dalsi znak
testx:
push si ;odlozenie poctu zadanych znakov
mov si,0 ;nastavenie na prvy znak
mov al,buffer+[si] ;nacitanie prveho znaku
cmp al,'-' ;je zadane cislo zaporne?
jz testzapp ;ano skok na test zaporneho cisla
pop si ;obnovenie poctu zadanych znakov
cmp si,6 ;bolo zadanych 5 znakov?
jz testkladd ;ano, skok na podrobne porovnanie
jg zlex ;ak viac ako 5 znakov
okx:
call prevod_do_ax ;prevod cisla z buffera do ax
pop cx ;obnovenie hodnoty cx
pop si ;obnovenie hodnoty si
retn ;navrat
zlex:
vtext nacx4 ;vypis upozornenia na rozsah
jmp nacxz ;skok na dalsie nacitanie
testzapp:
pop si ;obnovenie poctu zadanych znakov
cmp si,7 ;bolo zadanych 6 znakov?
jz testzapp_p ;ano, skok na podrobne porovnanie
jg zlex ;ak viac ako 6 znakov
jmp okx ;cislo ma menej ako 6 znakov
testkladd:
mov cx,si ;nastavenie pocitadla na zadany pocet znakov
mov si,0 ;nastavenie na prvy znak
horna_hranica:
mov al,buffer+[si] ;vyber z buffera
mov bl,hhran+[si] ;vyber z hornej hranice
cmp al,bl ;porovnanie cislic
jc okx ;cislo je mensie ako horna hranica
jz dalej_horna ;cislice su rovne
jmp zlex ;cislo je vacsie ako hranica
dalej_horna:
inc si ;nastavenie na dalsi znak
loop horna_hranica ;dalsi znak
jmp okx ;cislo sa rovna hornej hranici
testzapp_p:
mov cx,si ;nastavenie pocitadla na zadany znakov
mov si,0 ;nastavenie na prvy znak
dolna_hranica:
mov al,buffer+[si] ;vyber z buffera
mov bl,dhran+[si] ;vyber z dolnej hranice
cmp al,bl ;porovnanie cislic
jc okx ;cislo je vacsie ako dolna hranica
jz dalej_dolna ;cislice su rovne
jmp zlex ;cislo je mensie ako dolna hranica
dalej_dolna:
inc si ;nastavenie na dalsi znak
loop dolna_hranica ;dalsi znak
jmp okx ;cislo sa rovna dolnej hranici

nacitaj_znak: ;podprogram pre nacitanie znaku z klavesnice a jeho ulozenie na aktualnu poziciu v bufferi urcenu v si
mov ah,8 ;funkcia dosu pre nacitanie znaku bez echa
int 21h ;volanie funkcie
cmp si,0 ;je to prvy znak?
jz testminus ;ano, skok na test ci nebol zadany znak minusu
cmp al,13 ;je to enter?
jz znak_ok ;ano
test_znaku:
cmp al,'0' ;je to znak 0?
jz znak_ok ;ano
cmp al,'1' ;je to znak 1?
jz znak_ok ;ano
cmp al,'2' ;je to znak 2?
jz znak_ok ;ano
cmp al,'3' ;je to znak 3?
jz znak_ok ;ano
cmp al,'4' ;je to znak 4?
jz znak_ok ;ano
cmp al,'5' ;je to znak 5?
jz znak_ok ;ano
cmp al,'6' ;je to znak 6?
jz znak_ok ;ano
cmp al,'7' ;je to znak 7?
jz znak_ok ;ano
cmp al,'8' ;je to znak 8?
jz znak_ok ;ano
cmp al,'9' ;je to znak 9?
jz znak_ok ;ano
jmp nacitaj_znak ;bol zadany chybny znak, skok na nacitanie dalsieho
testminus:
cmp al,'-' ;je to znak -?
jz znak_ok ;ano
jmp test_znaku ;nie, skok na dalsi test
znak_ok:
mov buffer+[si],al ;ulozenie do buffera
vznak al ;vypis znaku na obrazovku
retn ;koniec nacitania, cislo je ulozene v bufferi

prevod_do_ax: ;podprogram na prevod cisla ulozeneho po znakoch v bufferi na 16b cislo so znamienkom ulozene v ax
mov si,0 ;nastavenie na prvy prvok buffera
mov ax,0 ;pociatocne nastavenie ax
mov bh,0 ;nulovanie hornych 8b bx
mov bl,buffer+[si] ;nacitanie prveho znaku
cmp bl,'-' ;je cislo zaporne?
jz zaporne_cislo1 ;ano
dalsia_cislica:
mov bl,buffer+[si] ;nacitanie cislice
cmp bl,13 ;je to enter?
jz koniec_cisla ;ano
mov dx,10 ;konstanta pre nasobenie
mul dx ;vynasobenie ax desiatimi (dalsi rad)
sub bl,'0' ;v bl je teraz hodnota cislice
add ax,bx ;pripocitanie dalsieho radu
inc si ;nastavenie na dalsiu cislicu
jmp dalsia_cislica ;skok na spracovanie dalsej cislice
zaporne_cislo1:
inc si ;preskocenie znamienka a nastavenie na prvu cislicu
jmp dalsia_cislica ;skok na spracovanie dalsej cislice
koniec_cisla:
mov si,0 ;nastavenie na prvy znak cisla
mov bl,buffer+[si] ;nacitanie prveho znaku
cmp bl,'-' ;je cislo zaporne?
jz zaporne_cislo2 ;ano
koniec_prevodu:
retn ;koniec prevodu, cislo je v ax
zaporne_cislo2:
mov bx,ax ;odlozenie cisla do bx
mov ax,0 ;nastavenie ax na nulu
sub ax,bx ;vysledkom je zaporne cislo
retn ;koniec prevodu, cislo je v ax

nuluj_buffer: ;podprogram na nulovanie obsahu buffera
push si ;odlozenie hodnoty si
mov si,0 ;nastavenie na prvy znak
mov cx,6 ;nastavenie poctu znakov
nuluj_dalsi:
mov buffer+[si],13 ;nulovanie buffera
inc si ;nastavenie na dalsi znak
loop nuluj_dalsi ;dalsi znak
pop si ;obnovenie hodnoty si
retn ;navrat

vypis_maticu: ;podprogram pre vypis matice
vtext vypmat1 ;vypis uvodu
mov stlpec,0 ;nastavenie na prvy stlpec
mov cx,m ;nastavenie pocitadla na pocet riadkov
dalsi_riadok_vypis:
push cx ;odlozenie pocitadla
mov cx,n ;nastavenie pocitadla na pocet prvkov riadku
mov si,stlpec ;nastavenie na prvy prvok v stlpci
vtext vypmat2 ;novy riadok
dalx_vypis:
push cx ;odlozenie pocitadla stlpcov
mov ax,mat+[si] ;nacitanie do ax z matice
call dec_vypis ;vypis prvku matice
pop cx
push cx
cmp cx,1
jz bez_ciarky
vtext vypmat4
bez_ciarky:
add si,m ;nastavenie na dalsie cislo
add si,m
pop cx ;obnovenie pocitadla stlpcov
loop dalx_vypis ;dalsie_cislo
add stlpec,2 ;nastavenie na dalsi riadok
pop cx ;obnovenie pocitadla
loop dalsi_riadok_vypis;dalsi riadok
retn ;navrat

najdi_kladne: ;podprogram pre najdenie poctu poczap prvkov
mov poczap,0 ;nulovanie najdenych cisel
vtext vyppoc ;vypis uvodu
mov riadok,0 ;nastavenie na prvy riadok
mov cx,m ;nastavenie pocitadla na pocet riadkov
dalsi_riadok_hladaj:
push cx ;odlozenie pocitadla
mov cx,n ;nastavenie pocitadla na pocet prvkov v riadku
mov si,0 ;nastavenie na prvy prvok v riadku
mov stlpec,1 ;nastavenie ukazovatela stlpca
dalx_hladaj:
push cx ;odlozenie pocitadla stlpcov
push riadok ;odlozenie aktualneho riadka
mov ax,riadok ;do ax dame riadok aby sme ho mohli vynasobit
mov bx,n ;nasobime poctom stlpcov
mul bx ;nasobenie
mov bx,2 ;nasobenie 2 pretoze cisla su 16b
mul bx ;nasobenie
mov riadok,ax ;teraz riadok ukazuje na zaciatok riadka
mov di,si ;odlozenie ukazovatela
add si,riadok ;teraz riadok ukazuje na prvok
mov ax,mat+[si] ;nacitanie do ax z matice
cmp ax,0 ;je v ax zaporne cislo?
jge najdi_dalej ;ano
inc poczap
najdi_dalej:
mov si,di ;obnovenie ukazovatela
add si,2 ;nastavenie na dalsie cislo
pop riadok ;obnovenie aktualneho riadku
pop cx ;obnovenie pocitadla stlpcov
inc stlpec ;dalsi stlpec
loop dalx_hladaj ;dalsie_cislo
pop cx ;obnovenie pocitadla
inc riadok ;nastavenie na dalsi riadok
loop dalsi_riadok_hladaj;dalsi riadok
mov ax,poczap ;presun do registra na vypis
call dec_vypis; ;vypis
retn ;navrat



dec_vypis: ;podprogram pre vypis dekadickej hodnoty v ax
mov cx,0 ;nastavenie pocitadla
push ax ;odlozenie eax
and ax,8000h ;extrakcia znamienka
cmp ax,8000h ;je cislo zaporne?
jz decwr_zaporne ;ano, skok na vypis zaporneho cisla
pop ax
call decwr ;vypis cisla
mov cx,7 ;chceme vypisat kazde cislo na 7 znakov
sub cx,bx ;kolko znakov chyba?
decwrk:
mov dx,' ' ;vypis medzier na konci
mov ah,2 ;funkcia dosu pre vypis znaku
int 21h ;volanie funkcie
loop decwrk ;dalsia medzera
retn ;navrat
decwr_zaporne:
vtext vypmat3 ;vypis minusu
pop ax ;obnovenie eax
mov bx,ax ;odlozenie eax, do ebx
mov ax,0 ;nastavenie eax na nulu
sub ax,bx ;v eax je je kladne cislo
call decwr ;vypis cisla
mov cx,6 ;chceme vypisat kazde cislo na 7 znakov (minus)
sub cx,bx ;kolko znakov chyba?
decwrz:
mov dx,' ' ;vypis medzier na konci
mov ah,2 ;funkcia dosu pre vypis znaku
int 21h ;volanie funkcie
loop decwrz ;dalsia medzera
retn ;navrat
decwr: ;podprogram na vypis dekadickej hodnoty
mov bx,10 ;konstanta, ktorou budeme delit.
xor cx,cx ;pocitadlo urcujuce pocet cislic cisla
decwr1:
xor edx,edx ;nulujeme hornu cast reg.paru EDX:ax (len ax)
div bx ;celociselne delenie cislom 10 (zvysok=cislica)
add dl,'0' ;menime zvysok na ascii hodnotu cislice
push dx ;ukladame do zasobnika (opacne poradie)
inc cx ;zvacsujeme pocet nami zistenych cislic cisla
or ax,ax ;zistujeme, ci mame uz v zasobniku vsetky cislice
jnz decwr1 ;ak nie, potom opakujeme cyklus
mov bx,cx ;ulozenie poctu vypisanych cislic
decwr2:
pop dx ;vyber cislice zo zasobnika
mov ah,2 ;funkcia dosu pre vypis znaku
int 21h ;volanie funkcie
loop decwr2 ;dalsia cislica
retn ;navrat

uvod db 10,13,' Matica 16b cisel so znamienkom ',10,13,'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$'
zaver db 10,13,10,13,'Koniec programu!$'
nacm1 db 10,13,10,13,'Zadaj pocet riadkov matice : $'
nacm2 db 10,13,'Cislo musi byt v rozsahu 1 az 10!$'
nacn1 db 10,13,'Zadaj pocet stlpcov matice : $'
nacn2 db 10,13,'Cislo musi byt v rozsahu 1 az 10!$'
nacx1 db 10,13,'Zadaj prvok A($'
nacx2 db ',$'
nacx3 db ') : $'
nacx4 db 10,13,'Cislo musi byt v rozsahu -32767 az 32767!$'
vypmat1 db 10,13,10,13,'Matica :$'
vypmat2 db 10,13,' $'
vypmat3 db '-$'
vypmat4 db ' , $'
vyppoc db 10,13,'Pocet zapornych prvkov v matici : $'
otdal db 10,13,'Dalsiu maticu?(a/n)$'
hhran db '32767',13
dhran db '-32767',13
buffer db 8,0,9 dup(0)
m dw 0
n dw 0
riadok dw 0
stlpec dw 0
poczap dw 0
mat dw 100,0,100 dup(0)
prog ends
end zac

Napsal: čtv 13. led 2005, 17:30
od pavel.minarik
nestačí rada: "vycházej z toho, že prvek na hlavní diagonále má souřadnici n,n kde n je počet řádků respektive sloupců matice"?