The interrupt service Int 21/AH=02h is used to print the digits.
The standard conversion from number to numeral is performed with the
div instruction, the dividend is initially the highest power of ten fitting 16 bits (104) and it is reduced to lower powers at each iteration.
The parameters are shown in order of push.
Each one is 16 bits.
|number||The 16-bit unsigned number to print in decimal|
|show leading zeros||If 0 no non-significant zeros are printed, else they are. The number 0 is always printed as "0"|
push 241 push 0 call print_dec ;prints 241 push 56 push 1 call print_dec ;prints 00056 push 0 push 0 call print_dec ;prints 0
;Parameters (in order of push): ; ;number ;Show leading zeros print_dec: push bp mov bp, sp push ax push bx push cx push dx ;Set up registers: ;AX = Number left to print ;BX = Power of ten to extract the current digit ;DX = Scratch/Needed for DIV ;CX = Scratch mov ax, WORD PTR [bp+06h] mov bx, 10000d xor dx, dx _pd_convert: div bx ;DX = Number without highmost digit, AX = Highmost digit mov cx, dx ;Number left to print ;If digit is non zero or param for leading zeros is non zero ;print the digit or WORD PTR [bp+04h], ax jnz _pd_print ;If both are zeros, make sure to show at least one digit so that 0 prints as "0" cmp bx, 1 jne _pd_continue _pd_print: ;Print digit in AL mov dl, al add dl, '0' mov ah, 02h int 21h _pd_continue: ;BX = BX/10 ;DX = 0 mov ax, bx xor dx, dx mov bx, 10d div bx mov bx, ax ;Put what's left of the number in AX again and repeat... mov ax, cx ;...Until the divisor is zero test bx, bx jnz _pd_convert pop dx pop cx pop bx pop ax pop bp ret 04h
To port the code to NASM remove the
PTR keyword from memory accesses (e.g.
mov ax, WORD PTR [bp+06h] becomes
mov ax, WORD [bp+06h])