Question

I am attempting to write a program in Assembly to take a plus or minus sign as the first input ( deciding whether to plus or minus two numbers together ) and then taking two 2 digit numbers and adding/subtracting and displaying the result. I have the following code so far, but I am having troubles in the output. I know in the code snippet below it is simply displaying a single char, but I would like it to display the actual output but I have no idea how, attempting to use a normal string display interrupt does not work because the size of num2 or al does not match the size of dx (the output string register)

.MODEL SMALL
.STACK 100h
.DATA
choice_msg  db 13,10,'Addition or Subtraction?',13,10,'$' 

first_msg   db 13,10,'Enter the first number:',13,10,'$'   
second_msg  db 13,10,'Enter the second number:',13,10,'$'    
result_msg  db 13,10,'The result is:',13,10,'$'    
new_line    db 13,10,'$'    
val1        db ?    
num2        db ?    
num3        db ?    
num4        db ?      
ten         db 10    

.CODE                       ;where the code is written

start:

mov ax, @data           ;Moves the address of the variables under .DATA into ax

mov ds,ax           ;moves ax into ds. the two lines allow you to display string using the 21h interrupt sequence 9

    mov ah,09
    mov dx, offset choice_msg
    int 21h             ;displays the string in choice_msg

    mov ah,01
    int 21h             ;copies a value into the al, using subfunction 01
    mov val1,al         ;moves the value in the al to the variable val1

    cmp val1,'+'            ;compares the entered value in val1 with "+"
    je addition         ;if the enterd value is "+" then it jumps to addition else it jumps to subtraction

addition:
    mov ah,09
    mov dx, offset first_msg
    int 21h             ;displays the string in first_msg

    mov ah,01
    int 21h             ;copies a value into the al, using subfunction 01
    sub al,48           ;subtracts 48 from the vaule in the al
    mov num2,al         ;moves the value in the al to the variable num2

    mov ah,01           
    int 21h             ;copies a value into the al, using subfunction 01
    sub al,48           ;subtracts 48 from the value in the al
    mov num3,al         ;moves the value in the al to the variable num3

    mov al,num2         ;moves the value in num2 into the al
    mul ten             ;multiplies the value in the al by ten
    add al,num3         ;adds the value in num3 to the al, to get the two-digit number
    mov num2,al         ;moves the two digit value into

    mov ah,09
    mov dx, offset new_line 
    int 21h             ;goes to the next line, i.e. "enter"

    mov ah,09
    mov dx, offset second_msg   ;displays the string in second_msg
    int 21h             

    mov ah,01
    int 21h             ;copies a value into the al, using subfunction 01
    sub al,48           ;subtracts 48 from the value in the al
    mov num3,al         ;moves the new value in the al into the variable num3

    mov ah,01
    int 21h             ;copies a value into the al, using subfunction 01
    sub al,48           ;subtracts 48 from the value in the al
    mov num4,al         ;moves the new value in the al into the variable num4

    mov al,num3         ;moves the value in num3 into the al
    mul ten             ;multiplies the value in the al by ten
    add al,num4         ;adds the value in num4 to the al, to get a two-digit number
    mov num3,al         ;moves the value in the al into the variable num3

    mov ah,09
    mov dx, offset new_line
    int 21h             ;goes to the next line, i.e. "enter"

    mov ah,09
    mov dx, offset result_msg
    int 21h             ;displays the string in reslut_msg

    ; mov the value of num 3 into bl
    mov bl, num3

    add num2,bl         ;adds num3 and num2 to form the sum
    add num2,48         ;adds 48 to num2


    mov al,num2
    mov ah,02
    mov dl, al
    int 21h             ;displays the value that was in the al

    mov ah,09
    mov dx, offset new_line
    int 21h             ; goes to next line, i.e. "enter"

    mov ax,4c00h
    int 21h             ;ends the program


