| Autore |
Discussione  |
|
|
maria lucia
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Canosa di Puglia
|
Inserito il - 12/01/2009 : 12:50:47
|
ciao a tutti, qualcuno è in grado di correggere gli errori che mi da questo programma scritto in linguaggio assembly? sostanzialmente gli errori riguardano l'uso delle scan_num e delle print_num, anche se non riesco a capire perchè non potrei usarle visto che le ho dichiarate nel mio programma :( grazie in anticipo a tutti coloro che proveranno ad aiutarmi ;)
TRACCIA:
scrivere un programma assembly che calcoli la media di 5 cifre inserite in un vettore definito nel segmento dati
------------data segment------------
pkey1 db "programma che calcola la media di 5 numeri inseriti in un vettore...$" pkey2 db "inserisci gli elementi:...$" pkey3 db "somma:...$" pkey4 db "media:...$" pkey5 db "numero pari...$" pkey6 db "numero dispari...$" vett db 5 dup(0) ;vettore di 5 elementi inizializzati a 0 elem dw 5 ;numero elementi vettore
------------code segment------------
start: ; set segment registers: mov ax, data mov ds, ax mov es, ax
; add your code here lea dx, pkey1 mov ah, 9 int 21h ; output string at ds:dx
;richiamo tutte le procedure in ordine call inserimento call somma call media call stampa proc inserimento
lea bx, vett ;assegno bx come indirizzo del vettore mov si, 0 ;inizializzo l'indice a 0 --> [bx+0] lea dx, pkey2 mov ah, 9 int 21h inserisci: call scan_num ;ERRORE!! ma visto che e' un vettore perche' non posso usarla? mov [bx+si], cl ;salvo il contenuto di cl nella prima locazione del vettore mov ah, 0eh mov al, 10d int 10h mov al, 13d int 10h inc si ;incremento l'indice --> [bx+1]....[bx+4] cmp si, elem ;gli elementi sono terminati? jz inserisci ;falso... ritorna all'inizio del ciclo ret
endp
proc somma mov ax, 0 ;azzero il registro ax...16 bit (8+8) mov al, [bx+0] ;al= al + 1^ numero add al, [bx+1] ;al= al + 2^ numero add al, [bx+2] ;al= al + 3^ numero add al, [bx+3] ;al= al + 4^ numero add al, [bx+4] ;al= al + 5^ numero lea dx, pkey3 mov ah, 9 int 21h call print_num ;ERRORE!! perche' non posso usarla visto che il ris l'ho salvato in ax? ret
endp
proc media mov bl, elem ;bl=5 div ax ;ax/bl call print_num ;ERRORE!! perche' non posso usarla visto che il ris l'ho salvato in ax? lea dx, pkey4 mov ah, 9 int 21h ret
endp
proc stampa cmp al, 0 ;resto=0? jz pari ;vero...allora il numero e' pari jnz dispari ;falso...allora il numero e' dispari pari: lea dx, pkey5 mov ah, 9 int 21h dispari: lea dx, pkey6 mov ah, 9 int 21h ret
endp
; wait for any key.... mov ah, 1 int 21h mov ax, 4c00h ; exit to operating system. int 21h ends
;definizione delle funzioni che sopra non riconosce :(
define_scan_num define_print_num define_print_num_uns define_pthis define_print_string
end start ; set entry point and stop the assembler.
|
|
|
maria lucia
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Canosa di Puglia
|
Inserito il - 12/01/2009 : 18:59:10
|
Rivedendo un attimino il programma mi sono accorta che andava cambiato qualcosa, anche se il problema rimane sempre lo stesso...uffi
!!! questa è l'idea del vettore che ho in mente:
vett | bx+0 | bx+1 | bx+2 | bx+3 | bx+4 | -->bx
------------data segment------------
pkey1 db "programma che calcola la media di 5 numeri inseriti in un vettore...$" pkey2 db "inserisci gli elementi:...$" pkey3 db "somma:...$" pkey4 db "media:...$" pkey5 db "numero pari...$" pkey6 db "numero dispari...$" vett db 5 dup(0) ;vettore di 5 elementi inizializzati a 0 elem db 5 ;numero elementi vettore somma db 0 ;variabile media db 0 ;variabile resto db 0 ;variabile
------------code segment------------
start: ; set segment registers: mov ax, data mov ds, ax mov es, ax
; add your code here lea dx, pkey1 mov ah, 9 int 21h ; output string at ds:dx
;richiamo tutte le procedure in ordine call inserimento call somma_num call media_num call stampa proc inserimento
lea bx, vett ;assegno bx come indirizzo del vettore mov si, 0 ;inizializzo l'indice a 0 --> [bx+0] lea dx, pkey2 mov ah, 9 int 21h inserisci: call scan_num ;ERRORE!! ma visto che e' un vettore perche' non posso usarla? mov [bx+si], cl ;salvo il contenuto di cl nella prima locazione del vettore mov ah, 0eh mov al, 10d int 10h mov al, 13d int 10h inc si ;incremento l'indice --> [bx+1]....[bx+4] cmp si, elem ;gli elementi sono terminati? jz inserisci ;falso... ritorna all'inizio del ciclo ret
endp
proc somma_num mov ax, 0 ;azzero il registro ax...16 bit (8+8) mov al, [bx+0] ;al= al + 1^ numero add al, [bx+1] ;al= al + 2^ numero add al, [bx+2] ;al= al + 3^ numero add al, [bx+3] ;al= al + 4^ numero add al, [bx+4] ;al= al + 5^ numero mov somma, al ;salvo il risultato della somma nella variabile somma
lea dx, pkey3 mov ah, 9 int 21h
mov ax, 0 mov ax, somma call print_num ;ERRORE!! perche' non posso usarla visto che il ris l'ho salvato in ax? ret
endp
proc media_num ;divisione = numero 16 bit / numero 8 bit ;dividendo in AX, divisore in un altro registro ;somma / elem
mov ax, somma ;dividendo somma mov bl, elem ;divisore media div bl ;quoziente in al e resto in ah mov media, al ;salvo il quoziente nella variabile mov resto, ah ;salvo il resto nella variabile
mov ax, 0 mov ax, media
call print_num ;ERRORE!! perche' non posso usarla visto che il ris l'ho salvato in ax? lea dx, pkey4 mov ah, 9 int 21h ret
endp
proc stampa mov ax, 0 mov ah, resto cmp ah, 0 ;resto=0? jz pari ;vero...allora il numero e' pari jnz dispari ;falso...allora il numero e' dispari pari: lea dx, pkey5 mov ah, 9 int 21h dispari: lea dx, pkey6 mov ah, 9 int 21h ret
endp
; wait for any key.... mov ah, 1 int 21h mov ax, 4c00h ; exit to operating system. int 21h ends
;definizione delle funzioni che sopra non riconosce :(
define_scan_num define_print_num define_print_num_uns define_pthis define_print_string
end start ; set entry point and stop the assembler.
|
Modificato da - maria lucia in data 12/01/2009 18:59:50 |
 |
|
|
jwein
Utente giovane

|
Inserito il - 13/01/2009 : 17:32:17
|
Ciao, che errore ti dà precisamente ? E' un errore di compilazione o di esecuzione ?
Ho letto il codice, ma purtroppo è molto difficile capire il codice scritto da altri, soprattutto se in assembly.
Ho notato però che per settare un registro a zero tu usi mov registro, 0 .. Ti consiglio di usare xor registro, registro ( tra se stesso ) in quanto è più veloce ( opera su bit paralleli ) ed è meglio visto dai professori...
Inoltre tu fai spesso assegnazioni tra variabili o registri di dimensione diversa. Sull'emu8086 che utilizziamo in laboratorio forse viene anche compilato, ma è considerato errore da chi corregge. Io ho la nuova versione dell'emu8086 e non mi compilava il tuo codice per questo motivo. Se devi fare una operazione del tipo mov ax, variabile ( dove variabile è di tipo db ) fai piuttosto: xor ax, ax ( lo setti a zero ) e in seguito: mov al, variabile. In questo modo fai una assegnazione tra singole locazioni di memoria di 8 bit.
Spero di averti aiutata un po', se ci scrivi che errore ti dà il compilatore o cosa accade di sbagliato possiamo darti una mano...
Ciao! |
 |
|
|
maria lucia
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Canosa di Puglia
|
Inserito il - 13/01/2009 : 17:48:11
|
------------------------------------------------- Ciao, che errore ti dà precisamente ? E' un errore di compilazione o di esecuzione ? ------------------------------------------------- l'errore è di compilazione
------------------------------------------------- Ho notato però che per settare un registro a zero tu usi mov registro, 0 .. Ti consiglio di usare xor registro, registro ( tra se stesso ) in quanto è più veloce ( opera su bit paralleli ) ed è meglio visto dai professori... ------------------------------------------------- si certo, seguirò il tuo consiglio :) al posto di scrivere: mov ax, 0 si dovrebbe scrivere: xor ax, ax
------------------------------------------------- Inoltre tu fai spesso assegnazioni tra variabili o registri di dimensione diversa. Sull'emu8086 che utilizziamo in laboratorio forse viene anche compilato, ma è considerato errore da chi corregge. Io ho la nuova versione dell'emu8086 e non mi compilava il tuo codice per questo motivo. Se devi fare una operazione del tipo mov ax, variabile ( dove variabile è di tipo db ) fai piuttosto: xor ax, ax ( lo setti a zero ) e in seguito: mov al, variabile. In questo modo fai una assegnazione tra singole locazioni di memoria di 8 bit. ------------------------------------------------- ti riferisci a questo tipo di procedere?
mov ax, somma ;dividendo somma mov bl, elem ;divisore media
------------------------------------------------- Spero di averti aiutata un po', se ci scrivi che errore ti dà il compilatore o cosa accade di sbagliato possiamo darti una mano...
Ciao! ------------------------------------------------- grazie mille :) sei stato davvero gentilissimo ;) provo a modificare questa versione e vi farò sapere ;) |
 |
