Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

display in Decimal 1

Status
Not open for further replies.

syskplim

Technical User
Nov 17, 2003
46
0
0
MY
how can i display my Hex code as Decimal?

mov dl,41h
mov ah,02h
int 21h

i'll get the output as 'A'. how to show it as '65'?
 
;***********************************************************

; 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

PRINT_NUM_UNS PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX

; flag to prevent printing zeros before number:
MOV CX, 1

; (result of "/ 10000" is always less or equal to 9).
MOV BX, 10000 ; 2710h - divider.

; AX is zero?
CMP AX, 0
JZ print_zero

begin_print:

; check divider (if zero go to end_print):
CMP BX,0
JZ end_print

; avoid printing zeros before number:
CMP CX, 0
JE calc
; if AX<BX then result of DIV will be zero:
CMP AX, BX
JB skip
calc:
MOV CX, 0 ; set flag.

MOV DX, 0
DIV BX ; AX = DX:AX / BX (DX=remainder).

; print last digit
; AH is always ZERO, so it's ignored
ADD AL, 30h ; convert to ASCII code.
PUTC AL


MOV AX, DX ; get remainder from last div.

skip:
; calculate BX=BX/10
PUSH AX
MOV DX, 0
MOV AX, BX
DIV CS:ten ; AX = DX:AX / 10 (DX=remainder).
MOV BX, AX
POP AX

JMP begin_print

print_zero:
PUTC '0'

end_print:

POP DX
POP CX
POP BX
POP AX
RET
ten DW 10 ; used as divider.
PRINT_NUM_UNS ENDP

skip_proc_print_num_uns:

DEFINE_PRINT_NUM_UNS ENDM
;***********************************************************
 
;***********************************************************

; 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

PRINT_NUM_UNS PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX

; flag to prevent printing zeros before number:
MOV CX, 1

; (result of &quot;/ 10000&quot; is always less or equal to 9).
MOV BX, 10000 ; 2710h - divider.

; AX is zero?
CMP AX, 0
JZ print_zero

begin_print:

; check divider (if zero go to end_print):
CMP BX,0
JZ end_print

; avoid printing zeros before number:
CMP CX, 0
JE calc
; if AX<BX then result of DIV will be zero:
CMP AX, BX
JB skip
calc:
MOV CX, 0 ; set flag.

MOV DX, 0
DIV BX ; AX = DX:AX / BX (DX=remainder).

; print last digit
; AH is always ZERO, so it's ignored
ADD AL, 30h ; convert to ASCII code.
PUTC AL


MOV AX, DX ; get remainder from last div.

skip:
; calculate BX=BX/10
PUSH AX
MOV DX, 0
MOV AX, BX
DIV CS:ten ; AX = DX:AX / 10 (DX=remainder).
MOV BX, AX
POP AX

JMP begin_print

print_zero:
PUTC '0'

end_print:

POP DX
POP CX
POP BX
POP AX
RET
ten DW 10 ; used as divider.
PRINT_NUM_UNS ENDP

skip_proc_print_num_uns:

DEFINE_PRINT_NUM_UNS ENDM
;***********************************************************

Bye
OSProgrammer
 
HUH!!! SO DIFFICULT TO CONVERT!!!

:( i ve to learn by heard to push up my level first b4 i can understand this convertion. i thought we've a simple instruction to do that.

by the way, thanks OSProgrammer. i'll note down the macro for future use. Thnkx again.

---->ASM fresher need help!<----

With kind regards.
syskplim@streamyx.com
 
Folks,

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

bsh3
 
thankx bsh3

i'll try it out. maybe this is what i want.

thankx.





---->ASM fresher need help!<----

With kind regards.
syskplim@streamyx.com
 
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 &quot;wrong&quot; 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.

 
I always get the digits back to front the first time.

I thought I was Mr Spock, but plainly I was mistaken.

rgds
Zeit.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top