Discussione Multidefined Symbol error A2005 MAMS 5.0

mattstack

Utente Bronze
1 Aprile 2021
62
19
12
46
Ciao sono nuovo su questo forum.
Stavo scrivendo delle macro molto semplici per la gestione dell' I/O, le varie etichette che ho definito in queste macro sono state definite locali, tramite la direttiva LOCAL, quindi non ci dovrebbe essere nessun problema di etichette "multidefinite" eppure ecco i soliti errori a cui non so dare risposta.
Codice:
input_int MACRO register
        
      LOCAL  input, continue

      ....... ;code

ENDM
Quando la macro viene estesa l'eticchette dovrebbero "espandersi" in modo diverso a ogni espansione della macro, allora perchè questo errore?
 
Ciao, dovresti dare più contesto. L'errore a cosa fa riferimento di preciso? Riporta il codice della macro per intero (l'intero codice, sarebbe ancora meglio).

Comunque si, vediamo come hai scritto il codice, ma ad ogni chiamata l'indirizzo dell'etichetta cambia.
 
Ultima modifica:
Ciao, dovresti dare più contesto. L'errore a cosa fa riferimento di preciso? Riporta il codice della macro per intero (l'intero codice, sarebbe ancora meglio).

Comunque si, vediamo come hai scritto il codice, ma ad ogni chiamata l'indirizzo dell'etichetta cambia.
scusa effettivamente sono stato troppo sintetico.
Codice:
input_int MACRO register

        LOCAL input, continue, stop_input

        push    ax
        push    cx
        push    bx

        mov     cx, 5

        input: mov   ah, 01h
               int   21h
               xor   ah, ah

               cmp   al, 13
               jne   continue

               mov   ax, register
               mov   bx, 10
               div   bx
               mov   register, ax
               pop   bx
               pop   cx
               pop   ax

               jmp   stop_input

               continue: cmp   al, 48
                         jb    stop

                         cmp   al, 57
                         ja    stop

                         sub   al, 48
                         add   register, ax
                         mov   ax, 10
                         mul   register
                         mov   register, ax
                         xor   ax, ax

                         loop  input
                         pop     bx
                         pop     cx
                         pop     ax
     
        stop_input: nop
ENDM

stack SEGMENT PARA STACK
     
        db      ?

stack ENDS

data SEGMENT PARA PUBLIC

        db     ?

data ENDS

code SEGMENT PARA PUBLIC     

        ASSUME ss: stack, ds: data, cs: code

_start:
        ;load the DS
        mov     ax, data
        mov     ds, ax

        ;input1
        input_int bx
   
        ;input msg2
        input_int dx

        stop: mov   ah, 04ch
              mov   al, 1
              int   21h

code ENDS    
        END _start
Ecco l'intero codice.
Ecco l'errore: Erorr A2005 multidefined symbol
 
Ultima modifica:
A vista non vedo problemi, ho provato ad assemblare con MASM 6.0, e non ho problemi nè assemblando nè linkando.
Ci sono nell'esecuzione però. Non mi è nuovo quel codice...

Ad ogni modo un errore è qui:

Codice:
sub   al, 48
add   register, ax
mov   ax, 10
mul   register
mov   register, ax

in quanto prima devi moltiplicare e poi sommare il carattere inserito.

Anche il push/pop di tutti quei registri non mi è del tutto chiaro. Il valore di AX non ti serve preservarlo ad esempio.
Inoltre register e bx sono la stessa cosa (o meglio: register è bx subito dopo la compilazione). Quindi quando viene eseguito il POP perdi il valore immesso in input.

Ti conviene usare una variabile nella quale mantieni la somma di ogni numero immesso in input.
Se vuoi memorizzare N valori, allora dovrai allocare N dw nel blocco DATA, tipo:

Codice:
array     dw  10   dup(?)   ; 10 elementi con dimensione dw

Ad ogni modo hai anche a disposizione altri registri che non utilizzi, che sono SI e DI.
 
  • Mi piace
