1
\$\begingroup\$

I wrote the following program to turn an LED on and off at 1-second intervals:

#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
 DDRB = 0b00100000;
 for (;;) {
 PORTB = 0b00100000;
 _delay_ms(1000);
 PORTB = 0b00000000;
 _delay_ms(1000);
 }
 return 0;
}

I tried disassembling the binary file of this code using the avr-objdump of which the output is:

00000080 <main>:
 80: 80 e2 ldi r24, 0x20 ; 32
 82: 84 b9 out 0x04, r24 ; 4
00000084 <.L2>:
 84: 85 b9 out 0x05, r24 ; 5
 86: 2f ef ldi r18, 0xFF ; 255
 88: 33 ed ldi r19, 0xD3 ; 211
 8a: 90 e3 ldi r25, 0x30 ; 48
0000008c <.L1^B1>:
 8c: 21 50 subi r18, 0x01 ; 1
 8e: 30 40 sbci r19, 0x00 ; 0
 90: 90 40 sbci r25, 0x00 ; 0
 92: e1 f7 brne .-8 ; 0x8c <.L1^B1>
 94: 00 c0 rjmp .+0 ; 0x96 <L0^A>
00000096 <L0^A>:
 96: 00 00 nop
 98: 15 b8 out 0x05, r1 ; 5
 9a: 2f ef ldi r18, 0xFF ; 255
 9c: 33 ed ldi r19, 0xD3 ; 211
 9e: 90 e3 ldi r25, 0x30 ; 48
000000a0 <.L1^B2>:
 a0: 21 50 subi r18, 0x01 ; 1
 a2: 30 40 sbci r19, 0x00 ; 0
 a4: 90 40 sbci r25, 0x00 ; 0
 a6: e1 f7 brne .-8 ; 0xa0 <.L1^B2>
 a8: 00 c0 rjmp .+0 ; 0xaa <L0^A>
000000aa <L0^A>:
 aa: 00 00 nop
 ac: eb cf rjmp .-42 ; 0x84 <.L2>
000000ae <_exit>:
 ae: f8 94 cli
000000b0 <__stop_program>:
 b0: ff cf rjmp .-2 ; 0xb0 <__stop_program>

My understanding of the above assembly code is:

  • the two lines under 00000080 <main>: sets the data direction of PB5 to output.
  • 00000084 <.L2>: section turns the LED on.
  • 0000008c <.L1^B1>: waits for 1 second (first 4 lines) which then jumps to 00000096 <L0^A>:
  • 00000096 <L0^A>: turns the LED off by writing the contents of r1 (which is currently 0s) to PB5
  • then 000000a0 <.L1^B2>: waits for 1 second and jumps to 000000aa <L0^A>:
  • 000000aa <L0^A>: spends one clock cycle and jumps to 00000084 <.L2>: which turns the LED on. So on and so forth.

Questions:

  1. Is my understanding of the assembly code correct?
  2. What is the purpose of a nop sometimes as the first instruction?
asked Feb 22, 2023 at 13:01
\$\endgroup\$
5
  • \$\begingroup\$ Have you checked the data sheets to see if R24 is a data direction register? \$\endgroup\$ Commented Feb 22, 2023 at 13:13
  • \$\begingroup\$ What is your goal? If you want to learn assembly, I don't recommend this method. Compilers often produce code that is harder to understand than assembly code generated by humans. \$\endgroup\$ Commented Feb 22, 2023 at 13:26
  • 1
    \$\begingroup\$ @Andyaka I checked the datasheet and thought that 0x04 is the data direction register. I thought that I'm writing the contents of r24 to 0x04, I may be wrong... \$\endgroup\$ Commented Feb 22, 2023 at 13:38
  • 1
    \$\begingroup\$ @kovac you are right: r24 is often used as a temporary register. Data direction register B is at IO address 4, ie, when using OUT. (And also at memory address 0x24, for when using ST.) It's a pecularity of this CPU that some registers appear in both IO and memory address spaces, but with different addresses. \$\endgroup\$ Commented Feb 22, 2023 at 13:55
  • \$\begingroup\$ Take a look here godbolt.org/z/9jTd7sdnj \$\endgroup\$ Commented Feb 22, 2023 at 16:26

1 Answer 1

2
\$\begingroup\$
  1. In general, yes, but disassembling the raw binary may not be very fruitful, as you could just look at the compiler output listing which includes the C source code and generated assembly opcodes.

  2. You ask for 1000 millisecond delay, which is done by looping 3199999 times. As the loop will be a few clock cycles less than 1000 milliseconds, it adds extra useless RJMP and NOP opcodes to waste a few clock cycles to end up closer to 1000 milliseconds.

answered Feb 22, 2023 at 13:19
\$\endgroup\$
2
  • \$\begingroup\$ For 1., how do I get this? \$\endgroup\$ Commented Feb 22, 2023 at 13:40
  • 1
    \$\begingroup\$ Most C compilers support -S for making the assmbler file filename.s from filename.c. If you're using the avr toolset, avr-gcc -S -Os -mmcu=atmega328 -c filename.c is likely to give you useful output. Also look at assembler listing output: avr-as -mmcu=atmega328 -o filename.o -a=filename.lst filename.s \$\endgroup\$ Commented Feb 22, 2023 at 13:50

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.