Search code examples
assemblyprintingnumbersscreeninterrupt

Assembler Print the number on the screen


How can i print the numbers of array at screen (not ASCII symbols)?

MODEL SMALL
STACK 256
DATASEG
  Data1 dw 4h, -23h, 3h, 276h, -79h, -345h, 6h, 44h, -77h, 111, 12,10, '$'
CODESEG
Start:
mov ax,@data    
mov ds,ax   
mov dx,offset Data1                       
mov ah,09h
int 21h

Exit:
   mov ah,04Ch 
   mov al,0h    
   int 21h      

End Start

This code print ASCII symbols that correspond to numbers in array. I want print the numbers


Solution

  • I assume that you want to get signed numbers and that you you know how negative numbers are coded (see Wikipedia's article of Ones' complement. MSDOS doesn't provide a ready function to convert data to numbers, so you have to create such a function by yourself. The main issue is to repeatedly divide by 10 and to process the remainder. There are a lot of examples and explanations on the net, search with Google: "assembly convert to decimal".

    This is my approach (TASM):

    LOCALS @@
    
    MODEL SMALL
    STACK 256
    DATASEG
      Data1 dw 4h, -23h, 3h, 276h, -79h, -345h, 6h, 44h, -77h, 111, 12,10, '$'
      Decimal db 8 DUP ('$')
    CODESEG
    
    main PROC
            mov ax, @data
            mov ds, ax
            mov es, ax
    
            mov si, OFFSET Data1
    
        Loop:
    
            mov di, OFFSET Decimal  ; Convert WORD to decimal string
            mov ax, [si]
            call ax2dec_signed
    
            push si                 ; store SI for later use
    
            mov dx, OFFSET Decimal  ; Print the number
            mov ah,09h
            int 21h
    
            mov ah, 02h             ; Print a space
            mov dl, 20h
            int 21h
    
            pop si                  ; restore SI
            add si, 2               ; next WORD
            cmp word ptr [si], '$'  ; End of String?
            jne Loop                ; No: once more
    
        Exit:
            mov ah,04Ch
            mov al,0h
            int 21h
    main ENDP
    
    ax2dec_signed PROC              ; Args: AX register to convert, ES:DI pointer to target string
            test ax, ax             ; AX negative?
            jns @@J1                ; No: skip the following code
            mov byte ptr [di], '-'  ; Yes: store the negative sign
            inc di                  ; Increment the pointer to the target string
            neg ax                  ; One's complement, i.e. AX = ABS(AX)
        @@J1:
            mov bx, 10              ; Base 10 -> divisor
            xor cx, cx              ; CX=0 (number of digits)
        @@Loop_1:
            xor dx, dx              ; Clear DX for division (don't forget it!)
            div bx                  ; AX = DX:AX / BX Remainder DX
            push dx                 ; Push remainder for LIFO in Loop_2
            add cl, 1               ; Equivalent to 'inc cl'
            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 [di], '$'           ; Store termination character for 'int 21h fn 09h'
            ret                     ; Ret: target string contains decimal '$'-terminated ASCII-String
    ax2dec_signed ENDP
    
    END main