Page 1 of 1

Printing a BCD value

Posted: Wed May 04, 2016 8:12 am
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.

Re: Printing a BCD value

Posted: Wed May 04, 2016 9:46 am
by Techel
Now shift the high nibble to the low one using shr al, 4.

Re: Printing a BCD value

Posted: Wed May 04, 2016 10:02 am
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"

Re: Printing a BCD value

Posted: Wed May 04, 2016 10:55 am
by Techel
Ok, didn't know shr/l don't accept byte registers. Then use the entire ax.

Re: Printing a BCD value

Posted: Wed May 04, 2016 11:00 am
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:

Re: Printing a BCD value

Posted: Wed May 04, 2016 11:33 am
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.)

Re: Printing a BCD value

Posted: Wed May 04, 2016 11:35 am
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.

Re: Printing a BCD value

Posted: Wed May 04, 2016 1:54 pm
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.

Re: Printing a BCD value

Posted: Wed May 04, 2016 2:43 pm
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

Re: Printing a BCD value

Posted: Wed May 04, 2016 10:13 pm
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

Re: Printing a BCD value

Posted: Sun May 08, 2016 7:43 pm
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)

Re: Printing a BCD value

Posted: Sun May 08, 2016 11:34 pm
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

Re: Printing a BCD value

Posted: Mon May 09, 2016 7:27 am
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".

Re: Printing a BCD value

Posted: Mon May 09, 2016 8:14 am
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.