Как я могу перейти относительно ПК, используя ассемблер gnu для AVR?

StackOverflow https://stackoverflow.com/questions/1761197

Вопрос

У меня есть двоичный файл, который я дизассемблировал с помощью avr-objcopy.Таблица векторов прерываний выглядит следующим образом:

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)

Я хочу собрать этот файл заново с несколькими изменениями.Я переформатировал его, удалив первые 2 столбца, чтобы это был обычный файл сборки.ie:

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

Однако, когда я запускаю

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

Итак, как я могу заставить avr-as учитывать скачки относительно ПК?

Это было полезно?

Решение

Я нашел ответ!

Я собирал, но не связывал.Таким образом, ассемблер заполнял все относительные переходы / вызовы / ответвления значением .+0.

Чтобы исправить это, мне нужно было создать пользовательский скрипт компоновщика, который я назвал linker.x, который содержит следующее:

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

Это указывает компоновщику запустить раздел .text по адресу 0.

Тогда я мог бы связать код, используя:

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

После связывания с помощью приведенной выше команды все .+ 0 были заполнены их правильными значениями!

Причина этого заключается в том, что до этапа компоновки as / gcc не знает, что еще будет включено в двоичный файл.Это компоновщик, который берет все отдельные объектные файлы и объединяет их в один.Таким образом, если этап компоновки никогда не запускается, нет способа заполнить относительные переходы абсолютными переходами.

Ассемблер AVR выполняет как сборку, так и компоновку.Но ассемблер gnu является более универсальным, и поэтому вам нужно ссылаться отдельно.

Другие советы

Я предполагаю, что rjmp PC+2 не работает в avr-as ?Вот как я бы сделал это в AVR Studio...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top