• AVR Freaks

AnsweredHot!Disassembly listings in XC8

Starting Member
  • Total Posts : 50
  • Reward points : 0
  • Joined: 2013/07/06 06:06:17
  • Location: 0
  • Status: offline
2020/07/08 03:32:15 (permalink)

Disassembly listings in XC8


On XC8 with an ATMEGA328PB, I'm trying to follow where the code jumps to in memory when it calls a function.  When the code is supposed to jump to a function I get the assembler call "CALL __eeprom_end".  But when I check further in the disassembler listing I see that my function begins at address 0x007A.  That doesn't seem to be the "end of eeprom" to me.  

I contrast the disassembly listing to the Program Memory view and notice something strange.  In the Program Memory view, at address 0x006E I have opcode 940E and that corresponds to "CALL __eeprom_end" while in the next memory location, 0x006F, I have the actual memory location of the function... 0x007A.

So, it appears that the disassembler process is not taking into account the value at the adjacent memory location and is, therefore, giving me an incorrect disassemble.  I've quoted the disassembly listing below and attached the Program Memory view as an image attachment.

Does someone know if there is a better way to display the disassembly listings?

Here's the disassembly listing:
---  /Users/jasmith/MPLABXProjects/book_for_basic_example.X/newmain.c  ----------------------------------
1:             #include <stdint.h>     // ISO integers
2:             #include <stdlib.h>
3:             #include <stdbool.h>
4:             #include <math.h>
5:             #include <xc.h>
7:             int my_function(void);
9:             int main(void)
10:            {
0066  93CF     PUSH R28
0067  93DF     PUSH R29
0068  D000     RCALL 0x69
0069  B7CD     IN R28, 0x3D
006A  B7DE     IN R29, 0x3E
11:                volatile int the_return_value = 0;
006B  821A     STD Y+2, R1
006C  8219     STD Y+1, R1
13:                __asm("NOP");
006D  0000     NOP
14:                the_return_value = my_function();
006E  940E     CALL __eeprom_end
0070  839A     STD Y+2, R25
0071  8389     STD Y+1, R24
15:                __asm("NOP");
0072  0000     NOP
17:                return EXIT_SUCCESS;
0073  E080     LDI R24, 0x00
0074  E090     LDI R25, 0x00
18:            }
0075  900F     POP R0
0076  900F     POP R0
0077  91DF     POP R29
0078  91CF     POP R28
0079  9508     RET
20:            int my_function(void)
21:            {
007A  93CF     PUSH R28
007B  93DF     PUSH R29
007C  B7CD     IN R28, 0x3D
007D  B7DE     IN R29, 0x3E
22:                __asm("NOP");
007E  0000     NOP
24:                return 1;
007F  E081     LDI R24, 0x01
0080  E090     LDI R25, 0x00
25:            }
0081  91DF     POP R29
0082  91CF     POP R28
0083  9508     RET

 I'm using MPLAB X 5.35 with XC8 2.20.  I've turned on "load symbols when programming or building for production" in Preferences->Conf->Loading.

I contrast this to the output from Compiler Explorer, where I don't get a specific memory location show in the disassembly, but I do get a label that makes sense ("call my_function" points to the label "my_function").  You can see the Compiler Explorer output in the attached image.


post edited by onnimikki - 2020/07/08 03:35:25

Attached Image(s)

Super Member
  • Total Posts : 1249
  • Reward points : 0
  • Joined: 2010/12/12 17:48:27
  • Location: Brisbane, Australia
  • Status: offline
Re: Disassembly listings in XC8 2020/07/08 14:52:16 (permalink) ☼ Best Answerby onnimikki 2020/07/09 11:55:49
+2 (2)
If this is the disassembly listing created by the IDE, just be aware that it will be trying to substitute in symbols where ever possible to make the code more readable. However, if there is more than one symbol which has the numerical address used in the call, for example, then it might have to guess which symbol is correct, and it might guess this incorrectly. The code is still correct, though.
The disassembly listing has also left out the second half of the call, whereas both words are shown in the program memory view. This is done to make things a bit tidier. You will notice that the address 0x6F is simply not shown in the listing.
If you want to get a full listing 'straight from the horses mouth', then you can run the avr-objdump utility (shipped with the compiler) on the elf file, but you might actually find the output of this harder to follow.
Starting Member
  • Total Posts : 50
  • Reward points : 0
  • Joined: 2013/07/06 06:06:17
  • Location: 0
  • Status: offline
Re: Disassembly listings in XC8 2020/07/09 10:51:30 (permalink)
Hi Jeff,
that's a good suggestion.  So I ran
/Applications/microchip/xc8/v2.20/avr/bin/avr-objdump -xdStm avr5 book_for_basic_example.X.production.elf > listing.lst
on the elf file. The result is relatively short and readable, and at the end I found the main function and the other function I wrote.  Seems a bit better than the MPLAB X disassembly output ... at least the call leads to a consistent memory address.
 000000cc <main>:
#include <xc.h>

int my_function(void);

int main(void)
  cc:   cf 93           push    r28
  ce:   df 93           push    r29
  d0:   00 d0           rcall   .+0             ; 0xd2 <main+0x6>
  d2:   cd b7           in      r28, 0x3d       ; 61
  d4:   de b7           in      r29, 0x3e       ; 62
    volatile int the_return_value = 0;
  d6:   1a 82           std     Y+2, r1 ; 0x02
  d8:   19 82           std     Y+1, r1 ; 0x01

  da:   00 00           nop
    the_return_value = my_function();
  dc:   0e 94 7a 00     call    0xf4    ; 0xf4 <my_function>
  e0:   9a 83           std     Y+2, r25        ; 0x02
  e2:   89 83           std     Y+1, r24        ; 0x01
  e4:   00 00           nop

    return EXIT_SUCCESS;
  e6:   80 e0           ldi     r24, 0x00       ; 0
  e8:   90 e0           ldi     r25, 0x00       ; 0
  ea:   0f 90           pop     r0
  ec:   0f 90           pop     r0
  ee:   df 91           pop     r29
  f0:   cf 91           pop     r28
  f2:   08 95           ret
Disassembly of section .text.my_function:

000000f4 <my_function>:

int my_function(void)
  f4:   cf 93           push    r28
  f6:   df 93           push    r29
  f8:   cd b7           in      r28, 0x3d       ; 61
  fa:   de b7           in      r29, 0x3e       ; 62
  fc:   00 00           nop

    return 1;
  fe:   81 e0           ldi     r24, 0x01       ; 1
 100:   90 e0           ldi     r25, 0x00       ; 0
 102:   df 91           pop     r29
 104:   cf 91           pop     r28
 106:   08 95           ret

Some related pages I came across while looking at avr-objdump... https://www.avrfreaks.net/forum/avr-objdump-and-avrtiny and https://www.nongnu.org/avr-libc/user-manual/group__demo__project.html or https://www.eit.lth.se/fileadmin/eit/courses/edi021/Avr-libc-2.0.0/group__demo__project.html and
Jump to:
© 2020 APG vNext Commercial Version 4.5