Skip to main content
Arduino

Return to Revisions

2 of 2
+ difference between disassembly and compilation to asm.
Edgar Bonet
  • 45.1k
  • 4
  • 42
  • 81

This looks like a bug in the toolchain: an off-by-one error in all relative jumps. For example, the main loop:

loop {
 write_reg(portB, 1 << LED_BUILTIN, 1 << LED_BUILTIN);
 delay(500_0000);
 write_reg(portB, 0, 1 << LED_BUILTIN);
 delay(500_0000);
}

got translated to this by RUSTFLAGS="--emit asm":

.LBB1_1:
 sbi 5, 5
 call _ZN13arduino_blink5delay17h9627a982856e7dadE
 cbi 5, 5
 call _ZN13arduino_blink5delay17h9627a982856e7dadE
 rjmp .LBB1_1

which looks correct to me. However, on the disassembly of the final program, it looks like this:

 b0: 2d 9a sbi 0x05, 5 ; PORTB |= (1<<5);
 b2: 0e 94 40 00 call 0x80 ; loop: delay();
 b6: 2d 98 cbi 0x05, 5 ; PORTB &= ~(1<<5);
 b8: 0e 94 40 00 call 0x80 ; delay();
 bc: fa cf rjmp .-12 ; goto loop; // 0xb2

The instruction that turns the LED on is now out of the loop. There are other similar off-by-one errors within the delay function, on the instructions brcs, breq and rjmp.

I have no idea how to solve this, other than looking at the bug tracker of the AVR Rust toolchain.

Edit: The Arduino IDE does not come with a Rust compiler. You are thus using a separate, presumably experimental, compiler. My guess is that, unless explicitly asked to --emit asm, this Rust compiler compiles directly to machine code. It is pretty common nowadays to skip the assembly language and compile from a high-level language directly to machine code.

The first assembly snippet was obtained with --emit asm. It is not really a "disassembly", but the result of a direct Rust → asm translation. The second snipped, generated by avr-objdump is a proper disassembly: the result of a Rust → machine code → asm translation.

My guess is that the bug lies in the Rust → machine code translation, which is why it does not affect the --emit asm output. Relative jumps on AVR are a bit unintuitive: they are relative to the program counter, which is a CPU register holding the address of the next instruction in the program. If you incorrectly assume these jumps are relative to the current instruction, you get precisely the faulty code of the second snippet.

Edgar Bonet
  • 45.1k
  • 4
  • 42
  • 81

AltStyle によって変換されたページ (->オリジナル) /