[PUZZLE] Testing the bits of a constant in PASM
Phil Pilgrim (PhiPi)
Posts: 23,514
'Learned a new trick today (new for me, at least); but, rather than divulging it right away, I thought it would be fun to present it as a puzzle. So here it is: How do you set a flag depending on the value of a certain bit in a CONstant?
Obviously, you could do something like this:
For extra recognition, how could you extend the same technique to replace the following with a single instruction and no extra registers?
-Phil
Obviously, you could do something like this:
mov x,#CONSTANT test x,#BIT wcBut that takes two instructions, plus an extra register. Can you do it with one instruction and no extra registers?
For extra recognition, how could you extend the same technique to replace the following with a single instruction and no extra registers?
mov x,#CONSTANT cmp x,#"A" wz
-Phil
Comments
-Phil
Edit: Oops! Marko's answer for the first part did not produce results equivalent to the code posted for the puzzle.
Edit 2: Okay, nonetheless, he did provide a more general solution for the case of testing a single bit.
(please enter 10 characters)
Kuroneko, you're right: 1/2 point awarded for that; the other for providing a more general solution than the 9-bit-restricted answer I had in mind.
potatohead: Ooh, sorry: no.
-Phil
Andy
(Sorry about the PM, Andy. I just like to have all my correspondence in one place.)
-Phil
The second part of Andy's entry (the cmp) works but produces the wrong (i.e. inverted) result for the zero flag.
-Phil
Have you seen the ! before the parentheses ?
Andy
-Phil
-Phil
I think I will soon receive another star under my name for this solution...
Andy
-Phil
I thought, the instruction needs a destination register, and if it should not be an initalized register and no SFR, then the only other register with a known value is the instruction itself.
The higher bits disturb a bit when comparing with the source immediate value, so we need an AND to eliminate these higher bits. And we should not modify the instruction, so a NR is necessary. An AND with NR is known as TEST instruction.
Testing a bit of a constant with result in Carry: An AND of CONSTANT and BITMASK results in zero or the BITMASK, this is ANDed with itself by the TEST instruction which eliminates the higher bits of the instruction and sets the Carry flag only according the source field.
Comparing a constant with another: The compile time compare of CONSTANT and "A" results in zero (False) or $FFFF_FFFF (True). $FFFF_FFFF is to big for the source field, so I shift it right and we have only 0 or 1 in the source field. Again the TEST eliminates the higher bits and the ZERO flag is set according this 0 or 1. Because the Z Flag would be set invers to a compare, I add a NOT (!) before the parentheses.
Puhh, now I have deserved my fourth star, I hope...
Andy
-Phil
While I am greenwood when it comes to the prop, I started to reply a few times. I did not because I was not sure of the context in which you were comparing a two literals as shown. If CONSTANT and BIT are already defined, could a logical have been used to compare the contents of the address of the CONSTANT and BIT locations? (Run time assuming the values have been stored)
What would be more interesting if this is a compile time trick would be to see what the resultant code is in the hex listings and compare what the compiler generated to carry out your trick as opposed to the original two instruction.
If I am way off the mark, just give a chuckle and let me know so I can adjust my frame of reference.
Thanks
Frank
Frank
code deleted - it was completely wrong