# The largest element

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

Web page: https://asm-editor.specy.app/learn/courses/m68k/examples/max-of-an-array

> One walk through eight words, keeping the best one seen so far and where it was, with a negative number in there to make the signed condition matter.

The same program in: [MIPS](https://asm-editor.specy.app/learn/courses/mips/examples/max-of-an-array.md), [RISC-V](https://asm-editor.specy.app/learn/courses/risc-v/examples/max-of-an-array.md), [Z80](https://asm-editor.specy.app/learn/courses/z80/examples/max-of-an-array.md), [x86-64](https://asm-editor.specy.app/learn/courses/x86/examples/max-of-an-array.md)

Eight words sit in memory. This program reads each one and keeps the largest value seen so far in
`d0`. It keeps that value's **zero-based index** in `d3`: the first element has index 0, the second
has index 1, and so on. One value is negative, so the choice of signed comparison matters.

The previous sum example carried a running total from one pass to the next. Here the loop carries
both the best value and its index. Each new word either replaces that pair or leaves it alone.

```m68k
count equ 8

    lea numbers, a0     ; a0 points at the first element
    clr.l d0            ; clear the upper word before loading a word
    move.w (a0)+, d0    ; best = numbers[0]
    clr.l d3            ; index of the best value = 0
    clr.l d4            ; index of the element being checked = 0
    move.l #count-2, d1 ; 6 gives seven passes with dbra
loop:
    addq.w #1, d4       ; move to the next index
    move.w (a0)+, d2    ; read the next word, then advance a0
    cmp.w d0, d2        ; compare this word with the best: d2 - d0
    ble not_bigger      ; signed: keep the best if this word <= it
    move.w d2, d0       ; new best value
    move.w d4, d3       ; new best index
not_bigger:
    dbra d1, loop

    org $2000
numbers: dc.w 12, -4, 37, 8, 99, 41, 2, 60
```

`org $2000` places the eight words at `$2000` through `$200F`, two bytes per word. The first
`move.w (a0)+, d0` reads 12 and moves `a0` to `$2002`. This gives the program a best value before
the loop starts. Starting the best at 0 would give the wrong answer if every element were negative.

Seven elements remain. The loop starts its `dbra` counter at `count-2`, or 6, so its seven passes
check the words at indices 1 through 7. `d4` advances to each index before that word is read.
`cmp.w d0, d2` prepares the flags from `d2 - d0` without changing either value. If the new word is
less than or equal to the best, `ble` skips both assignments. An equal value therefore keeps the
earlier index.

`move.w` writes only the low 16 bits of a data register. Clearing all of `d0` first makes its full
register display predictable when the positive word 12 is loaded; the later word moves replace only
that low word. `d3` and `d4` are also cleared as full registers before their word-sized updates, and
the long move initializes all of `d1`.

## Run it and follow the best value

Select **Build**, then **Run**. In the registers panel, `d0` is `00000063` (hexadecimal `$63` is
decimal 99) and `d3` is `00000004`: 99 is the fifth element, at index 4. `a0` is `00002010`, just
past the last word, and `d1` is `0000FFFF`. The loop does not read from `$2010`.

Select **Build** again to reset the program, then select **Step** once per instruction. After the
first read, `d0` is `0000000C` (12) and `a0` is `00002002`. On the first loop pass, `d4` becomes 1,
`d2` receives the word `FFFC` (-4), and `a0` advances to `00002004`. The signed `ble` is taken, so
`d0` stays 12 and `d3` stays 0. The first `dbra` changes `d1` from 6 to 5 and returns to `loop`.

Keep stepping until the word 99 is read from `$2008`. At that point `d4` is 4 and `a0` is
`0000200A`. Its comparison is greater, so the two moves put `00000063` in `d0` and `00000004` in
`d3`. The remaining words do not change that pair.

## Try an unsigned comparison

Change `ble not_bigger` to `bls not_bigger`, the unsigned “lower or same” condition. Before selecting
**Build** and **Run**, predict which value and index will remain in `d0` and `d3`. Think about the
bit pattern `FFFC`: as an unsigned word, is it smaller or larger than 12?

<details>
<summary>Show answer</summary>

`d0` ends at `0000FFFC` and `d3` at `00000001`. Read as an unsigned word, `FFFC` is 65532. The
unsigned comparison treats it as larger than every other word in this array, so the value at index
1 remains the best. The original signed `ble` treats the same bits as -4.

</details>

## Instructions in this Lecture

- M68K: [`lea`](https://asm-editor.specy.app/documentation/m68k/instruction/lea.md), [`clr`](https://asm-editor.specy.app/documentation/m68k/instruction/clr.md), [`move`](https://asm-editor.specy.app/documentation/m68k/instruction/move.md), [`addq`](https://asm-editor.specy.app/documentation/m68k/instruction/addq.md), [`cmp`](https://asm-editor.specy.app/documentation/m68k/instruction/cmp.md), [`ble`](https://asm-editor.specy.app/documentation/m68k/instruction/ble.md), [`dbra`](https://asm-editor.specy.app/documentation/m68k/instruction/dbra.md)

Previous: [Sum of an array](https://asm-editor.specy.app/learn/courses/m68k/examples/sum-of-an-array.md)

Next: [Length of a string](https://asm-editor.specy.app/learn/courses/m68k/examples/string-length.md)
