Problem with modulo (%) and reset

ah hah! This had all the signs of a watchdog problem, except that those are supposed to be all fixed on Uno. And looking at the code, it does look like they should indeed be fixed.

Except...

The C compiler uses register 1 (R1) as a "known zero" in most places. Functions that use it for something else are supposed to save and restore it, so any particular C function, like main(), knows it can assume that R1 contains a zero. R1 is initialized in the startup code that happens before main() happens (which is before setup() or loop() as well.)

The optiboot bootloader suppresses the normal startup code. R1 does not get set to zero.

The first thing done in the bootloader is to reset the watchdog timer "MCUSR = 0;", which compiles to "out 0x34, R1" - it assumes that R1 contains a zero!

RESET does not set register contents to zero.

If a reset occurs while R1 contains certain values, (bit 1 set), the bootloader will not restart the sketch.

The divide library function uses R1 as a loop counter.

The following sketch shows the same behavior:

void setup() {
  asm("ldi r30, 2\n"
  "mov r1, r30\n");
  while (1);
}

void loop() {
}

This is actually a bug in the bootloader. I don't see any way to fix it in the main Arduino code...