3

I am currently working on a project that requires me to prompt a user for three inputs (length, width, & height) and then calculate the volume (lwh). I am having problems printing out the result after the calculations are complete. Is there a way to print out a decimal value?

.MODEL  SMALL
 .STACK 100h  

.DATA
l  DB ?
w  DB ?
h  DB ?
v  DB ?
M1 DB 10,13, "Please enter the length: $"
M2 DB 10,13, "Please enter the width : $"
M3 DB 10,13, "Please enter the height: $"
M4 DB 10,13, "The volume is:$"          

   .CODE
    Main    PROC
    mov ax, @data       ; getting data segment address
    mov ds, ax          ; initializing the data segment  

    mov dx, offset M1   ; prompting user for a value
    mov ah, 09h     ; writing string to STDOUT
    int 21h             ; BIOS routines
    mov ah, 01h     ; reading in from STDIN, input stored in al
    int 21h
    mov bl, al
    sub ax,ax           ; clearing ax register for the next input
    sub bl, 30h
    mov l, bl
    sub bx,bx

    mov dx, offset M2
    mov ah, 09h
    int 21h 
    mov ah, 01h
    int 21h
    mov bl, al
    sub ax,ax
    sub bl, 30h
    mov w, bl
    mov al, l   
    mul bl 
    mov v, al
    sub ax, ax
    sub bx,bx

    mov dx, offset M3
    mov ah, 09h
    int 21h 
    mov ah, 01h
    int 21h
    sub al, 30h 
    mov h,  al 
    sub bx, bx
    mov bl, v
    mul bx
    mov v, al
    sub ax, ax
    sub bx,bx  

    mov dx, offset M4 
    mov ah, 09h
    int 21h 
    sub dx, dx
    mov dx, offset v
    mov ah, 09h
    int 21h
    mov ax, 400ch           ; returning control to OS
    int 21h     
    Main ENDP
    END Main
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
John Alto
  • 51
  • 2
  • 5

2 Answers2

3

This can be done simply with division/modulo. For example, if we have a 1 byte value to convert into decimal - say 152 - we can first divide 152 by 100, and then apply modulo 10 to it, giving a result of 1 (the first digit in the number)

(152 / 100) % 10 = 1

We can then save that to a string buffer for printing later, while we work on the next digit. For the next digit, we repeat the process, except dividing by 10 rather than 100

(152 / 10) % 10 = 5

Store this result in the next slot in the buffer. Repeat this process until you are dividing your value by 1, when you can just use modulo:

152 % 10 = 2

In psuedocode, the algorithm would look something like this:

buffer: byte[4]
buffer[3] = 0       ;; Null-terminate the buffer
buffer_index = 0

value: 153
divisor: 100        ;; Increase this for values larger than 999

while divisor > 0 do
    buffer[buffer_index] = (value / divisor) % 10
    buffer_index = buffer_index + 1
    divisor = divisor / 10
repeat

print buffer

I'll leave the assembly translation to you ;)

Levi
  • 1,921
  • 1
  • 14
  • 18
1

EMU8086 has a set of macros included, and there is a function that will do what you want. Add this to the top of your assembly file:

include "emu8086.inc"

Just above END Main add BOTH of these new lines:

Main ENDP

DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS

END Main

Now anywhere in your code that you need to print a signed integer to the console you can simply put the value in AX and do:

call print_num

To print unsigned integers you can do this:

call print_num_uns

As an example if you placed this code in your program:

mov ax, -10
call print_num

It should display this to the console:

-10

Please note: these macros and functions are a feature of EMU8086 and are not available in other 8086 assemblers.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198