View Full Version : [assembler 8086] Aiuto calcolo media
pol88884
22-05-2009, 17:11
Ciao a tutti, sempre per quanto riguarda i problemi sull'assembler 8086, ho provato a fare questo esercizio, ma non esce.
Dice cosė:
- Scrivere un programma assembler che calcoli la media di 4 cifre (0..9) inserite in un vettore definito nel segmento dati.
Quando vado a vedere nel registro di AL mi da come risultato 0 invece di 4, mentre nel registro AH mi 66 invece di resto 0.
Dove sbaglio?
Questo č il codice:
; calcolo media di 4 cifre (0..9) inserite in un vettore definito nel segmento dati
data segment
numeri db 4 dup (2,2,2,2) ; cifre definite di cui calcolare la media
due db 1 dup(2); dividendo
somma db 0
data ends
code segment
assume CS:CODE,SS:STACK,DS:DATA
inizioprogramma:
MOV AX,DATA
MOV DS,AX
MOV AX,0; inizializzo ax
MOV SI,0; inizializzo il contatore si
MOV BX,offset numeri; carico l'offset nel vettore BX
sommatot:
CMP SI,4
JE dividi; se si e' uguale a 4 salta a dividi
MOV AL,byte ptr[bx+si] ; sposto i numeri a ogni ciclo in AX
ADD somma,AL;somma i quattro numeri definiti nel segmento dati
INC SI; incrementa il contatore si
JMP sommatot ;salta sempre a sommatot
dividi:
MOV AX,SOMMA; sposto il totale della somma in AX
DIV DUE ; divido AX:DUE
code ends
Ciao
Ho trovato i seguenti:
- Errore concettuale: Devi calcolare la media di 4 numeri e dividi per 2.
- memoria: Somma e' un byte solo, non puoi caricarlo in AX (e l'errore mi sa che deriva da qui) a meno che...
- logica: Perche' accumuli dentro "somma", invece che tenere direttamente dentro AL, ovviamente cambiando qualcosina, se li' ti serve alla fine per la divisione?
pol88884
23-05-2009, 22:07
Ciao ho provato a modificare quelle parti, ma mi da sempre numeri strani. In AH ora mi da 65 e in AL mi da 0.
Qui inserisco il codice:
; calcolo media di 4 cifre (0..9) inserite in un vettore definito nel segmento dati
data segment
numeri db 4 dup (2,2,2,2) ; cifre definite di cui calcolare la media
quattro db 1 dup(4); dividendo
data ends
code segment
assume CS:CODE,SS:STACK,DS:DATA
inizioprogramma:
MOV AX,DATA
MOV DS,AX
MOV AX,0; inizializzo ax
MOV SI,0; inizializzo il contatore si
MOV BX,offset numeri; carico l'offset nel vettore BX
sommatot:
CMP SI,4
JE dividi; se si e' uguale a 4 salta a dividi
ADD AL,byte ptr[bx+si] ; sommo i numeri
INC SI; incrementa il contatore si
JMP sommatot ;salta sempre a sommatot
dividi:
DIV quattro ; divido AX:QUATTRO
code ends
mi sa che e' sbagliata la dichiarazione degli array e dei valori.
Non usare dup, che non ti serve, semplicemente metti i valori che ti servono direttamente
numeri db 4,5,7,8
divisore db 4
dup serve per ripetere contenuti identici piu' volte, cosa che non dovrebbe appunto servirti (soprattutto per il divisore)
pol88884
24-05-2009, 17:42
Ho modificato quelle parti, ma non va. Ho notato comunque che in AL e in AH escono sempre gli stessi numeri ovvero 65 e 0 sia durante la somma che durante la divisione e anche cambiando i valori. Potrebbe essere che sbaglio a puntare a data?
Inserisco il codice:
; calcolo media di 4 cifre (0..9) inserite in un vettore definito nel segmento dati
data segment
numeri db 2,2,2,2 ; cifre definite di cui calcolare la media
quattro db 4; dividendo
data ends
code segment
assume CS:CODE,SS:STACK,DS:DATA
inizioprogramma:
MOV AX,DATA
MOV DS,AX
MOV AX,0; inizializzo ax
MOV SI,0; inizializzo il contatore si
MOV BX,offset numeri; carico l'offset nel vettore BX
sommatot:
CMP SI,4
JE dividi; se si e' uguale a 4 salta a dividi
ADD AL,byte ptr[bx+si] ; sommo i numeri
INC SI; incrementa il contatore si
JMP sommatot ;salta sempre a sommatot
dividi:
DIV quattro ; divido AX:QUATTRO
code ends
rеpne scasb
24-05-2009, 18:14
■
pol88884
25-05-2009, 10:41
Ciao ho applicato quella modifica:
; calcolo media di 4 cifre (0..9) inserite in un vettore definito nel segmento dati
data segment
numeri db 2,2,2,2 ; cifre definite di cui calcolare la media
quattro db 4; dividendo
data ends
code segment
assume CS:CODE,SS:STACK,DS:DATA
inizioprogramma:
MOV AX,DATA
MOV DS,AX
MOV AX,0; inizializzo ax
MOV SI,0; inizializzo il contatore si
MOV BX,offset numeri; carico l'offset nel vettore BX
sommatot:
CMP SI,4
JE dividi; se si e' uguale a 4 salta a dividi
ADD AL,byte ptr[bx+si] ; sommo i numeri
INC SI; incrementa il contatore si
JMP sommatot ;salta sempre a sommatot
dividi:
DIV ds:byte ptr[quattro] ; divido AX:QUATTRO
code ends
Ma comunque continua ad uscire il 65 in AL e mi da un messaggio di errore:
divide error - overflow.
to manually process this error,
change address of INT 0 in interrupt vector table
Prova a debuggare un po'
Ad esempio prova a vedere quanto vale AX prima della divisione,
poi prova a dividere direttamente per 4 invece che per una locazione di memoria, (ovvero puoi caricare direttamente 4 in un registro come CL e dividere per quello)
pol88884
25-05-2009, 11:00
Esce sempre 65 in AL e 0 in AH sia durante la somma che durante la divisione.
Esce sempre 65 in AL e 0 in AH sia durante la somma che durante la divisione.
Cosa vuol dire "esce"?
Cosa hai fatto per vedere in un qualunque momento il valore di AL e AH?
pol88884
25-05-2009, 11:27
Mi correggo vado nel menų debug e vedo singoli step per vedere i passaggi che fa il programma.
Nella finestra dei registri ho notato che non mi fa la somma tra le variabili, esce direttamente 70 in AL inserisco delle foto dei risultati:
http://img198.imageshack.us/my.php?image=debug2g.jpg
http://img5.imageshack.us/img5/2504/debug3b.jpg
qui invece va da 70 a 71:
http://img40.imageshack.us/img40/9340/debug4.jpg
infine nell'ultimo ciclo di ADD AL,byte ptr[bx+si] va direttamente a 65:
http://img38.imageshack.us/img38/1739/debug5.jpg
Non capisco il perchč
rеpne scasb
26-05-2009, 10:45
■
E' un po' che non scrivo direttamente codice ASM per DOS.
Ma non era
MOV AX,@Data
rеpne scasb
26-05-2009, 11:19
■
Vero (anche se e' possibile che qualche assemblatore rappresenti il segmento dati con 'DATA'), ma allora se la variabile DATA (non @DATA), non esiste come fa il linker a generargli l'eseguibile? Perche' vale 0h?
Magari esiste...
nel sorgente la prima parola e' proprio
data segment
e magari data senza @data vale 0, ovvero il primo indirizzo disponibile per i dati nel segmento, dato che non c'e' alcuna direttiva di spiazzamento (mi sembra fosse la direttiva org)
rеpne scasb
26-05-2009, 11:31
■
pol88884
26-05-2009, 16:12
Ciao, si chiama emu8086 (www.emu8086.com)
pol88884
27-05-2009, 16:34
Se non si conosce che tipo di assemblatore usa, si puo' dire tutto quello che si vuole. A naso direi di trasformare la riga:
Codice:
data segment
in
Codice:
data segment byte 'DATA'
Ho provato a sostituirla ma non cambia molto.
MOV AX,@Data
E questo l'hai provato?
pol88884
27-05-2009, 17:13
Si, ma il risultato non cambia.
Prova a fare qualche semplice tentativo...
prova programmi come
MOV ax,5
E vedere cosa c'e' in AX secondo il debugger.
Poi prova con
MOV ax, variabile
E di nuovo debugger.
pol88884
27-05-2009, 17:40
Nel primo caso va bene. Nel secondo caso invece esce sbagliato mi vale 0 AX.
pol88884
27-05-2009, 19:51
Mi correggo va anche nel secondo caso.
E allora prova la prima parte del tuo codice
MOV AX,DATA
MOV DS,AX
MOV AX,0; inizializzo ax
MOV SI,0; inizializzo il contatore si
MOV BX,offset numeri; carico l'offset nel vettore BX
MOV CL, [BX]
E guarda se tutto e' corretto
Poi continui cosi', aggiungi parti fino a che non trovi qual e' il pezzo che inspiegabilmente non funziona
pol88884
28-05-2009, 00:00
Grazie!!! ora il programma funziona :D
Grazie!!! ora il programma funziona :D
Eh!!!
Adesso pero' ci devi spiegare...
pol88884
28-05-2009, 11:21
Certamente :) , il problema era in questa parte di codice:
MOV BX,offset numeri; carico l'offset nel vettore BX
sommatot:
CMP SI,4
JE dividi; se si e' uguale a 4 salta a dividi
ADD AL,byte ptr[bx+si] ; sommo i numeri
INC SI; incrementa il contatore si
JMP sommatot ;salta sempre a sommatot
Non so il perchč ma non faceva la somma tra AL e i vettori e non inseriva l'offset in BX. Lo rivisto tutto e ho cambiato cosė:
; calcolo media di 4 cifre (0..9) inserite in un vettore definito nel segmento dati
stack segment
ends
data segment
valore db 2,2,2,2 ;cifre definite di cui calcolare la media
ends
code segment
assume ds:data,cs:code,ss:stack
start:
mov ax,data
mov ds,ax
mov es,ax
xor cx,cx; inizializzo cx,ax e si
xor ax,ax
xor si,si
inizioprogramma:
cmp si,4
je divisione ; se si e' uguale a 4 salta a dividi
mov al,valore[si] ; sposta in al il valore del vettore a ogni ciclo
add cl,al; fa la somma di ogni valore
inc si
jmp inizioprogramma
divisione:
mov al,cl ; sposta la somma nel divisore al
mov cl,4 ; divisore media
div cl; divido al:cl il risultato stara' in al e il resto in ah
ends
end start
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.