0

I'm new to assembly. I have this project i have to do for school, it's about creating a calculator. Everything seems to work fine except this : To convert numbers from Decimal to Binary, then from Binary to ASCII, my professor told us to use a procedure. He actually even wrote it for us. Long story short, when i tried using it, i got different errors. I remember struggling with the A2030 error, but i got rid of it. Unfortunately, now i'm stuck again. When i try to assemble my code, i keep getting this error :

SUB.asm (169) : error A2070: invalid instruction operands

line 169 :

MOV RESFINALASCII, BYTE PTR [DI]

I kind of understood by looking it up on the internet that the problem was because one of my variables might be a BYTE while the other one might be a WORD but i have no clue. I'm hoping someone can help me understand this a little better and fix my code.

Here's the code :

ASSUME CS:CSEG, DS:CSEG, ES:CSEG
CSEG        SEGMENT
            ORG 100H
            
MAIN:           JMP DEB

;***********************************Procédures
;--------------------------- Conversion du nombre en BINAIRE

CONVBIN     PROC

            MOV AX,0
            MOV BX,0AH
        
CONVBINBCL:
            MUL BX
            ADD AL,[SI]
            ADC AH,0
            INC SI
            CMP [SI],0DH
            JNE CONVBINBCL
            RET
CONVBIN     ENDP

CONVDEC     PROC
            
            MOV BX,0AH
            
CONVDECBCL: 
            DIV BX
            OR DL,30H
            MOV [DI],DL
            INC DI
            CMP AX,0
            JNE CONVDECBCL
            RET
CONVDEC     ENDP

;***********************************


DEB:

SAISIEOP:
;--------------------------- Affichage message INT21-40
            LEA DX,br
            MOV AH,9
            INT 21H ;-- Nouvelle ligne
            
            MOV BX,0001H
            LEA DX,MESSAGE3
            MOV CX, L_MESSAGE3 
            MOV AH, 40H
            INT 21H
            
;--------------------------- Saisie de l'opérateur
            MOV CX,1
            LEA DI,OPERATEUR

            MOV AH,01
            INT 21H
            CMP AL,043
            JE SAISIENB
            CMP AL,045
            JE SAISIENB
            CMP AL,042
            JE SAISIENB
            CMP AL,047
            JE SAISIENB
            
ERREUROP:   
;--------------------------- Affichage message INT21-40
            LEA DX,br
            MOV AH,9
            INT 21H ;-- Nouvelle ligne
            
            MOV BX,0001H
            LEA DX,ERREUROPERANDE
            MOV CX, L_ERREUROPERANDE 
            MOV AH, 40H
            INT 21H 
            
            JMP SAISIEOP        


SAISIENB:
;--------------------------- Affichage message INT21-40
            LEA DX,br
            MOV AH,9
            INT 21H ;-- Nouvelle ligne
            
            MOV BX,0001H
            LEA DX,MESSAGE1
            MOV CX,L_MESSAGE1 
            MOV AH, 40H
            INT 21H
            
;--------------------------- Saisie du nombre
            MOV CX,4
            LEA DI,NOMBRE1D
SAISIE1:
            MOV AH,01
            INT 21H 
            
            CMP AL,0DH
            JE SUITE1
            CMP AL,30H
            JB HORSCODE1
            CMP AL,39H
            JA HORSCODE1
            AND AL, 00001111B
            MOV [DI],AL
            INC DI
            DEC CX
            JNZ SAISIE1

SUITE1:     MOV [DI], 0DH
            LEA SI,NOMBRE1D 
            CALL CONVBIN
            MOV NOMBRE1B,AX

HORSCODE1:

SAISIENB2:
;--------------------------- Affichage message INT21-40
            LEA DX,br
            MOV AH,9
            INT 21H ;-- Nouvelle ligne
            
            MOV BX,0001H
            LEA DX,MESSAGE2
            MOV CX,L_MESSAGE2 
            MOV AH, 40H
            INT 21H

;--------------------------- Saisie du nombre           
            MOV CX,4
            LEA DI,NOMBRE2D
SAISIE2:    
            MOV AH,01
            INT 21H 
            CMP AL,0DH
            
            JE SUITE2
            CMP AL,30H
            JB HORSCODE2
            CMP AL,39H
            JA HORSCODE2
            AND AL, 00001111B
            MOV [DI],AL
            INC DI
            DEC cx
            JNZ SAISIE2
            
SUITE2:     MOV [DI],0DH    
            LEA SI,NOMBRE2D 
            CALL CONVBIN
            MOV NOMBRE2B,AX
            JMP OPSELEC
            
HORSCODE2:
            
;--------------------------- Conversion du nombre en DECIMAL

CONVDECIMAL:        
            LEA DI,RESFINALASCII
            MOV AX,NOMBRE1B
            CALL CONVDEC
// LINE 169 MOV RESFINALASCII,BYTE PTR [DI]    
            



;--------------------------- JMP to opération
OPSELEC:    MOV CX,1
            LEA DI,OPERATEUR

            MOV AH,01
            INT 21H
            CMP AL,043
            JE ADDI
            CMP AL,045
            JE SUBS
            CMP AL,042
            JE MULTI
            CMP AL,047
            JE DIVI
            
