I'm using an ATMega328p on an Arduino board.
I've been trying to understand the .hex output generated when I compile my program using the Arduino IDE.
The hex output for my program is:
:100000000C9434000C944F000C944F000C944F004F :100010000C944F000C944F000C944F000C944F0024 :100020000C944F000C944F000C944F000C944F0014 :100030000C944F000C944F000C944F000C944F0004 :100040000C944F000C944F000C944F000C944F00F4 :100050000C944F000C944F000C944F000C944F00E4 :100060000C944F000C944F0011241FBECFEFD4E02E :10007000DEBFCDBF11E0A0E0B1E0E8EFF0E002C0EC :1000800005900D92A030B107D9F711E0A0E0B1E0E2 :1000900001C01D92A030B107E1F70C9467000C94E9 :1000A00000008FEF84B987B98EEF8AB9089501C037 :1000B0000197009759F020E00000000000000000C8 :1000C000000000002F5F2A3599F3F6CF08958FEFD7 :1000D00084B987B98EEF8AB98FEF88B985B98BB9A2 :1000E00084EF91E00E94570018B815B81BB884EF50 :0800F00091E00E945700F0CFDF :00000001FF
I've looked up the Intel Hex file standard on wikipedia, and that all makes sense to me.
The format is:
[Colon] [Data Size] [Start Address] [Record Type] [Data] [Checksum]
Great, so I've got the first record, which is 16 bytes starting at address 0x0000.
So the first line of the program can be parsed as:
The data contains eight machine instructions:
0C94 3400 0C94 4F00 0C94 4F00 0C94 4F00
The first instruction, when I look at an assembler listing (avr-objdump.exe -S) shows as:
0: 0c 94 34 00 jmp 0x68 ; 0x68 <__ctors_end>
That makes sense to me. The first instruction is a JMP 0x68, which should skip over to the beginning of the program (or at least to some overhead setup instructions before the main() of the program).
However, when I look at the AVR Instruction Set, this isn't what that machine instruction should be doing. http://www.atmel.com/dyn/resources/prod_documents/doc0856.pdf
If we convert the hex to a binary instruction (so we can match it to the AVR Instruction Set PDF), we get:
0x0C94 = 0b'0000110010010100
But the JMP instruction in the PDF shows:
1001 010k kkkk 110k kkkk kkkk kkkk kkkk
That's 0x9[4 or 5]X[C or D]
which could be 0x940C, but then the bytes of the
instruction would be backwards.
I'm not quite sure how it calculated the jump address to be 0x68 either.
I'm confused why the assembler listing shows this as a JMP instruction, while the AVR instruction set shows this as an ADD instruction. I believe the compiler made the .hex file correctly as my compiled programs run correctly on my Microcontroller.
Anyone have any idea what's going on here?