Divido il codice in più pezzi cosi ti possso spiegare meglio gli errori.
Dati segment (codice tuo)
DIVIDENDO DB 15H
DIVISORE DB 03H
RESTO DB ?
QUOZIENTE DB ?
Dati ends
Sistema segment stack
dw 100 dup(?)
top label word
Sistema ends
Codice segment
dati segment cosi come è non significa niente devi specificate il tipo in questo caso avresti dovuto specificare 'data'
non capisco a cosa ti serva lo stack visto che si definisce uno stack autonomo se o mi serve per passare parametri o se devo usare più segmenti codice cosa che non è specificata.
a che ti serve specificare la top label ?
normalmente la top label viene impostata automaticamente dalla direttiva . (processore) che oltre a definire le istruzioni valide predefinisce anche l'accesso hai segmenti.
la top label si mette quando io voglio specificare un organizzazione diversa dei segmenti ad esempio
.386 mi definisce in automatico l'accesso allo stack a 32bit tipo dati(dd alias dword) bene se voglio usare un accesso a 16bit tipo dati (dw alias word) allora uso la direttiva top label word.
comunque e meglio non usarla perchè ogni tanto da problemi con le istruzioni call.
consiglio al posto di usare lo statement nome segment tipo ti conviene usare
.data per il segmento dati
.code per il segmento codice
.stack per il segmento stack
Assume cs:Codice,ss:Sistema,ds:Dati,es:Dati
Inizio:;Inizializzazione dei registri di segmento
mov ax,Sistema
mov ss,ax
lea ax,top
mov sp,ax
mov ax,Dati
mov ds,ax
mov es,ax
allora qui c'è un errore di impostazione dei segmenti in quanto i registri ss,ds,es devono essere impostati con il segmento e non con il valore del registro.
per far giò devi usare la direttiva seg
avresti dovuto fare :
mov ax,seg sistema
mov ss,ax
mov ax,offset sistema
mov sp,ax
mov ax,seg dati
mov ds,ax
mov es,ax
nel blocco sotto ci sono degli errori logici
;Programma
MOV AL,DIVIDENDO
MOV RESTO,AL
MOV AH,DIVISORE
MOV BX,0
SALTO:
SUB DIVISORE,AL
INC BX
CMP RESTO,AH
JAE SALTO
MOV QUOZIENTE,BX
MOV AX,RESTO
prima di fare il programma perchè non cancelli tutti i registri che utilizzi?
sai con l'ambiente pulito si lavora meglio!
poi hai usato i registri nella maniera sbagliata perchè
hai definito DIVIDENDO DB 15H cioè hai definito una variabile lunga 15h avresti dovuto fare
dividendo equ 15h ; la differenza sta nel fatto che mentre io ho definito una costante tu hai definito una variabile molto lunga!
la stessa cosa avresti dovuto fare per divisore e cioè
divisore equ 03h
poi che senso ha fare mov resto,al se il resto non lo hai calcolato ?
il resto lo devi calcolare alla fine !
poi prima metti la condizione e poi effettui il calcolo!
comunque il programma andava fatto cosi!
.data
dividendo equ 15h
divisore equ 03h
resto db ?
quoziente db ?
.code
assume cs:@code,ds:@data
sottrazione proc near
inizio:
mov ax,@data
mov ds,ax
mov es,ax ; lo inserisco per il debug ma se non uso il debug potrei ampiamente farne a meno!
xor ax,ax ; cancella il registro ax a livello di cicli macchina e di codice operativo questo sistema e più conveniente rispetto hai suoi omologhi mov ax,0 sub ax,ax
xor bx,bx
mov al,divisore
mov ah,dividendo
salto:
cmp al,dh
jl fine
sub al,ah
inc bx
jmp short salto ; siccome stiamo internamente alla label di riferimento utilizzo la short per ridurre lo sviluppo dell' istruzione in fase di mopilazione.
fine:
mov byte ptr quoziente,bl
xor ax,ax
mov al,dividendo
sub al,bl
mov byte ptr resto,al
mov ax,4c00h
int 21h
sottrazione endp
end
comunque se vuoi usare la div ricordati questo:
il quoziente deve essere immesso nel registo ax
mentre il dividendo deve essere messo in un altro registro .
questo perche' al conterrà il quozioente mentre in ah ci sara il resto.
esempio
mov dl,5
mov al,16
div dl
alla fine delle 3 istruzioni
ah = 1 ; resto
al = 3 ; quoziente
mentre se invece facciamo una divisione a 16 bit
avremo ax = quoziente dx = resto