汇编程序在屏幕上打印数字

时间:2014-11-23 12:17:36

标签: assembly printing numbers screen interrupt

如何在屏幕上打印数组的数字(不是ASCII符号)?

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

此代码打印与数组中的数字对应的ASCII符号。我想打印数字

1 个答案:

答案 0 :(得分:3)

我认为您希望获得已签名的数字并且您知道负数是如何编码的(请参阅Wikipedia's article of Ones' complement。MSDOS不提供将数据转换为数字的就绪函数,因此您必须自己创建这样一个函数。主要问题是重复除以10并处理剩余部分。网上有很多例子和解释,用Google搜索:"程序集转换为十进制"。

这是我的方法(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