subtraction:
    mov ah,09
    mov dx, offset first_msg
    int 21h             ;displays the string in first_msg

    mov ah,01
    int 21h             ;copies a value into the al, using subfunction 001
    sub al,48           ;subtracts 48 from the value in the al
    mov num2,al         ;moves the value in the al into the variable num2

    mov ah,01
    int 21h             ;copies a value into the al, using subfunction 01
    sub al,48           ;subtracts 48 from the value in the al
    mov num3,al         ;moves the value in the al into the variable num3

    mov al,num2         ;moves the value in num2 into the al
    mul ten             ;multiplies the value in the al by ten
    add al,num3         ;adds the value in num3 to the al, to get a two-digit number
    mov num2,al         ;moves the value in the al into the variable num2

    mov ah,09
    mov dx, offset new_line 
    int 21h             ;goes to the next line, i.e. "enter"

    mov ah,09
    mov dx, offset second_msg
    int 21h             ;displays the string in second_msg

    mov ah,01
    int 21h             ;copies a value into the al, using subfunction 01
    sub al,48           ;subtracts 48 from the value in the al
    mov num3,al         ;moves the value in the al into the variable num3

    mov ah,01
    int 21h             ;copies a value into the al, using subfuntion 01
    sub al,48           ;subtracts 48 from the value in the al
    mov num4,al         ;moves the value in the al into the variable num4

    mov al,num3         ;moves the value in num3 into the al
    mul ten             ;multiplies the value in the al by ten
    add al,num4         ;adds the value in num4 to the al, to get a two-digit number
    mov num3,al         ;moves the value in the al into the variable num3

    mov ah,09
    mov dx, offset new_line
    int 21h             ;goes to next line, i.e. "enter"

    mov ah,09
    mov dx, offset result_msg
    int 21h             ;displays the string in result_msg

    mov bl, num3        ;move value of num3 to bl

    sub num2,bl         ;subtracts the value in num3 from the value in num2
    add num2,48         ;adds 48 to the new value in num2
    mov al,num2         ;moves the value in num2 into the al
    mov ah,02
    mov dh,al
    int 21h             ;displays the resulting value

    mov ah,09
    mov dx, offset new_line
    int 21h             ;goes to the next line, i.e. "enter"

    mov ax,4c00h
    int 21h             ;ends the program

END
Was it helpful?

Solution 2

Thanks for the help! I found a way that works quite well, for my code. See it below:

About the duplicate code: Yes I realised that (this is not actually my code, it was a friends that needed fixing), I fixed up the code and proceduralised a lot of it to minimalise code re-use. And the result is the final program here: I know the code is not perfect, and there are many performance improvements that can be made but the outcome is a working program with an okay execution time.

.MODEL SMALL
.STACK 100h
.DATA

choice_msg  db 13,10,'Addition or Subtraction?',13,10,'$' 
first_msg   db 13,10,'Enter the first number:',13,10,'$'
second_msg  db 13,10,'Enter the second number:',13,10,'$'
result_msg  db 13,10,'The result is:',13,10,'$'
new_line    db 13,10,'$'
val1        db ?
num1        db ?
num2        db ?
num3        db ?        ; purely a buffer variable 
ten         db 10   
t1          db 0
t2          db 0     
result      db 0

.CODE                   ;where the code is written
start:  

    mov ax, @data           ;Moves the address of the variables under .DATA into ax
    mov ds,ax           ;moves ax into ds. the two lines allow you to display string using the 21h interrupt sequence 9

    mov ah,09
    mov dx, offset choice_msg
    int 21h             ;displays the string in choice_msg

    mov ah,01
    int 21h             ;copies a value into the al, using subfunction 01

    cmp al,'+'          ;compares the entered value in with "+"
    jne subtraction         ;if the enterd value is "+" then it jumps to addition else it jumps to subtraction

addition: 

    call read           ;Read the input
    call endl           ;output new line

    mov bl, num2        ;move the value of num 2 into bl

    add num1,bl         ;adds num2 and num1 to form the sum1
    mov al, num1        ;mov num1 to al
    mov result, al      ;store the result of the sum in result

    call write          ;write the output 
    jmp exit

