Code: Select all
mov al, ch
and al, 0fh
mov dl, al
P.S : I tested masking lower nibble, but it wasn't my answer.
Code: Select all
mov al, ch
and al, 0fh
mov dl, al
It says "byte register cannot be first operand"Techel wrote:Now shift the high nibble to the low one using shr al, 4.
Sorry, but even word register wasn't acceptedTechel wrote:Ok, didn't know shr/l don't accept byte registers. Then use the entire ax.
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.)
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
Cool. Now use some routines to make it smaller and easier to maintain, like this:Haghiri75 wrote:Finally, I switched to nasm and my code is now 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
8086 only supported "shl reg,1" and "shl reg,cl". The "shl reg,imm8" variation was added by 80186.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?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.
I'm pretty sure the fastest solution is just to do 4 "shr al, 1" instructions. And it doesn't clobber any other registers.Octocontrabass wrote:If the programmer wants to shift right by 4 on an 8086, the programmer will have to explicitly use "shr al, cl".