How to get a emu8086 program to output a result?

118 Views Asked by At

Here is my assignment:

Write a program to divide two 8-bit numbers using successive subtraction method using 8086. Multiply this result with 7365. Display this result in Blue color on the output screen at row 19, column 14, page no. 0 using interrupts.

Here is my code:

; You may customize this and other start-up templates; 
; The location of this template is c:\emu8086\inc\0_com_template.txt

; You may customize this and other start-up templates;
; The location of this template is c:\emu8086\inc\0_com_template.txt

org 100h

dividend db 25; Example dividend
divisor db 5; Example divisor
result db 0; To store the quotient
remainder db 0; To store the remainder

main:
    mov ax, @data; Initialize the data segment
    mov ds, ax

    mov al, 16h; Load dividend into AL
    mov bl, 4h; Load divisor into BL
    xor ah, ah; Clear AH to store quotient
    xor dh, dh; Clear DH to store remainder

divide_loop:
    cmp al, bl; Compare AL and BL
    jl divide_done; Jump if AL < BL, division is done

    sub al, bl; Subtract BL from AL
    inc ah; Increment quotient

    jmp divide_loop; Repeat the loop

divide_done:
    mov 1000h, ah; Store quotient in memory
    mov 1001h, al; Store remainder in memory

mult:
    mov bx, 7365h
    mov ax, 1000h
    mul bx
    mov 1002h, ax

display_result:
    mov ah, 13h; Set interrupt for write string
    mov bh, 0; Set page number to 0
    mov bl, 0011_1011b; Set text color to white on black
    mov cx, 2; Set number of characters to write
    mov dl, 10; Set column position to 10
    mov dh, 19; Set row position to 19

    mov bx, 1002h; Point to the data to display
    mov es, bx; Set data segment for the string

    lea dx, [bx]; Load address of the string into DX

    int 10h; Call interrupt to write the string

end main

ret

The result is not getting displayed to screen.

I have sought help of Chatgpt and interrupts manual of 8086 to write this, I compiled this on emu8086 4.08

1

There are 1 best solutions below

0
Sep Roland On
org 100h

 dividend db 25; Example dividend
 divisor db 5; Example divisor
 result db 0; To store the quotient
 remainder db 0; To store the remainder

main:

In emu8086, when mentioning org 100h, you will be creating an executable program with the .COM extension. In such a program execution starts with the first byte and that byte should be code, not data like is the case here! You must store those data defining lines much lower in the text, beneath all the code.

int 10h; Call interrupt to write the string

end main

ret

In a .COM program there's also no need to include main: nor end main. It's noise.

mov al, 16h; Load dividend into AL
mov bl, 4h; Load divisor into BL

Better use the variables that were defined in the program. You write it like: mov al, [dividend] mov bl, [divisor]

divide_done:
 mov 1000h, ah; Store quotient in memory
 mov 1001h, al; Store remainder in memory
mult:
 mov bx, 7365h
 mov ax, 1000h
 mul bx
 mov 1002h, ax

The multiplication is wrong. Because mov ax, 1000h is not using the quotient that is stored in memory. This instruction just loads the immediate value 1000h (4096). Why would it operate any different from the instruction mov bx, 7365h that is directly above?
You need to dereference by using the square brackets like in mov ax, [1000h]. But wait, since you have stored the remainder from the division at address 1001h, you should not be reading a full word from the memory! You can use instead: mov al, [1000h] mov ah, 0.

Once your multiplication produced its 32-bit result in DX:AX, and you stored only the lowest 16 bits in memory at 1002h, you still need to convert the value into a corresponding string of characters. See Displaying numbers with DOS for a complete primer on doing that.

Since your assignment wants you to display these characters at a specific position on the screen (14,19) and using the BlueOnBlack attribute (01h), you can't rely on (colorless) DOS, but need to use a suitable BIOS function. The one that you have selected can do the job, but you got most of its arguments totally wrong! Did you consult a reference at least?
Displaying characters with DOS or BIOS is another primer that amongst other things, explains and shows how to output colorful text using BIOS. The WriteStringWithAttributeTVM code snippet should be of special interest for you. It accepts 2 arguments: in BL the attribute (01h for BlueOnBlack) and in SI the address of the first character in the string that corresponds to the product that you have calculated.

org  100h
mov  ax, data
mov  ds, ax
mov  al, [dividend]
mov  bl, [divisor]

...

mult:
 mov  bx, 7365h
 mov  al, [result]
 mov  ah, 0
 mul  bx             ; -> DX:AX

 ...        < add conversion code based on the 1st link >

 mov  bl, 01h
 mov  si, OFFSET buffer
 call WriteStringWithAttributeTVM
 ret

 ...        < add WriteStringWithAttributeTVM from the 2nd link >

 dividend  db 25 ; Example dividend
 divisor   db 5  ; Example divisor
 result    db 0  ; To store the quotient
 remainder db 0  ; To store the remainder
 buffer    db 32 dup 0