Next, we arrive at mask-field. This accessor returns a number which has the masked-off bits set to zero. It is also setf-able, meaning that it can be used to emulate the behaviour of deposit-field, but changing the integer in place. Note that in the setf case, as with deposit-field, the byte specifier acts on the inserted number as well. I’m going to show the Lisp code and the equivalent C code, for clarity:
CL-USER> (let* ((orig #xffffffff) (mask-width 10) (mask-shift 5) (mask (byte mask-width mask-shift))) (format t "Masked off part is: #x~X~%" (mask-field mask orig)) (format t "orig is unchanged: #x~X~%" orig) (format t "deposit-field #x100: #x~X~%" (deposit-field #x100 mask orig)) (format t "Setting the masked part to #x100...~%") (setf (mask-field mask orig) #x100) (format t "orig is now: #x~X~%" orig)) Masked off part is: #x7FE0 orig is unchanged: #xFFFFFFFF deposit-field #x100: #xFFFF811F Setting the masked part to #x100... orig is now: #xFFFF811F NIL
And the C:
#include <stdio.h> #include <stdint.h> int main(void) { uint32_t orig = 0xffffffff; uint32_t mask = 0x7fe0; uint32_t inserting = 0x100; printf("Masked off part is: 0x%x\n", orig & mask); printf("orig is unchanged: 0x%x\n", orig); printf("Setting the masked part to 0x100...\n"); orig = ( orig & ~mask ) | (inserting & mask); printf("orig is now 0x%x\n", orig); return 0; }
producing output:
$ ./mask-field Masked off part is: 0x7fe0 orig is unchanged: 0xffffffff Setting the masked part to 0x100... orig is now 0xffff811f