Hi. I am trying to print a single digit decimal number on to the screen. So far I've come out with this code.

mov ax, 3
	var db '$'
	mov bx, offset var
	
	add ax, 30h
	mov [bx], ax
	add bx, 1
	mov byte ptr [bx], '$'

	mov ah, 9
	mov dx, offset var
	int 21h

	mov ah, 4ch
	int 21h

I do not see the result. It is printing blank for me.

Recommended Answers

All 8 Replies

deostroll,

I can see that you're doing this in DOS.

If your execution actually begins at "mov ax,3", then the "var db '$'" is executed next. $ is just a counter of the current program position, so it is a somewhat random opcode that depends on the address.

You need to figure out how to work with a variable, or at least get your code to jump around your variable.

mov ax, 3
        jmp next1
	var db '$'
next1:
	mov bx, offset var

- Dan

var db '$' ; actually stores the value 0x24 into the byte 'var'
var db $ ; would attempt to store the current offset
              ; but would thow an error for an offset is 16-bits

You are allowing your program to run into junk you should
define your variables as follows for beginners sake:

jmp mycode
; data area
mystr    db 'hex$'
myword dw 1234h
; code area
mycode:
mov ax,[myword]
mov ah,09
mov dx,offset mystr
int 21h
ret

To print out the decimal representation of a value
you need to do the following.
For the value 231 for example:
231 / 100 = 2 + 30h = 32h '2'
031 / 10 = 3 + 30h = 33h '3'
001 / 1 = 1 + 30h = 31h '1'

You will need to use the DIV instruction.
For an unsigned byte divisor the dividend is placed in AX.
Quotient will be returned in AL and the remainder in AH.
For an unsigned word divisor the dividend is placed in DX:AX.
Quotient will be returned in AX and the remainder in DX.

For example:

mov ax,10h
mov bl,8
div bl ; 10h (16) / 8 = 2r0, after execution AL = 2

Heres an example to print a single digit:

mov dl,2 ; our digit will be 2
add dl,30h
mov ah,02h ; Function 02h Console Output
int 21h
int 20h

Thanks, NotNull, I overlooked the single-quotes.

So that let's us say exactly how the processor perceives this code, and having "defined" the variable within the code actually looks like:

mov ax,3
and al,bb
add ...

and so on.

Opening the executable in the debugger, then disassembling, would show this.

You're pretty much covered by the other posts but you do need to be more careful of what instructions you use. In this case you're fine, but...

;	add ax, 30h
;	mov [bx], ax
                add al, 30h
                mov [bx],al

	add bx, 1
	mov byte ptr [bx], '$'

Your data value is 8-bits in size but you were writing 16-bits by using the ax register.
Also you could have done this with an or operation

or al,'0'
            mov [bx],al

but I'm not sure if the others caught this but you changed your register

add al, 30h
                mov [bx],al

                mov byte ptr  [bx+1],'$'
;	add bx, 1
;	mov byte ptr [bx], '$'

You spend CPU time changing your bx register by one, then stalled the write of the additional byte terminator instead of just writing it with displacement.

You're pretty much covered by the other posts but you do need to be more careful of what instructions you use. In this case you're fine, but...

;	add ax, 30h
;	mov [bx], ax
                add al, 30h
                mov [bx],al

	add bx, 1
	mov byte ptr [bx], '$'

Your data value is 8-bits in size but you were writing 16-bits by using the ax register.
Also you could have done this with an or operation

or al,'0'
            mov [bx],al

but I'm not sure if the others caught this but you changed your register

add al, 30h
                mov [bx],al

                mov byte ptr  [bx+1],'$'
;	add bx, 1
;	mov byte ptr [bx], '$'

You spend CPU time changing your bx register by one, then stalled the write of the additional byte terminator instead of just writing it with displacement.

hi
you should insert number in AX
and call procedure :

DecimalToString PROC Near

push ax
push bx
push cx
push dx
xor cx, cx ; this basically do this: cx = 00000000
mov bx, 10d ; put the decimal number 10 in bx, why? patient please we'll see in a moment why!
loop1:
xor dx, dx
div bx ; divide ax by bx and put the remainder in dx! this does basically this: 420/10 with 402 = 321 + 99.
push dx ; save the remainder in the stack
inc cx
cmp ax, 0
jnz loop1

mov ah, 02
loop2:
pop dx
add dl, 48
int 21h ; print to screen
dec cx
jnz loop2
pop dx
pop cx
pop bx
pop ax
ret
DecimalToString ENDP ; end
best regards

sarab457, your code can use some optimization.

xor dx,dx before the div bx is not needed.

DX:AX = AX / BX DX:Remainder AX:Quotient

No need to pre-initialize!

I'm really not sure what you're trying to do, but make these alterations to your code!

loop1: 
   inc cx 
   div bx ; divide ax by bx and put the remainder in dx! this does basically this: 420/10 with 402 = 321 + 99. 
   test ax,ax     ;
   push dx         ; Push remainder on the stack 
   jnz loop1       ; Loop until no quotient
                         ; Note:  cx is # of items on the stack!
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.