Как определить подпрограмму / макрос в файле sperate .asm? - PullRequest
0 голосов
/ 12 июля 2020

Я программирую в AVR для Atmega32 с помощью AtmelStudio. Мне было интересно, как вы можете написать подпрограмму или функцию в отдельном файле, а затем вызвать ее в main.asm?

текущая проблема: у меня есть подпрограмма genArrays внутри genArray.asm. Использование .include "genArray.asm" в начале main.asm приводит к тому, что программа запускается genArray немедленно в начале main.asm, когда я не хочу, чтобы она вызывалась до тех пор, пока я не вызову ее с помощью инструкции call (пример ниже)

main.asm:

.include "genArray.asm"
.org 0x0000
start:
...
... ---- ; do some stuff
...
...
call genArrays ---- ; call to genArrays subroutine that is defined in genArray.asm (separate file)
... ---- ; return here and continue with program
... ---- ; do some more stuff

genArray.asm:

genArrays: ---- ; start of subroutine
...
...
...
... -----; do some stuff
...
ret

Ответы [ 2 ]

0 голосов
/ 13 июля 2020

Попробуйте простую вещь: поместите .include "genArray.asm" в конец main.asm, чтобы его код появился после main в памяти программ.

Этого должно быть достаточно на данный момент. Вы также можете взглянуть на сборку, сгенерированную avr-gcc, и увидеть, как она определяет свои функции.

0 голосов
/ 13 июля 2020

С помощью ассемблера GNU / binutils. Я очень ржавый на моем avr, но ...

so.s

    .globl _start
    _start:
    nop
    nop
    rcall fun
    nop
    nop
    here:
    rjmp here

fun.s

    .globl fun
    fun:
    nop
    nop
    ret

build

avr-as so.s -o so.o
avr-as fun.s -o fun.o
avr-ld -Ttext=0 so.o fun.o -o so.elf
avr-objdump -d so.elf

so.elf:     file format elf32-avr


Disassembly of section .text:

00000000 <__ctors_end>:
   0:   00 00           nop
   2:   00 00           nop
   4:   03 d0           rcall   .+6         ; 0xc <fun>
   6:   00 00           nop
    ...

0000000a <here>:
   a:   ff cf           rjmp    .-2         ; 0xa <here>

0000000c <fun>:
   c:   00 00           nop
   e:   00 00           nop
  10:   08 95           ret

язык ассемблера указывается c ассемблеру, а не целевому объекту, поэтому вам нужно использовать язык ассемблера, который вы используете, это gnu ассемблер для avr. Точно так же то, как вы их связываете, очень сильно зависит от инструмента c. gnu ld имеет множество функций, AVR - это PITA, для которого нужно создать (с нуля), поэтому вы можете использовать уже созданный набор инструментов и скрипт компоновщика. (на linux я просто получил набор инструментов).

Как бы ужасно это ни было:

avr-gcc -nostdlib  so.s fun.s -o so.elf
avr-objdump -d so.elf
    
so.elf:     file format elf32-avr


Disassembly of section .text:

00000000 <__ctors_end>:
   0:   00 00           nop
   2:   00 00           nop
   4:   03 d0           rcall   .+6         ; 0xc <fun>
   6:   00 00           nop
    ...

0000000a <here>:
   a:   ff cf           rjmp    .-2         ; 0xa <here>

0000000c <fun>:
   c:   00 00           nop
   e:   00 00           nop
  10:   08 95           ret

работает (пока).

...