# Even or odd, count the set bits, multiply by shifting

[Courses](https://asm-editor.specy.app/learn/courses.md) › [Z80 assembly](https://asm-editor.specy.app/learn/courses/z80.md) › Examples

Web page: https://asm-editor.specy.app/learn/courses/z80/examples/bit-tricks

> Four questions about one byte answered with a bit test, three doublings of a pair, a mask and a loop that reads the carry flag.

The same program in: [M68K](https://asm-editor.specy.app/learn/courses/m68k/examples/bit-tricks.md), [MIPS](https://asm-editor.specy.app/learn/courses/mips/examples/bit-tricks.md), [RISC-V](https://asm-editor.specy.app/learn/courses/risc-v/examples/bit-tricks.md), [x86-64](https://asm-editor.specy.app/learn/courses/x86/examples/bit-tricks.md)

One byte can answer four questions. Is 183 odd, what is it times eight, what are its bottom four
bits, and how many of its eight bits are ones? The answers land in `d`, `hl`, `e`, and `c`.

Open in the editor, choose **Build**, then use **Run** for the final values or **Step** to follow
the flags and registers as they change. The registers panel displays hexadecimal.

```z80
N   equ 183

    .org 0x8000
    ld a, N         ; n = 183, which is 0b10110111

    ld d, 0
    bit 0, a        ; is the lowest bit set?
    jr z, even      ; Z is 1 when the bit is 0
    ld d, 1         ; d = 1 when n is odd
even:

    ld l, a
    ld h, 0         ; widen unsigned a into hl
    add hl, hl
    add hl, hl
    add hl, hl      ; n * 8, three doublings

    ld c, 0         ; bits = 0
    ld b, 8         ; eight of them
count:
    srl a           ; the lowest bit falls into C
    jr nc, no_bit
    inc c           ; bits++
no_bit:
    djnz count

    ld a, N
    and 0x0F        ; the low four bits on their own
    ld e, a
    halt
```

`bit 0, a` asks whether the lowest bit is set without changing `a`. It sets `Z` backwards from
the question: `Z` is 1 when that bit is 0. Thus `jr z, even` takes the even route, while the
default value has its lowest bit set and leaves `d = 01`.

The two instructions `ld l, a` and `ld h, 0` widen unsigned `a` into `hl`. This is needed because
183 times 8 is 1464, too large for a byte. Each `add hl, hl` doubles the whole 16-bit pair, so
three of them leave `hl = 05B8`. The Z80's single-register shift instructions such as `srl` do
not take `hl`; `add hl, hl` is the short way to double this pair.

`and 0x0F` keeps only the bits where the mask has ones. For example, `0xB6 & 0x0F = 0x06`.
With this program's `0xB7`, the same mask leaves `07`, so `e = 07`. A mask can isolate any packed
field; a field above the low bits also needs shifting down afterward.

The loop counts one bit on each pass. On its first pass, `a` is `B7`; `srl a` changes it to `5B`
and puts the bit that fell off, `1`, in the C flag. `jr nc` therefore does not jump and `inc c`
makes the count `01`. On a pass where the outgoing bit is 0, C is clear, `jr nc` jumps, and the
count stays as it is. After eight shifts every bit has fallen out of `a`, and `c = 06` because
`10110111` has six ones.

Change `N equ 183` to `N equ 180`. Before you build and run, predict `d`, `hl`, `e`, and `c` in
hexadecimal.

<details>
<summary>Check your answer</summary>

`d = 00` because 180 is even. `hl = 05A0` because `0xB4 × 8 = 0x05A0`; `e = 04` from the low
four bits; and `c = 04` because `B4` has four set bits.

</details>

## Instructions in this Lecture

- Z80: [`ld`](https://asm-editor.specy.app/documentation/z80/instruction/ld.md), [`bit`](https://asm-editor.specy.app/documentation/z80/instruction/bit.md), [`jr`](https://asm-editor.specy.app/documentation/z80/instruction/jr.md), [`add`](https://asm-editor.specy.app/documentation/z80/instruction/add.md), [`srl`](https://asm-editor.specy.app/documentation/z80/instruction/srl.md), [`inc`](https://asm-editor.specy.app/documentation/z80/instruction/inc.md), [`djnz`](https://asm-editor.specy.app/documentation/z80/instruction/djnz.md), [`and`](https://asm-editor.specy.app/documentation/z80/instruction/and.md), [`halt`](https://asm-editor.specy.app/documentation/z80/instruction/halt.md)

Previous: [Multiply and divide, with the remainder](https://asm-editor.specy.app/learn/courses/z80/examples/multiply-and-divide.md)

Next: [A subroutine with its arguments in registers](https://asm-editor.specy.app/learn/courses/z80/examples/subroutine-with-register-arguments.md)