subtraction:

    call read           ;Read the input
    call endl           ;output new line

    mov bl, num2        ;move value of num2 to bl

    sub num1,bl         ;subtracts the value in num2 from the value in num1
    mov al, num1        ;move result to a register
    mov result, al      ;move the result of the subtraction to result

    call write          ;display result with write procedure
    jmp exit


    ;-----------------------
    ;procedure declarations: 

    proc endl

        mov ah,09
        mov dx, offset new_line
        int 21h             ;goes to next line, i.e. "enter"

        ret

    endp


    proc read


        mov ah,09
        mov dx, offset first_msg
        int 21h             ;displays the string in first_msg

        mov ah,01           ;read char
        int 21h             ;copies a value into the al, using subfunction 01
        sub al,48           ;subtracts 48 from the vaule in the al
        mov num1,al         ;moves the value in the al to the variable num1

        mov ah,01           ;read second char
        int 21h             ;copies a value into the al, using subfunction 01
        sub al,48           ;subtracts 48 from the value in the al
        mov num2,al         ;moves the value in the al to the variable num2

        mov al,num1         ;moves the value in num1 into the al
        mul ten             ;multiplies the value in the al by ten
        add al,num2         ;adds the value in num2 to the al, to get the two-digit number
        mov num1,al         ;moves the two digit value into

        call endl

        mov ah,09
        mov dx, offset second_msg   ;displays the string in second_msg
        int 21h             

        mov ah,01
        int 21h             ;copies a value into the al, using subfunction 01
        sub al,48           ;subtracts 48 from the value in the al
        mov num2,al         ;moves the new value in the al into the variable num2

        mov ah,01
        int 21h             ;copies a value into the al, using subfunction 01
        sub al,48           ;subtracts 48 from the value in the al
        mov num3,al         ;moves the new value in the al into the variable num3

        mov al,num2         ;moves the value in num2 into the al
        mul ten             ;multiplies the value in the al by ten
        add al,num3         ;adds the value in num3 to the al, to get a two-digit number
        mov num2,al         ;moves the value in the al into the variable num2

        ret                 ;first number in num1, second in num2    
    endp


    ;The write procedure writes the decimal stored in result.
    ;by dividing by ten it seperates the two digits as quotient
    ;and remainder. Then it outputs the quotient and remainder
    ;in ascii form.
    proc write
            mov dx,offset result_msg
            mov ah,09h
            int 21h         ;display the result_msg string

            mov al,result   ;move the result from add/sub to al
            mov ah,00       ;initialize ah
            div ten         ;div al by ten, quotient is in al 
                            ;remainder is stored in ah.

            mov dl,ah       ;move the remainder to dl
            mov t2,dl       ;store the remainder in t2

            mov dl,al       ;move quotient into dl
            add dl,48       ;add 48 to dl, to convert it to ascii
            mov ah,02h      ;char display interupt code
            int 21h         ;display char in dl register

            mov dl,t2       ;move remainder to t2
            add dl,48       ;convert it to ascii by adding 48
            mov ah,02h      ;display character in dl interupt code
            int 21h         ;diplays contents of dl 

            call endl       ;output a new line
            ret             


    endp


    exit:
    mov ax, 4c00h               ;This is just a failsafe exit
    int 21h


END

OTHER TIPS

Here's a procedure (in NASM syntax) that will print any unsigned 16-bit integer:

; Converts the integer value in AX to a string in
; decimal representation and prints it.
; The digits are placed in a string buffer in reverse
; order - i.e. for the value 123, '3' would be placed
; last in the buffer, then '2' before that, and '1'
; before that, so that we'd end up with the string "123".
print_int:
  mov byte [buffer+9],'$'   ; add a string terminator at the end of the buffer
  lea si,[buffer+9]
  mov bx,10             ; divisor      
print_loop:
  xor dx,dx             ; clear dx prior to dividing dx:ax by bx
  div bx                ; AX /= 10
  add dl,'0'            ; take the remainder of the division and convert it from 0..9 -> '0'..'9'
  dec si                ; store characters in reverse order
  mov [si],dl
  test ax,ax
  jnz print_loop        ; repeat until AX==0 
  mov ah,9              ; print string
  mov dx,si
  int 21h
  ret

buffer: resb 10

I noticed that you've got a lot of duplicate code in your program. It would be better if you only read the input numbers in once place in your program, and then performed the appropriate operation on them based on the operator specified by the user.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top