如何使用 avr-gcc 生成准确的列表文件?
How do I generate an accurate listing file using avr-gcc?
我正在尝试为 avr 模拟器创建一个界面。接口的输入是avr assembly,由接口编译。在此编译期间,我想为每个汇编指令生成一个包含 4 个内容的文件:原始汇编文件中的行号、汇编指令在内存中的位置、assembled 汇编指令的操作码, 和原始汇编指令。
到目前为止,我已经成功地使用了一个基本的测试程序,但是当我开始使用一个包含分支的程序进行测试时,我注意到我生成的列表文件和目标文件都不准确:分支没有分支标签,而不是 pc + 1。从 this question 我认为这是一个链接器问题。
鉴于此 test.s 文件:
.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
我用来 assemble 的原始命令是:
avr-gcc -Wa,-alhns -Wa,-L -mmcu=atmega2560 test.s -c -o test.o > test.lst
我使用avr-objcopy生成的对应的hex文件是
:100000000AE010E0100F0A950030>01F4123304F4F6
:0800100021E000C022E0022EF5
:00000001FF
列表文件是:
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
如果我改用
avr-gcc -Wa,-alhns -Wa,-L -mmcu=atmega2560 test.s -o test.o > test.lst
我生成了包含整个中断向量的十六进制 table
:100000000C9472000C947E000C947E000C947E0084
:100010000C947E000C947E000C947E000C947E0068
:100020000C947E000C947E000C947E000C947E0058
:100030000C947E000C947E000C947E000C947E0048
:100040000C947E000C947E000C947E000C947E0038
:100050000C947E000C947E000C947E000C947E0028
:100060000C947E000C947E000C947E000C947E0018
:100070000C947E000C947E000C947E000C947E0008
:100080000C947E000C947E000C947E000C947E00F8
:100090000C947E000C947E000C947E000C947E00E8
:1000A0000C947E000C947E000C947E000C947E00D8
:1000B0000C947E000C947E000C947E000C947E00C8
:1000C0000C947E000C947E000C947E000C947E00B8
:1000D0000C947E000C947E000C947E000C947E00A8
:1000E0000C947E0011241FBECFEFD1E2DEBFCDBF46
:1000F00000E00CBF0E9480000C948C000C94000067
:100100000AE010E0100F0A950030E1F7123314F402
:0C01100021E001C022E0022EF894FFCF95
:00000001FF
但值得注意的是,分支的十六进制现在是准确的。问题是,列表文件仍然和以前一样。不仅分支的操作码错误,现在汇编指令的内存位置也错误。
我在生成这个列表文件时犯了什么错误?理想情况下,我想生成一个具有正确操作码并且不包含中断向量 table 或包含中断向量 table 并且具有正确的汇编指令内存位置的代码。
提前致谢。
另一种可能的方法是 assemble+link 和调试信息,然后使用 objdump
和源代码 + 反汇编输出模式来获取机器代码和地址 + 原始源代码行.
这样您就可以得到 linked 的可执行文件,其中正确填充了分支目标。
您可以使用可执行文件的 objdump -D
到 "disassemble" non-code 部分,因此您可能可以使用它来获取 IVT 的 hexdump。
我正在尝试为 avr 模拟器创建一个界面。接口的输入是avr assembly,由接口编译。在此编译期间,我想为每个汇编指令生成一个包含 4 个内容的文件:原始汇编文件中的行号、汇编指令在内存中的位置、assembled 汇编指令的操作码, 和原始汇编指令。
到目前为止,我已经成功地使用了一个基本的测试程序,但是当我开始使用一个包含分支的程序进行测试时,我注意到我生成的列表文件和目标文件都不准确:分支没有分支标签,而不是 pc + 1。从 this question 我认为这是一个链接器问题。
鉴于此 test.s 文件:
.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
我用来 assemble 的原始命令是:
avr-gcc -Wa,-alhns -Wa,-L -mmcu=atmega2560 test.s -c -o test.o > test.lst
我使用avr-objcopy生成的对应的hex文件是
:100000000AE010E0100F0A950030>01F4123304F4F6
:0800100021E000C022E0022EF5
:00000001FF
列表文件是:
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
如果我改用
avr-gcc -Wa,-alhns -Wa,-L -mmcu=atmega2560 test.s -o test.o > test.lst
我生成了包含整个中断向量的十六进制 table
:100000000C9472000C947E000C947E000C947E0084
:100010000C947E000C947E000C947E000C947E0068
:100020000C947E000C947E000C947E000C947E0058
:100030000C947E000C947E000C947E000C947E0048
:100040000C947E000C947E000C947E000C947E0038
:100050000C947E000C947E000C947E000C947E0028
:100060000C947E000C947E000C947E000C947E0018
:100070000C947E000C947E000C947E000C947E0008
:100080000C947E000C947E000C947E000C947E00F8
:100090000C947E000C947E000C947E000C947E00E8
:1000A0000C947E000C947E000C947E000C947E00D8
:1000B0000C947E000C947E000C947E000C947E00C8
:1000C0000C947E000C947E000C947E000C947E00B8
:1000D0000C947E000C947E000C947E000C947E00A8
:1000E0000C947E0011241FBECFEFD1E2DEBFCDBF46
:1000F00000E00CBF0E9480000C948C000C94000067
:100100000AE010E0100F0A950030E1F7123314F402
:0C01100021E001C022E0022EF894FFCF95
:00000001FF
但值得注意的是,分支的十六进制现在是准确的。问题是,列表文件仍然和以前一样。不仅分支的操作码错误,现在汇编指令的内存位置也错误。
我在生成这个列表文件时犯了什么错误?理想情况下,我想生成一个具有正确操作码并且不包含中断向量 table 或包含中断向量 table 并且具有正确的汇编指令内存位置的代码。
提前致谢。
另一种可能的方法是 assemble+link 和调试信息,然后使用 objdump
和源代码 + 反汇编输出模式来获取机器代码和地址 + 原始源代码行.
这样您就可以得到 linked 的可执行文件,其中正确填充了分支目标。
您可以使用可执行文件的 objdump -D
到 "disassemble" non-code 部分,因此您可能可以使用它来获取 IVT 的 hexdump。