I am trying to create an interface for an avr simulator. The input to the interface is avr assembly, which is compiled by the interface. During this compilation, I would like to generate a file that contains 4 things for each assembly instruction: the line number in the original assembly file, the location of the assembly instruction in memory, the opcode for the assembled assembly instruction, and the original assembly instruction.
I have been successful so far using a basic test program, but once I started testing with a program that contained branches I noticed that both the listing file and object file I was generating were not accurate: the branches were not branching to labels, but instead to pc + 1. From this question I believe it is a linker issue.
Given this test.s file:
.global main
main:
ldi r16, 10
ldi r17, 0
loop:
add r17, r16
dec r16
cpi r16, 0
brne loop
cpi r17, 50
brge grtr
ldi r18, 1
rjmp done
grtr:
ldi r18, 2
done:
mov r0, r18
The original command I was using to assemble the it was:
avr-gcc -Wa,-alhns -Wa,-L -mmcu=atmega2560 test.s -c -o test.o > test.lst
The corresponding hex file that I generate using avr-objcopy is
:100000000AE010E0100F0A950030>01F4123304F4F6
:0800100021E000C022E0022EF5
:00000001FF
and the listing file is:
1 .global main
2 main:
3 0000 0AE0 ldi r16, 10
4 0002 10E0 ldi r17, 0
5 loop:
6 0004 100F add r17, r16
7 0006 0A95 dec r16
8 0008 0030 cpi r16, 0
9 000a 01F4 brne loop
10 000c 1233 cpi r17, 50
11 000e 04F4 brge grtr
12 0010 21E0 ldi r18, 1
13 0012 00C0 rjmp done
14 grtr:
15 0014 22E0 ldi r18, 2
16 done:
17 0016 022E mov r0, r18
18
DEFINED SYMBOLS
test.s:2 .text:0000000000000000 main
test.s:5 .text:0000000000000004 loop
test.s:14 .text:0000000000000014 grtr
test.s:16 .text:0000000000000016 done
NO UNDEFINED SYMBOLS
If instead I use
avr-gcc -Wa,-alhns -Wa,-L -mmcu=atmega2560 test.s -o test.o > test.lst
I generate hex that includes the entire interrupt vector table
:100000000C9472000C947E000C947E000C947E0084
:100010000C947E000C947E000C947E000C947E0068
:100020000C947E000C947E000C947E000C947E0058
:100030000C947E000C947E000C947E000C947E0048
:100040000C947E000C947E000C947E000C947E0038
:100050000C947E000C947E000C947E000C947E0028
:100060000C947E000C947E000C947E000C947E0018
:100070000C947E000C947E000C947E000C947E0008
:100080000C947E000C947E000C947E000C947E00F8
:100090000C947E000C947E000C947E000C947E00E8
:1000A0000C947E000C947E000C947E000C947E00D8
:1000B0000C947E000C947E000C947E000C947E00C8
:1000C0000C947E000C947E000C947E000C947E00B8
:1000D0000C947E000C947E000C947E000C947E00A8
:1000E0000C947E0011241FBECFEFD1E2DEBFCDBF46
:1000F00000E00CBF0E9480000C948C000C94000067
:100100000AE010E0100F0A950030E1F7123314F402
:0C01100021E001C022E0022EF894FFCF95
:00000001FF
but noticeably the hex for the branches is now accurate. The problem is, the listing file is still the same as before. Not only are the opcodes for the branches wrong, but now the memory locations for the assembly instructions are wrong too.
What mistake am I making in generating this listing file? Ideally I would like to generate one that has proper opcodes and either does not include the interrupt vector table, or includes the interrupt vector table and has the correct memory locations for the assembly instructions.
Thanks in advance.
objdump
with a source + disassembly output mode to get machine code and addresses + original source lines. That would let you get linked executables with branch targets filled in properly. – Peter Cordes-mmcu=atmega2560
for linking. Passing-nostdlib
seems to work too as long as you don't need library stuff obviously. – Jester