0
votes

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.

1
Another possible approach would be to assemble with debug info, then use 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
If you don't want the vector table then don't use -mmcu=atmega2560 for linking. Passing -nostdlib seems to work too as long as you don't need library stuff obviously.Jester
@PeterCordes although the format is more difficult to parse, that solution does provide me all the information I need. If you want to post that as an answer I can accept it.zach
@Jester I realize now that I think I need the vector table since at some point I will likely be simulating interrupts. Linking with the mmcu specified is probably going to be a requirement for me.zach
Soooooo that means you don't have a problem because the second version is what you want?Jester

1 Answers

1
votes

Another possible approach would be to assemble+link with debug info, then use 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.

You can use objdump -D to "disassemble" non-code sections of an executable, so you can probably use that to get a hexdump of the IVT.