Search code examples
assemblydosx86-16fasm

How to print integer, instead ascii value?


I want to add five numbers in loop and print that sum. This is my code.

format MZ
stack sth:256
entry codeseg: main

segment sdat use16
;ds segment x
tabl db 1,2,3,4,10


segment sth use16
db 256 dup (?)

segment codeseg use16

main:
mov ax, sdat
mov ds, ax

;mov ax, sth
;mov ss, ax
;mov sp, 256

xor ax,ax
mov bx,tabl
mov cx,5
add:
        add ax,[bx]
        inc bx
        loop add

mov dx, ax
mov ah, 02h
int 21h


mov ax, 4c00h
int 21h
ret

I don't know what I'm doing wrong, I'd like to print out the sum, not the value of the ascii.


Solution

  • You have to convert the content of the AX register into an ASCII string which can be shown by the operating system. I've updated your code accordingly, among other changes. Now your challenge is to figure it all out ;-)

    format MZ
    stack 256
    entry codeseg:main
    
    segment dataseg use16
    tabl db 1,2,3,4,10
    outstr db 8 dup ('$')
    
    segment codeseg use16
    
    main:
    mov ax, dataseg
    mov ds, ax
    mov es, ax
    
    xor ax,ax
    mov bx,tabl
    mov cx,5
    addd:
        add al,[bx]
        adc ah, 0
        inc bx
        loop addd
    
    lea di, [outstr]
    call ax2dec
    
    lea dx, [outstr]
    mov ah, 09h
    int 21h
    
    mov ax, 4c00h
    int 21h
    
    ax2dec:                                 ; Args: AX:number ES:DI: pointer to string
        mov bx, 10                          ; Base 10 -> divisor
        xor cx, cx                          ; CX=0 (number of digits)
      Loop_1:
        xor dx, dx                          ; Clear DX for division
        div bx                              ; AX = DX:AX / BX   Remainder DX
        push dx                             ; Push remainder for LIFO in Loop_2
        inc cx                              ; inc cl = 2 bytes, inc cx = 1 byte
        test ax, ax                         ; AX = 0?
        jnz Loop_1                          ; No: once more
      Loop_2:
        pop ax                              ; Get back pushed digits
        or al, 00110000b                    ; Conversion to ASCII
        stosb                               ; Store only AL to [ES:DI] (DI is a pointer to a string)
        loop Loop_2                         ; Until there are no digits left
        mov BYTE [es:di], '$'               ; Termination character for 'int 21h fn 09h'
        ret