|
|
jwein
Utente giovane

|
Inserito il - 13/01/2009 : 17:59:57
|
Ciao! Sì, mi riferisco a quel tipo di operazioni.. Ho provato a compilare il tuo programma, e a parte gli errori dovuti al mov fatto tra locazioni di memoria di dimensione diversa non ho avuto problemi. Non è che non hai aggiunto include 'emu8086.inc' all'inizio di tutto il codice ? E' la libreria fondamentale.. Li sono definite le procedure.. Quando ti dà l'errore di compilazione cosa ti dice esattamente ? (Nella finestrella che si apre) |
Modificato da - jwein in data 13/01/2009 18:09:39 |
 |
|
|
maria lucia
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Canosa di Puglia
|
Inserito il - 13/01/2009 : 19:28:18
|
ho applicato le tue modifiche al mio programma...
1) ho inserito l'include 'emu8086.inc' che avevo dimenticato e ora compila;
2) ho moficato le istruzioni mov ax, 0 sostituendole con xor ax, ax
3) ora però mi dà un problema riguardo questo pezzo di codice:
Immagine:
 35,92 KB |
Modificato da - maria lucia in data 13/01/2009 19:32:47 |
 |
|
|
jwein
Utente giovane

|
Inserito il - 13/01/2009 : 21:10:47
|
Ciao! No.. Si riferisce a 'cmp si, elem'.
Ricorda che i registri della CPU 8086 sono a 16 bit.. SI è a 16 bit, elem è stata probabilmente dichiarata come db (giusto?). Quindi tu stai facendo una operazione che coinvolge un registro che è a 16 bit e una variabile che è a 8 bit e ciò dà errore. Per risolvere ci sono vari modi. Potresti portare la variabile elem dal tipo 'db' al tipo 'dw', ma non è la cosa ideale in quanto diventerebbe di 16 bit e sprecherebbe solo spazio aggiuntivo nel segmento dati.
Io ti consiglierei di fare una cosa del genere:
xor dx, dx ; azzero un registro generico
mov dl, elem ; copio nella sua parte bassa il valore di elem
cmp si, dx ; faccio il controllo tra SI e il registro
E' un po' il metodo di cui ti avevo parlato prima. Puoi fare operazioni solo tra variabile / registri della stessa dimensione. Quindi quando hai errori di questo tipo ( 'operands do not match' ) ricordati che puoi risolvere in modo molto semplice azzerando un qualsiasi registro tra quelli che non stai usando, copiando nella parte bassa di questo registro il valore della variabile ( in questo modo è come se copiassi NELLA META' di un registro a 16 bit, e quindi di fatto in un registro a 8 bit, il contenuto della variabile a 8 bit e quindi l'operazione è consentita ), e in seguito fai il controllo tra il registro a 16 bit e l'altro registro a 16 bit dove hai copiato il valore ( tanto, dato che l'hai messo nella parte bassa, quando poi vai a prendere l'intero registro il valore è identico in quanto i bit vengono allineati a destra ).
E' molto più facile a farsi che a dirsi :) Se ci sono altri problemi non esitare a chiedere ;) |
Modificato da - jwein in data 13/01/2009 21:14:09 |
 |
