Show understanding of how bit manipulation can be used to monitor and control a device, and be able to implement the techniques in both a high‑level language (C/Python) and the Cambridge assembly language (9618).
0b1111 0110 = 0xF6 = –10 in two’s‑complement (8‑bit).| Operator | Name | Effect |
|---|---|---|
| & | AND | Result bit = 1 only if both operands are 1. |
| | | OR | Result bit = 1 if either operand is 1. |
| ^ | XOR | Result bit = 1 if the operands differ. |
| ~ | NOT | Flips every bit (two’s‑complement representation). |
| << | Logical left shift | Moves bits left, inserting 0s on the right; MSB is discarded (or placed in the carry flag). |
| >> | Logical right shift | Moves bits right, inserting 0s on the left; LSB is discarded (or placed in the carry flag). |
| arith >> | Arithmetic right shift | Preserves the sign bit when shifting a signed value. |
| rol / ror | Rotate left / right | Cyclic shift – bits that fall off one end re‑appear on the opposite end; no loss of information. |
val << 1 multiplies an unsigned value by 2. The original MSB is lost; the processor may set the carry flag (C) to the discarded bit.val >> 1 divides an unsigned value by 2, inserting 0 at the MSB.val >> 1 on a signed two’s‑complement value copies the sign bit into the new MSB, preserving the sign.rol val moves every bit left; the original MSB becomes the new LSB.ror val moves every bit right; the original LSB becomes the new MSB.Assume an 8‑bit I/O register PORTA located at address $20. A typical mapping is shown below.
Bit 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| | | | |LED1|LED0|SW1|SW0|
+---+---+---+---+---+---+---+---+
| Symbol | Meaning |
|---|---|
| PORTA | I/O register (8‑bit) |
| ACC | Accumulator (working register) |
| MAR←PC | Memory address register receives program counter |
| PC←PC+1 | Program counter increments |
| ACC←PORTA | Read register into accumulator |
| PORTA←ACC | Write accumulator back to register |
A mask isolates or modifies particular bits. The mask for a single bit at position n is 1 << n. Masks can also cover a field of several bits.
| Name | Bit(s) | Mask (binary) | Mask (hex) |
|---|---|---|---|
| LED0 | 2 | 0b00000100 | 0x04 |
| LED1 | 3 | 0b00001000 | 0x08 |
| SW0 | 0 | 0b00000001 | 0x01 |
| SW1 | 1 | 0b00000010 | 0x02 |
| MODE (bits 4‑6) | 4‑6 | 0b01110000 | 0x70 |
// Set MODE bits (bits 4‑6) to value 5 (binary 101)uint8_t mode = 5; // 0b101
PORTA = (PORTA & ~0x70) | (mode << 4);
// ^ clear field ^ insert new value
// Test whether Switch 1 (SW1) is HIGHif (PORTA & 0x02) { // 0x02 = 1 << 1
// switch is high
}
PORTA |= 0x04; // OR with mask
// Turn LED0 OFF (clear bit 2)
PORTA &= ~0x04; // AND with inverted mask
// Toggle LED1 (invert bit 3)
PORTA ^= 0x08; // XOR with mask
// C styleif (STATUS_REG & 0x80) { // bit 7 = over‑temperature?
CONTROL_REG |= 0x01; // start cooling fan (bit 0)
}
;--- test bit 7 of STATUS_REG (direct address $30) -----------------LDA $30 ; ACC ← STATUS_REG
AND #$80 ; test over‑temperature flag
BEQ noAlarm ; branch if flag = 0
;--- set fan‑ON bit (bit 0 of CONTROL_REG at $31) ---------------
LDA $31 ; ACC ← CONTROL_REG
ORA #$01 ; set bit 0
STA $31 ; write back
noAlarm:
while (1) {uint8_t sw = PORTA & 0x03; // read SW0‑SW1
PORTA = (PORTA & ~0x0C) | (sw << 2); // mirror switches onto LEDs
}
// Bits in SENSOR_STATUS (address $40)// 7 – Over‑temperature alarm
// 6 – Sensor fault
// 5‑0 – Reserved
if (SENSOR_STATUS & 0x80) { // alarm?
CONTROL_REG |= 0x02; // fan ON (bit 1)
} else {
CONTROL_REG &= ~0x02; // fan OFF
}
uint8t raw = DEVSTATUS; // read once (address $50)uint8_t errorCode = (raw & 0xF0) >> 4; // bits 7‑4
bool dataReady = (raw & 0x08) != 0; // bit 3
bool overflow = (raw & 0x04) != 0; // bit 2
In many 8‑bit processors the bit shifted out of the MSB is placed in the carry flag (C). The flag can be examined to decide whether an overflow occurred.
LDA $20 ; ACC ← PORTA (example value 0x90)ASL ; arithmetic shift left – same as logical left for unsigned
BCC noOverflow ; branch if Carry = 0 (no overflow)
; overflow handling code here
noOverflow:
STA $20 ; store shifted result
;--- set LED0 (bit 2) ---------------------------------------------LDA $20 ; ACC ← PORTA (ACC←PORTA)
ORA #$04 ; ACC ← ACC OR 0x04 (ACC←ACC|mask)
STA $20 ; PORTA ← ACC (PORTA←ACC)
;--- clear LED0 -----------------------------------------------
LDA $20
AND #$FB ; mask = ~0x04
STA $20
;--- toggle LED1 -----------------------------------------------
LDA $20
EOR #$08 ; XOR with mask
STA $20
;--- test‑and‑set example (over‑temperature → fan) ---------------
LDA $30 ; ACC ← STATUS_REG
AND #$80
BEQ noAlarm
LDA $31 ; ACC ← CONTROL_REG
ORA #$01
STA $31
noAlarm:
1 << n.&, |, ^, ~ to test, set, clear and toggle flags.1 << n (e.g., 0x04 for bit 2).((1 << width)‑1) << lowPos (e.g., 0x70 for bits 4‑6).& to test, | to set, &~ to clear, and ^ to toggle individual or grouped bits.&&, ||) to make multi‑condition decisions.#mask) for constants.$addr) for registers.Your generous donation helps us continue providing free Cambridge IGCSE & A-Level resources, past papers, syllabus notes, revision questions, and high-quality online tutoring to students across Kenya.