; This macro defines a procedure that prints number in AX,
; used with PRINT_NUM_UNS to print signed numbers:
; Requires DEFINE_PRINT_NUM_UNS !!!
DEFINE_PRINT_NUM MACRO
LOCAL not_zero, positive, printed, skip_proc_print_num
; protect from wrong definition location:
JMP skip_proc_print_num
PRINT_NUM PROC NEAR
PUSH DX
PUSH AX
CMP AX, 0
JNZ not_zero
PUTC '0'
JMP printed
not_zero:
; the check SIGN of AX,
; make absolute if it's negative:
CMP AX, 0
JNS positive
NEG AX
PUTC '-'
positive:
CALL PRINT_NUM_UNS
printed:
POP AX
POP DX
RET
PRINT_NUM ENDP
skip_proc_print_num:
DEFINE_PRINT_NUM ENDM
;***********************************************************
; This macro defines a procedure that prints out an unsigned
; number in AX (not just a single digit)
; allowed values from 0 to 65535 (0FFFFh)
DEFINE_PRINT_NUM_UNS MACRO
LOCAL begin_print, calc, skip, print_zero, end_print, ten
LOCAL skip_proc_print_num_uns
; protect from wrong definition location:
JMP skip_proc_print_num_uns
; This macro defines a procedure that prints number in AX,
; used with PRINT_NUM_UNS to print signed numbers:
; Requires DEFINE_PRINT_NUM_UNS !!!
DEFINE_PRINT_NUM MACRO
LOCAL not_zero, positive, printed, skip_proc_print_num
; protect from wrong definition location:
JMP skip_proc_print_num
PRINT_NUM PROC NEAR
PUSH DX
PUSH AX
CMP AX, 0
JNZ not_zero
PUTC '0'
JMP printed
not_zero:
; the check SIGN of AX,
; make absolute if it's negative:
CMP AX, 0
JNS positive
NEG AX
PUTC '-'
positive:
CALL PRINT_NUM_UNS
printed:
POP AX
POP DX
RET
PRINT_NUM ENDP
skip_proc_print_num:
DEFINE_PRINT_NUM ENDM
;***********************************************************
; This macro defines a procedure that prints out an unsigned
; number in AX (not just a single digit)
; allowed values from 0 to 65535 (0FFFFh)
DEFINE_PRINT_NUM_UNS MACRO
LOCAL begin_print, calc, skip, print_zero, end_print, ten
LOCAL skip_proc_print_num_uns
; protect from wrong definition location:
JMP skip_proc_print_num_uns
One of the major x86 Y2k glitches came from a method that was employed in a lot of software to convert two digit, positive integers from binary to decimal. Would like to add that this was the defacto method for 808x chips. On the higher chips, >80386, it was not so good because the AAM instruction was very slow.
mov ax,37 ; AX now holds 37 in binary
aam ; an ASCII instruction known as ASCII Adjust
; after Multiply
; at this point, AL = binary 7
; AH = binary 3
or ax,3030h
; the above statement OR's in zero's in to AH and AL
; conveting binary 3 and 7 to ASCII '3' and '7'
; at this point one can store the digits sequentially
; using:
mov address,ah
mov address+1,al
; if you want to store AX into a word, using:
; mov Address, AX
; you have to remember that the Intel chips are little
; endian and that you need to
xchg, ah,al
; to get the proper alignment
The original point of AAM was to work with packed decimal digits. This is where you decide to ignore hex values from A to F and pack your decimal digits into bytes. When you manipulate them with normal arithmetic instructions you get the "wrong" answers. For instance 9 + 1 = A, not 010h. The adjust instructions (of which there is a whole family) were designed for this scenario.
Remember that if you've got a number like 0A3h, it won't be possible to convert it into 2 decimal digits, so instructions like aam have their limitations. Hence the general method so kindly supplied by several above!
The principle is dead easy: you knock of tens by division, and convert each number from a simple single-digit number to an ascii code by adding the ascii for a zero-character. The nice thing is you can scale this up indefinitely. If you're just learning, there is no harm in ignoring issues like leading zeroes, provided the answer is right. And if you get the digits back-to-front the first time, it only proves you're human.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.