如何使用用于AVR的gnu汇编程序相对于PC跳?

问题描述 投票:2回答:2

我有一个二进制文件,已使用avr-objcopy进行了反汇编。中断向量表如下所示:

00000000:;矢量表0:13 c0 rjmp。+ 38; 0x28,复位2:b8 c1 rjmp。+ 880; 0x374,INT04:fd cf rjmp .-6;为0x06:fc cf rjmp .-8;为0x08:fb cf rjmp .-10;为0x0答:fa cf rjmp .-12;为0x0c:f9 cf rjmp .-14;为0x0e:f8 cf rjmp .-16;为0x010:f7 cf rjmp .-18;为0x012:c7 c1 rjmp。+ 910; 0x3a2,TIMER1 OVF14:f5 cf rjmp .-22;为0x016:f4 cf rjmp .-24;为0x018:f3 cf rjmp .-26;为0x01a:f2 cf rjmp .-28;为0x01c:2b c2 rjmp。+ 1110; 0x474,ADC转换完成1e:f0 cf rjmp .-32;为0x020:ef cf rjmp .-34;为0x022:ee cf rjmp .-36;为0x024:ed cf rjmp .-38;为0x026:00 00点;开始28:f8 94 cli(剪断)

我想通过一些修改来重新组装该文件。我已经删除了前两列,从而对其进行了重新格式化,从而使其成为常规的程序集文件。即:

.org 0rjmp。+ 38; 0x28,复位rjmp。+ 880; 0x374,INT0(剪断)

但是,当我跑步时

$ avr-as -mmcu = atmega8 test.asm

然后反汇编生成的文件。 (使用objcopy -S a.out)输出看起来像:

00000000:0:00 c0 rjmp。+ 0; 0X22:00 c0 rjmp。+ 0;为0x44:00 c0 rjmp。+ 0;为0x66:00 c0 rjmp。+ 0; 0x8中8:00 c0 rjmp。+ 0;是0xAa:00 c0 rjmp。+ 0;位于0xCc:00 c0 rjmp。+ 0; 0xee:00 c0 rjmp。+ 0;为0x1010:00 c0 rjmp。+ 0; 0×1212:00 c0 rjmp。+ 0; 0×1414:00 c0 rjmp。+ 0; 0x1616:00 c0 rjmp。+ 0;为0x1818:00 c0 rjmp。+ 0; 0X1A1a:00 c0 rjmp。+ 0;为0x1C1c:00 c0 rjmp。+ 0; 0X1E1e:00 c0 rjmp。+ 0;为0x2020:00 c0 rjmp。+ 0;为0x2222:00 c0 rjmp。+ 0; 0X2424:00 c0 rjmp。+ 0; 0×2626:00 00点28:f8 94 cli(剪断)

所以我如何获得avr-as以尊重PC相对跳跃?

assembly avr disassembly gas relative-addressing
2个回答
6
投票

我找到了答案!

我正在组装但未链接。因此,汇编器用。+ 0填充所有相对的跳转/调用/分支。

要解决此问题,我需要创建一个名为linker.x的自定义链接描述文件,其中包含以下内容:

SECTIONS{。 = 0x0;.text:{*(。text)}}

这告诉链接器从地址0开始.text节。

然后我可以使用以下方式链接代码:

$ avr-ld -mavr4 -Tlinker.x a.out -o output.o

使用上述命令链接后,所有..0均填充了正确的值!

之所以这样,是因为直到链接阶段,as / gcc都不知道二进制文件中还会包含什么。链接器将所有单个目标文件合并为一个。因此,如果从不运行链接程序阶段,则无法用绝对跳转来填充相对跳转。

AVR的汇编器同时进行组装和链接。但是gnu汇编程序更为通用,因此您需要单独链接。


0
投票

我假设rjmp PC+2在avr-as中不起作用?这就是我要在AVR Studio中执行的操作...

© www.soinside.com 2019 - 2024. All rights reserved.