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

mov [bx], ax
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.

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
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

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...

;	mov [bx], ax
mov [bx],al

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

mov [bx],al

mov byte ptr  [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...

;	mov [bx], ax
mov [bx],al

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

mov [bx],al

mov byte ptr  [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
int 21h ; print to screen
dec cx
jnz loop2
pop dx
pop cx
pop bx
pop ax
ret
DecimalToString ENDP ; end
best regards

ok

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.