Printing a BCD value

Programming, for all ages and all languages.
Post Reply
Haghiri75
Member
Member
Posts: 29
Joined: Fri Nov 16, 2012 4:16 am
Location: Iran
Contact:

Printing a BCD value

Post by Haghiri75 »

I wrote a code with interrupt 1ah, and I did this :

Code: Select all

mov al, ch
and al, 0fh
mov dl, al
Now, for example time is "18:36", it shall print hours, and only prints 8. Because I wanted program to do this. But, what can I do to show "1"?

P.S : I tested masking lower nibble, but it wasn't my answer.
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: Printing a BCD value

Post by Techel »

Now shift the high nibble to the low one using shr al, 4.
Haghiri75
Member
Member
Posts: 29
Joined: Fri Nov 16, 2012 4:16 am
Location: Iran
Contact:

Re: Printing a BCD value

Post by Haghiri75 »

Techel wrote:Now shift the high nibble to the low one using shr al, 4.
It says "byte register cannot be first operand"
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: Printing a BCD value

Post by Techel »

Ok, didn't know shr/l don't accept byte registers. Then use the entire ax.
Haghiri75
Member
Member
Posts: 29
Joined: Fri Nov 16, 2012 4:16 am
Location: Iran
Contact:

Re: Printing a BCD value

Post by Haghiri75 »

Techel wrote:Ok, didn't know shr/l don't accept byte registers. Then use the entire ax.
Sorry, but even word register wasn't accepted :lol:
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: Printing a BCD value

Post by Octocontrabass »

It sounds like there's something wrong with your assembler. It should accept shr al, 4 as a valid instruction in most situations. (It's not a valid 8086 instruction, so make sure your assembler is using 80186 instructions at minimum.)
Haghiri75
Member
Member
Posts: 29
Joined: Fri Nov 16, 2012 4:16 am
Location: Iran
Contact:

Re: Printing a BCD value

Post by Haghiri75 »

Octocontrabass wrote:It sounds like there's something wrong with your assembler. It should accept shr al, 4 as a valid instruction in most situations. (It's not a valid 8086 instruction, so make sure your assembler is using 80186 instructions at minimum.)

I use masm16.
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: Printing a BCD value

Post by Octocontrabass »

MASM only accepts 8086 instructions by default. To use 80186 instructions like "shr al, 4" in your code, you need to enable the 80186 instruction set using the .186 directive.
Haghiri75
Member
Member
Posts: 29
Joined: Fri Nov 16, 2012 4:16 am
Location: Iran
Contact:

Re: Printing a BCD value

Post by Haghiri75 »

Finally, I switched to nasm and my code is now this :

Code: Select all

mov bh, ch
shr bh, 4
and bh, 0fh
add bh, 30h


mov ah, 0x0e
mov al, bh
int 0x10

mov bh, ch
and bh, 0fh
add bh, 30h

mov ah, 0x0e
mov al, bh
int 0x10

mov ah,0x0e
mov al, ':'
int 0x10

mov bh, cl
shr bh, 4
and bh, 0fh
add bh, 30h

mov ah, 0x0e
mov al, bh
int 0x10

mov bh, cl
and bh, 0fh
add bh, 30h

mov ah, 0x0e
mov al, bh
int 0x10

mov ah,0x0e
mov al, ':'
int 0x10

mov bh, dh
shr bh, 4
and bh, 0fh
add bh, 30h

mov ah, 0x0e
mov al, bh
int 0x10

mov bh, dh
and bh, 0fh
add bh, 30h

mov ah, 0x0e
mov al, bh
int 0x10
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Printing a BCD value

Post by Brendan »

Hi,
Haghiri75 wrote:Finally, I switched to nasm and my code is now this :
Cool. Now use some routines to make it smaller and easier to maintain, like this:

Code: Select all

;Print a single character
;
;Input
;    al = character to print
;
;Output
;    none

printChar:
    push ax
    mov ah, 0x0e
    int 0x10
    pop ax
    ret

Code: Select all

;Print a BCD value
;
;Input
;    al = BCD value to print
;
;Output
;    none

printBCD:
    push ax
    mov ah,al      ;ah = BCD value
    shr al,4       ;al = high nibble
    and ah,0x0F    ;ah = low nibble
    or ax,0x3030   ;al = high nibble + '0', ah = low nibble + '0'
    call printChar ;Print character for high nibble
    mov al,ah      ;al = character for low nibble
    call printChar ;Print character for low nibble
    pop ax
    ret

Code: Select all

    mov al,ch        ;al = hour as BCD
    call printBCD

    mov al, ':'
    call printChar

    mov al,cl        ;al = minute as BCD
    call printBCD

    mov al, ':'
    call printChar

    mov al,dh        ;al = second as BCD
    call printBCD
:)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
samreeve
Posts: 1
Joined: Sun May 08, 2016 6:58 pm
Libera.chat IRC: samreeve

Re: Printing a BCD value

Post by samreeve »

Off topic, but the 8086 can perform shr al,4. The op-code should be 0xD2 E8 with the CL register set to 4. So that compiler is mad.

Also, If you implemented a function that could print out hex codes, for example in order to print registers etc.. , it would also be able to print out BCD ( but you'd have to check for A-F first)
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Printing a BCD value

Post by Brendan »

Hi,
samreeve wrote:Off topic, but the 8086 can perform shr al,4. The op-code should be 0xD2 E8 with the CL register set to 4. So that compiler is mad.
8086 only supported "shl reg,1" and "shl reg,cl". The "shl reg,imm8" variation was added by 80186.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: Printing a BCD value

Post by Octocontrabass »

samreeve wrote:Off topic, but the 8086 can perform shr al,4. The op-code should be 0xD2 E8 with the CL register set to 4. So that compiler is mad.
How do you propose the assembler generate code to set CL to the correct value? Does it simply insert a MOV and hope the programmer knows that it will clobber CL? Does it try to save/restore CX on the stack, even though the stack may not be usable?

There are no good solutions to that problem, so the assembler generates an error instead. If the programmer wants to shift right by 4 on an 8086, the programmer will have to explicitly use "shr al, cl".
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Printing a BCD value

Post by iansjack »

Octocontrabass wrote:If the programmer wants to shift right by 4 on an 8086, the programmer will have to explicitly use "shr al, cl".
I'm pretty sure the fastest solution is just to do 4 "shr al, 1" instructions. And it doesn't clobber any other registers.
Post Reply