Reazioni: ZiFF°A
Ultima modifica:
Se moltiplico prima e poi sommo, da quel che ho provato, bx(registro contenente l'input) non conterrà il valore giusto.

al = 49-48 = 1
al*10 = 10
ah = 0 ;azzero ah così da potere memorizzare 16bit in bx non avendo problemi con la parte alta di ax
bx += ax

bx a questo punto è = 10

al = 50-48 = 2
al*10 = 20
ah = 0
bx += ax

bx a questo punto è = 30

Non capisco cosa intendi
 
Supponiamo che tu voglia inserire in input il valore 49.
Il registro che contiene il numero sarà inizialmente a 0 (diciamo bx=0).

Digiti '4'. Converti in numero, quindi '4' - '0' = 4.
Bx = 0; quindi farai bx*10=0 + 4.

Inserisci il numero '9', (e fai sempre la conversione) quindi dovrai fare:
Farai bx*10= 4*10 = 40 + 9 = 49.

Quindi prima moltiplichi * 10 e poi sommi il carattere immesso in input.

Ciò che fai tu è prima sommare, e poi moltiplicare. Ergo, se inserisci il numero 4 ti ritrovi con il valore 40, se inserisci 49 ti ritrovi con 490.
Il tuo codice infatti fa questo:

Bx = 0
'4' - '0' = 4
Sommi bx + 4 = 4 e poi fai 4*10=40.
Poi con il 9 fai 40+9=49, ma moltiplichi dopo, quindi ti trovi 490.

Capito che intendo?

Usa un debugger, così vedi i valori in memoria e nei registri (anche Emu8086 va bene, lo usi solo per eseguire step by step).
 
Ultima modifica:
Supponiamo che tu voglia inserire in input il valore 49.
Il registro che contiene il numero sarà inizialmente a 0 (diciamo bx=0).

Digiti '4'. Converti in numero, quindi '4' - '0' = 4.
Bx = 0; quindi farai bx*10=0 + 4.

Inserisci il numero '9', (e fai sempre la conversione) quindi dovrai fare:
Farai bx*10= 4*10 = 40 + 9 = 49.

Quindi prima moltiplichi * 10 e poi sommi il carattere immesso in input.

Ciò che fai tu è prima sommare, e poi moltiplicare. Ergo, se inserisci il numero 4 ti ritrovi con il valore 40, se inserisci 49 ti ritrovi con 490.
Il tuo codice infatti fa questo:

Bx = 0
'4' - '0' = 4
Sommi bx + 4 = 4 e poi fai 4*10=40.
Poi con il 9 fai 40+9=49, ma moltiplichi dopo, quindi ti trovi 490.

Capito che intendo?

Usa un debugger, così vedi i valori in memoria e nei registri (anche Emu8086 va bene, lo usi solo per eseguire step by step).
Infatti io divido per 10 dopo aver inserito il carattere 13(invio) e alla fine delle 4 iterazioni, comunque Emu8086 mi chiede di pagare quindi userò un semplice debbuger come quello di Ms-dos
 
Ultima modifica:
Si ho capito che intendi. In realtà quella parte la puoi togliere se esegui prima la moltiplicazione e poi la somma.

Ad ogni modo l'errore è proprio dovuto al punto in cui fai quella divisione:
Codice:
               mov   ax, register
               mov   bx, 10
               div   bx
               mov   register, ax

la causa è l'operando che usi BX. Così facendo la divisione interessa la coppia DX:AX, e quindi va in overflow la divisione.
Devi inizializzare DX a 0, tipo così dovrebbe funzionare:

Codice:
               mov   ax, register
               mov   dx, 0   ; xor dx, dx
               mov   bx, 10
               div   bx
               mov   register, ax

ciò non toglie il fatto che se segui quanto suggerivo sopra, ti eviti direttamente queste istruzioni. ;)

EDIT:

Non ho spiegato il motivo dell'overflow, ma per essere più chiaro.
Tu arrivi al termine del programma con il registro DX che contiene il risultato di quell'operazione (l'input inserito); diciamo 12, che nel tuo caso è in realtà 120 (che verrà qui diviso).
Quando fai la divisione la coppia che viene presa è DX:AX, ed entrambi contengono 120. Il risultato che esce viene memorizzato in AX ma... è troppo grande per stare in 16bit, quindi va in overflow e non termina correttamente.

Se inizializzi DX=0 dopo aver assegnato il suo valore al registro AX (come ho fatto li sopra) funziona, in quanto appunto setti a 0 la parte alta e viene diviso solo il numero 120 per 10.
 
Si ho capito che intendi. In realtà quella parte la puoi togliere se esegui prima la moltiplicazione e poi la somma.

Ad ogni modo l'errore è proprio dovuto al punto in cui fai quella divisione:
Codice:
               mov   ax, register
               mov   bx, 10
               div   bx
               mov   register, ax

la causa è l'operando che usi BX. Così facendo la divisione interessa la coppia DX:AX, e quindi va in overflow la divisione.
Devi inizializzare DX a 0, tipo così dovrebbe funzionare:

Codice:
               mov   ax, register
               mov   dx, 0   ; xor dx, dx
               mov   bx, 10
               div   bx
               mov   register, ax

ciò non toglie il fatto che se segui quanto suggerivo sopra, ti eviti direttamente queste istruzioni. ;)

EDIT:

Non ho spiegato il motivo dell'overflow, ma per essere più chiaro.
Tu arrivi al termine del programma con il registro DX che contiene il risultato di quell'operazione (l'input inserito); diciamo 12, che nel tuo caso è in realtà 120 (che verrà qui diviso).
Quando fai la divisione la coppia che viene presa è DX:AX, ed entrambi contengono 120. Il risultato che esce viene memorizzato in AX ma... è troppo grande per stare in 16bit, quindi va in overflow e non termina correttamente.

Se inizializzi DX=0 dopo aver assegnato il suo valore al registro AX (come ho fatto li sopra) funziona, in quanto appunto setti a 0 la parte alta e viene diviso solo il numero 120 per 10.
Ok ho fatto il problema è sempre lo stesso però, mi restituisce i seguenti errori l'Assemblatore:
Schermata del 2021-04-02 13-45-15.png

Tutti problemi a che fare con l'eticchette della macro, ma come si può vedere le ho definite locali alla macro stessa
Schermata del 2021-04-02 13-46-45.png

L' assemblatore si è rimbambito o che cosa?
 
Scarica una versione recente di MASM, penso sia quello il problema.
Io sto usando la versione Microsoft (R) Macro Assembler Version 6.14.8444 e come linker uso la Microsoft (R) Segmented Executable Linker Version 5.60.339.
 
Ultima modifica:
Scarica una versione recente di MASM, penso sia quello il problema.
Io sto usando la versione Microsoft (R) Macro Assembler Version 6.14.8444 e come linker uso la Microsoft (R) Segmented Executable Linker Version 5.60.339.
Generano codice eseguibile a 16bit, oppure si può specificare all'Assemblatore? Sto usando un emulatore MS-DOS quindi eseguibili a 32bit o 64bit non mi servono a molto
Messaggio unito automaticamente:

Messaggio unito automaticamente:

Scarica una versione recente di MASM, penso sia quello il problema.
Io sto usando la versione Microsoft (R) Macro Assembler Version 6.14.8444 e come linker uso la Microsoft (R) Segmented Executable Linker Version 5.60.339.
c'è qualche direttiva per generare eseguibilli a 16bit? Mi potresti dare un link per il dowloand che non lo trovo