;*************************** SOUSTRACTION
SUBS:       MOV AX,NOMBRE1b
            MOV BX,0
            SUB AX,NOMBRE2b
            MOV RESULTAT,AX
            ADC BX,0
            MOV RESULTAT+2,BX
            JMP AFFRES
;****************************

            
;*************************** ADDITION
ADDI:       MOV AX,NOMBRE1b
            MOV BX,0
            ADD AX,NOMBRE2b
            MOV RESULTAT,AX
            ADC BX,0
            MOV RESULTAT+2,BX
            JMP AFFRES
;***************************


;*************************** MULTIPLICATION
MULTI:      MOV AX,NOMBRE1b
            MOV BX,0
            MUL NOMBRE2b
            MOV RESULTAT,AX
            ADC BX,0
            MOV RESULTAT+2,BX
            JMP AFFRES
;***************************


;*************************** DIVISION
DIVI:       MOV AX,NOMBRE1b
            MOV BX,0
            DIV NOMBRE2b
            MOV RESULTAT,AX
            ADC BX,0
            MOV RESULTAT+2,BX
            JMP AFFRES
;***************************


;--------------------------- Affichage RESULTAT
AFFRES:     MOV AX,RESULTAT
            MOV CX,0
            MOV DX,0
AFFRESBCL:  
            CMP AX,0
            JE PRINT1
            MOV BX,10
            DIV BX
            PUSH DX
            INC CX
            XOR DX,DX
            JMP AFFRESBCL
PRINT1:         
            CMP CX,0
            JE SORTIE
            POP DX
            ADD DX,48
            MOV AH,02H
            INT 21H
            DEC CX
            JMP PRINT1
SORTIE:     JMP FIN


;---------------------------

COMMENT /*          
            MOV AH,3FH
            LEA DX, BUFFER
            INT 21H
            
            MOV AH, 40H
            LEA DX, BUFFER
            INT 21H 
*/
;--------------------------- Fin d'execution INT24-4C
FIN:        MOV AH, 4CH
            INT 21H
            

;---------------------------
;------ZONE DE DONNEES------
;---------------------------

br DB 0AH,0DH,"$" ;-- ligne vide
        
NOMBRE1D    db 5 DUP (?)
NOMBRE2D    db 5 DUP (?)

NOMBRE1b        dW ?
NOMBRE2b        dW ?

RESULTAT    dW 2 DUP (?)
RESFINALASCII db 10 DUP (?)

OPERATEUR DB 1 DUP (?)
L_OPERATEUR EQU $-OPERATEUR
            
MESSAGE1    DB "VEUILLEZ SAISIR LE PREMIER NOMBRE"
L_MESSAGE1  EQU $-MESSAGE1
MESSAGE2    DB "VEUILLEZ SAISIR LE DEUXIEME NOMBRE"
L_MESSAGE2  EQU $-MESSAGE2
MESSAGE3    DB "Quelle operation souhaitez vous realiser ?"
L_MESSAGE3  EQU $-MESSAGE3
ERREUROPERANDE DB "Erreur lors de la saisie de l'operande"
L_ERREUROPERANDE EQU $-ERREUROPERANDE

BUFFER DB 80,?,80 DUP("$")


;--------------------------- Fin d'assemblage
CSEG        ENDS
            END MAIN```
Thanks a lot for your help,
- a french student
  • Which is line 169? This [mcve] is not very minimal as a demo of that specific problem. Quote the problematic line along with the error message so we can see it, and find it in context. But yes, the way you declare data in MASM does imply an operand-size for something like `mov [symbol], ax`, so if you want to load 2 elements from a byte array, you might need `mov ax, word ptr [array]` to override it. – Peter Cordes Jun 11 '22 at 21:43
  • @PeterCordes Thanks i didn't notice, i updated it – Nathan Arkxv Jun 11 '22 at 21:44
  • 1
    Ok. You can't `mov` between two memory locations; load into a register and store that. Or better, write your string->number function to return an integer in a register, or return a pointer. Or wait, that's a number->decimal function, leaving the result in an array of ASCII bytes? But you were going to copy the first byte? Did you actually want to memcpy it, like `rep movsb` or a loop? Unclear what's going on there; execution falls into the next block after that, and you're already passing a pointer to `RESFINALASCII` as an arg to `CONVDEC`, so wouldn't it already store the data there? – Peter Cordes Jun 11 '22 at 21:46
  • Oh, your `CONVDEC` stores the digits backwards, starting at the DI you pass it. (And forgets to `xor dx,dx` before `div`, so it's super broken.) So you don't need to do anything with the pointer after `CONVDEC` returns, you should just fix `CONVDEC` to store digits in printing order, either by reversing after you finish printing, or store backwards and then copy. (See [How do I print an integer in Assembly Level Programming without printf from the c library?](https://stackoverflow.com/a/46301894) / [Displaying numbers with DOS](https://stackoverflow.com/q/45904075)) – Peter Cordes Jun 11 '22 at 21:54

0 Answers0