 # Extracting bitfields

#1

Here’s a useful routine bits I wrote for the uLisp RISC-V assembler, but it has applications in programming for microcontroller boards such as the Arduino. It extracts a single bit, or a bit field of several bits, from the number provided as its first parameter:

``````(defun bits (x a &optional b)
(if b (logand (ash x (- b)) (1- (ash 1 (- a b -1))))
(logand (ash x (- a)) 1)))
``````

To extract a single bit provide the bit position of the bit as the second argument; for example:

``````> (bits #b1001011001010011 4)
1
``````

To extract a bitfield, specify the starting and ending bit positions, inclusive; for example:

``````> (format t "~b" (bits #b1001011001010011 6 2))
10100
``````

Note that I’m taking advantage of the ~b format directive added in uLisp 3.5 to show the result in binary.

#2

Looks similar to `ldb`, although that doesn’t have the reversing ability.

`ldb` and `dpb` are CL functions that would definitely be useful in uLisp.

#3

I’ll need to read about `ldb` and `dpb` - thanks!

Just realised bits can be written more simply:

``````(defun bits (x a &optional (b a))
(logand (ash x (- b)) (1- (ash 1 (- a b -1)))))
``````

#4

`ldb` and `dpb`, for reference.

They sorta-depend on the additional function `byte`, because they take an implementation-defined representation of what a byte is. (CL had a lot of legacy stuff to contend with.) SBCL uses a simple cons cell, though, which I imagine is inherited from CMUCL.

#5

It looks like:

``````(ldb (byte length position) arg)
``````

is equivalent to my:

``(bits arg (+ position length -1) position)``