BIT TESTING¶
Bit testing is a major component of embedded programs, here we examine the default bit testing Words available in Mecrisp-Stellaris.
Note
1 or -1 = True and 0 = False.
Bit Testing Words¶
There are three alternatives, BIT@, CBIT@ and HBIT@. Their differences are the size of the data they fetch when testing. Otherwise they are all identical in that they use a BIT MASK and the contents of an ADDRESS to test a particular BIT for TRUE (or 1). They then leave a FLAG on the stack representing the outcome of the test.
Word |
Test Data Size |
---|---|
bit@ |
LDR Rt, [Rn, <Rm|#imm>] Load register with word |
cbit@ |
LDRB Rt, [Rn, <Rm|#imm>] Load register with byte |
hbit@ |
LDRH Rt, [Rn, <Rm|#imm>] Load register with halfword |
BIT@¶
The disassembles below show the design of the three bit test Words which are identical apart from whether they load a word, byte or halfword.
see bit@
00001A98: CF01 ldmia r7 { r0 }
00001A9A: 6836 ldr r6 [ r6 #0 ]
00001A9C: 4006 ands r6 r0
00001A9E: 3E01 subs r6 #1
00001AA0: 41B6 sbcs r6 r6
00001AA2: 43F6 mvns r6 r6
00001AA4: 4770 bx lr
Bytes: 14 ok.
CBIT@¶
see cbit@
00001C80: CF01 ldmia r7 { r0 }
00001C82: 7836 ldrb r6 [ r6 #0 ]
00001C84: 4006 ands r6 r0
00001C86: 3E01 subs r6 #1
00001C88: 41B6 sbcs r6 r6
00001C8A: 43F6 mvns r6 r6
00001C8C: 4770 bx lr
Bytes: 14 ok.
HBIT@¶
see hbit@
00001B8C: CF01 ldmia r7 { r0 }
00001B8E: 8836 ldrh r6 [ r6 #0 ]
00001B90: 4006 ands r6 r0
00001B92: 3E01 subs r6 #1
00001B94: 41B6 sbcs r6 r6
00001B96: 43F6 mvns r6 r6
00001B98: 4770 bx lr
Bytes: 14 ok.
Testing¶
A hex test number, $23456789 is saved to a variable named “test1”.
$23456789 variable test1
$23456789 shown in binary:¶
test1 @ bin1.
3|3|2|2|2|2|2|2|2|2|2|2|1|1|1|1|1|1|1|1|1|1|
1|0|9|8|7|6|5|4|3|2|1|0|9|8|7|6|5|4|3|2|1|0|9|8|7|6|5|4|3|2|1|0
0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1
BIT@¶
As shown in the disassembly above, a 32 bit word or ‘CELL’ is fetched for this test and loaded into register R6.
“bit@” requires two input parameters and places a flag (True or False) on the Stack depending on the result.
Bit@ Stack Diagram¶
bit@ ( mask a-addr - - flag ) Test Bit in word-location
Parameters¶
mask; bits 0 to 32 which are the bit positions to be tested
a-addr; the memory address of a register, variable etc.
Testing Results¶
-1 ($FFFFFFFF) = TRUE, and 0 = FALSE
0 bit test1 bit@ . -1 ok.
1 bit test1 bit@ . 0 ok.
Note
the Word “bit” simply turns a bit position into a bit value. i.e. bit position 0 is actually bit 1. Bit position 1 is actually bit 2 and so on.
CBIT@¶
As shown in the disassembly above, a 8 bit ‘character’ (or byte) is fetched and loaded into register R6. All bits above bit 7 are filled with zeros.
cbit@ Stack Diagram¶
cbit@ ( mask c-addr - - flag ) Test Bits in byte-location
Why would we use cbit@ to test a bit instead of bit@ ?
Example¶
Perhaps a project quickly reads 16 bytes into a buffer and then tests various bits ?
In this example the buffer data is $00 - $0F
$F buffer: data
: data! ( c # -- ) data + c! ;
$00 0 data!
$01 1 data!
$02 2 data!
$03 3 data!
$04 4 data!
$05 5 data!
$06 6 data!
$07 7 data!
$08 8 data!
$09 9 data!
$0A $A data!
$0B $B data!
$0C $C data!
$0D $D data!
$0E $E data!
$0F $F data!
Testing Results¶
index, bit, array
1 0 data + cbit@ . 0 ok. \ should = false
1 1 data + cbit@ . -1 ok. \ should = true
3 2 data + cbit@ . -1 ok. \ should = true
3 1 data + cbit@ . -1 ok. \ should = true
3 0 data + cbit@ . 0 ok \ should = false
HBIT@¶
As shown in the disassembly above, a 16 bit ‘HALFWORD’ is fetched and loaded into register R6. All bits above bit 16 are filled with zeros.
HBIT@ could possibly be used to read a buffer full of GPIO bits but would otherwise be utilised in a similar way to CBIT@ above.
That exercise is left to the reader.