|
|
battistis
Utente Nonno
   

Regione: Friuli-Venezia Giulia
Prov.: Verbano-Cusio-Ossola
Città: inCentroConPassAuto
|
Inserito il - 14/01/2009 : 14:15:19
|
da un amigo nn iscritto che leggeva questa disc.
Citazione:
Io ti ho detto che ho programmato per anni in assembler...ma su Microchip, non su intel... Su intel ci ho anche programmato, ma anni e anni fa... Comunque io ritengo che mov [bx+si], cl non sie errato, perché, anche se ciò che è tra quadre è a 16bit (come DEVE essere), quello che segue può essere a 8, anzi, DEVE, perché ciò che c'è tra parentesi è un indirizzo... Semmai il problema è che non puoi fare quella somma li,dentro quella parentesi...io proverei a fare la somma di BX ed SI separatamente su DI (se non sbaglio)...ma ti devi rivedere i registri dell'8086, non me li ricordo, sono tanti anni che non li uso... Auf Wiedersehen!
|
battistis[d0t]altervista[d0t]org |
 |
|
|
jwein
Utente giovane

|
Inserito il - 14/01/2009 : 15:39:46
|
Ciao, beh non abbiamo mai detto che non si possa fare. E' ovvio che possono essere eseguite operazioni tra locazioni di memoria (e su sistemi intel le locazioni di memoria sono, in genere, di 8 bit) e metà di registri a 16 bit (quindi, ancora, 8 bit).
Non capisco cosa voglia dire il tuo amico, anche perchè il problema è, penso, stato risolto e lui ha probabilmente letto la discussione molto di fretta.
L'operazione di cui parla (mov [bx+si], cl) può tranquillamente essere fatta, mai detto o pensato qualcosa in contrario. Inoltre la somma all'interno della parentesi in stile [bx+si] può essere fatta senza alcun problema su compilatori moderni e in particolar modo sull'emu8086 (che riprende la sintassi del fasm). Inoltre non capisco che senso abbia fare la somma separatamente, su un altro registro, poi (DI...). L'ottimizzazione va un po' a farsi fottere :)
E' chiaro poi che ogni compilatore presenta una sintassi leggermente diversa, su compilatori per microchip probabilmente sarà diverso. Tra l'altro il problema è, penso, stato risolto, non capisco il senso del messaggio, sinceramente :)
Ciao! |
Modificato da - jwein in data 14/01/2009 15:49:43 |
 |
|
|
maria lucia
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Canosa di Puglia
|
Inserito il - 14/01/2009 : 16:25:23
|
ciao a tutti....bhè che dire....vi ringrazio....ora il programma funziona 
|
 |
|
|
jwein
Utente giovane

|
Inserito il - 14/01/2009 : 17:13:03
|
| Ciao! Di niente, mi fa piacere che hai risolto ;) |
 |
|
| |
Discussione  |
|
|
|