How can I jump relative to the PC using the gnu assembler for AVR?

烂漫一生 提交于 2019-12-19 10:21:07

问题


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)

However, when I run

$ avr-as -mmcu=atmega8 test.asm

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)

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


回答1:


I found the answer!

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

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

SECTIONS
{
  . = 0x0;
  .text : { *(.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

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

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's assembler does the both assembling and linking. But the gnu assembler is more generic and so you need to link separately.




回答2:


I'm assuming that rjmp PC+2 doesnt work in avr-as ? That's how I'd do it in AVR Studio...



来源:https://stackoverflow.com/questions/1761197/how-can-i-jump-relative-to-the-pc-using-the-gnu-assembler-for-avr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!