如何使用用于AVR的gnu汇编器相对于PC跳转? [英] How can I jump relative to the PC using the gnu assembler for AVR?

查看:70
本文介绍了如何使用用于AVR的gnu汇编器相对于PC跳转?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a binary file that I've disassembled using avr-objcopy. The interrupt vector table looks like:


00000000 :
    ; VECTOR TABLE
   0:   13 c0           rjmp    .+38        ;  0x28, RESET
   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
   a:   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, TIMER1 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 conversion complete
  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           nop
  ; START
  28:   f8 94           cli
 (snip)

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

I want to reassemble this file with a few modifications. I've reformatted it by removing the first 2 columns so that it is a regular assembly file. ie:


.org 0
    rjmp    .+38            ;  0x28, RESET
    rjmp    .+880           ;  0x374, INT0
(snip)

但是,当我跑步时

$ avr-as -mmcu=atmega8 test.asm

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

and then disassemble the generated file. (using objcopy -S a.out) The output looks like:

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           nop
  28:   f8 94           cli
(snip)

那么我如何获得avr-as以尊重与PC相关的跳转?

So how can I get avr-as to respect the PC-relative jumps?

推荐答案

我找到了答案!

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

I was assembling but not linking. So the assembler was filling in all relative jumps/calls/branches with .+0.

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

To fix this I needed to create a custom linker script I called linker.x which contains the following:


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

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

This tells the linker to start the .text section at address 0.

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

Then I could link the code using:

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

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

After linking using the above command all of the .+0's were filled in with their correct values!

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

The reason for this, is because until the linking stage, as/gcc don't know what else is going to be included in the binary file. It is the linker that takes all the individual object files and combines them into one. So if the linker stage is never run, there is no way to fill in the relative jumps with absolute jumps.

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

AVR's assembler does the both assembling and linking. But the gnu assembler is more generic and so you need to link separately.

这篇关于如何使用用于AVR的gnu汇编器相对于PC跳转?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