2

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

00000000 :
    ; 向量表
   0: 13 c0 rjmp .+38 ; 0x28,复位
   2: b8 c1 rjmp .+880 ; 0x374, INT0
   4: fd cf rjmp .-6 ; 0x0
   6: fc cf rjmp .-8 ; 0x0
   8: fb cf rjmp .-10 ; 0x0
   一个:fa cf rjmp .-12 ;0x0
   c: f9 cf rjmp .-14 ; 0x0
   e: f8 cf rjmp .-16 ; 0x0
  10: f7 cf rjmp .-18 ; 0x0
  12: c7 c1 rjmp .+910 ; 0x3a2,定时器1 OVF
  14:f5 cf rjmp .-22;0x0
  16: f4 cf rjmp .-24 ; 0x0
  18: f3 cf rjmp .-26 ; 0x0
  1a:f2 cf rjmp .-28;0x0
  1c: 2b c2 rjmp .+1110 ; 0x474,ADC转换完成
  1e: f0 cf rjmp .-32 ; 0x0
  20: ef cf rjmp .-34 ; 0x0
  22: ee cf rjmp .-36 ; 0x0
  24: ed cf rjmp .-38 ; 0x0
  26: 00 00 无
  ; 开始
  28:f8 94 cli
 (剪断)

我想通过一些修改重新组装这个文件。我通过删除前 2 列对其进行了重新格式化,使其成为常规程序集文件。IE:

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

但是,当我跑步时

$ avr-as -mmcu=atmega8 test.asm

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

00000000 :
   0: 00 c0 rjmp .+0 ; 0x2
   2: 00 c0 rjmp .+0 ; 0x4
   4: 00 c0 rjmp .+0 ; 0x6
   6: 00 c0 rjmp .+0 ; 0x8
   8: 00 c0 rjmp .+0 ; 0xa
   a: 00 c0 rjmp .+0 ; 0xc
   c: 00 c0 rjmp .+0 ; 0xe
   e: 00 c0 rjmp .+0 ; 0x10
  10: 00 c0 rjmp .+0 ; 0x12
  12: 00 c0 rjmp .+0 ; 0x14
  14: 00 c0 rjmp .+0 ; 0x16
  16: 00 c0 rjmp .+0 ; 0x18
  18: 00 c0 rjmp .+0 ; 0x1a
  1a: 00 c0 rjmp .+0 ; 0x1c
  1c: 00 c0 rjmp .+0 ; 0x1e
  1e: 00 c0 rjmp .+0 ; 0x20
  20: 00 c0 rjmp .+0 ; 0x22
  22: 00 c0 rjmp .+0 ; 0x24
  24: 00 c0 rjmp .+0 ; 0x26
  26: 00 00 无
  28:f8 94 cli
(剪断)

那么我怎样才能让 avr-as 尊重 PC 相关的跳跃呢?

4

2 回答 2

6

我找到了答案!

我正在组装但没有链接。所以汇编器用 .+0 填充所有相关的跳转/调用/分支。

为了解决这个问题,我需要创建一个名为 linker.x 的自定义链接器脚本,其中包含以下内容:

部分
{
  . = 0x0;
  .text : { *(.text) }
}

这告诉链接器在地址 0 处开始 .text 部分。

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

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

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

这样做的原因是因为在链接阶段之前,as/gcc 不知道二进制文件中还会包含什么。链接器获取所有单独的目标文件并将它们组合成一个。因此,如果从不运行链接器阶段,则无法用绝对跳转填充相对跳转。

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

于 2009-11-20T08:13:07.533 回答
0

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

于 2009-11-19T13:57:57.320 回答