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

  1. mask; bits 0 to 32 which are the bit positions to be tested

  2. 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.