Best practices assembly code for bit operations
Cncjerry
Posts: 64
Can somebody point me to what would be considered best practices for the equivalent PIC assembly codes for setting a bit, clearing a bit, testing a bit in 32 bit registers? I currently initialize a register shifting the bit around for setting or clearing with or, and, andn, XOR depending.
Jerry
Jerry
Comments
AND = clear a bit with the zeros in the mask (source field)
But to make it easy use ANDN to clear a bit wth 1s in the mask ,as the N reverses the mask.
And then there is the MUXC/MUXZ,
set the bit to the values of C or Z (eg 0 or 1) and the mask (dest field) will tell what bits to affect
Next question, if I have a 32 bit register that I need to shift out a specific pin with clock on another pin, is there an easy way to nondestructively ( to the other bits in the outa register) shift it out? There must be serial clock code around I guess. But I was thinking the cleanest way would be to save out and dira, flip all dira to inputs except for the two (clock and data) pins, then load outa with data, or in the clock, etc. I would then reload outa and dira.
"bits" has be set equal to 8 previously. I think this would work with other sizes of data if the value of "bits" were adjusted.
I doubt any of this code is original to myself.
It is destructive to oByte but not the other bits in the outa register.
Edit: I hadn't seen Tony's post.
I think your code could be improved (sped up) with some "djnz" statements.
You're "asm_cnt" could be loaded with "#8" and instead of shifting and then testing, a single "djnz" would take care of catching the end of your countdown.
When it has no value left, e.g shifted out it should no longer jump back to loop2.
Saves me a long (mov counter,#24) before the loop starts and speed wise it's negligible
sar asm_cnt,#1 wz 'shift right
if_nz jmp #:loop2
Thanks for explaining Tony. I just think the "djnz" statement is pretty cool that it can subtract and jump in four clock cycles (8 cycles when not jumping) so I try to use it when ever I can.
My not understanding your code made me think you could take advantage of it too. I'll need to study your code a bit more and see if I can better understand it.
Considering I am not using spi, i2c or any serial other than USB, are there any other alternatives for serial data and clock that would further simplify the code (unused prop pins?) ? The serial shift speed (clock low) on the downstream device clock is 7ns so the tuning word of 48 bits can go out at something greater than 1Mhz.
I think the following will work as a 32 bit shiftin/shiftout (MSb first) with a single register (called Shifter) preloaded with your value
The InMask bit must have an IN direction, and the OutMask bit must have an OUT direction.
If the single instruction clock is too fast, then you can separate the clockset and clockclear instructions by locating them elsewhere inside the loop.
Cheers,
Peter (pjv)
That's some nice code.
FYI, the "test" statement is an "and" without writing so your:
could be written:
I mainly say this in case others here are confused about why one of us use test and one uses and (as I would have likely been a few days ago).
I think there may be some devices that can not be read from and written to during the same position of the clock pulse. I noticed, I set the output pin prior to the rising clock edge and read from the device after the clock goes high, but after checking the datasheet (for the Nordic nRF24L01+) I see the I could also read prior to the rising clock pulse.
I can't think of any SPI devices off-hand where your code couldn't be used, but I wouldn't be surprised if they exist.
I think you just made it possible to speed up several of my drivers, thank you.