如何在单独的 .asm 文件中定义子程序/宏?
Posted
技术标签:
【中文标题】如何在单独的 .asm 文件中定义子程序/宏?【英文标题】:How to define a subroutine/macro in sperate .asm file? 【发布时间】:2020-07-12 20:25:02 【问题描述】:我正在使用 AtmelStudio 在 AVR 中为 Atmega32 编程。我想知道如何在单独的文件中编写子例程或函数,然后在 main.asm
中调用它?
当前的问题是我在 genArray.asm
中有一个子程序 genArrays
。
在main.asm
的开头使用.include "genArray.asm"
会导致程序在main.asm
的开头立即运行genArray
,当我不希望它被调用时,直到我使用调用指令实际调用它(下面的示例)
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
【问题讨论】:
全局声明符号。然后您必须使用正确的设置/拆卸说明在另一个文件中调用该函数。将它们链接在一起,以便在最终的二进制文件中解析符号。 【参考方案1】:使用 gnu 汇编器/binutils。我的 avr 很生疏,但是...
所以.s
.globl _start
_start:
nop
nop
rcall fun
nop
nop
here:
rjmp here
fun.s
.globl fun
fun:
nop
nop
ret
构建
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
汇编语言是特定于汇编器的,不是目标的,所以你需要使用你正在使用的汇编器的语言,上面是gnu assembler for avr。同样,您如何链接它们在很大程度上是特定于工具的。 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
有效(到目前为止)。
【讨论】:
【参考方案2】:尝试简单的事情:将.include "genArray.asm"
放在main.asm
的末尾,这样它的代码就会在程序内存中的main
之后出现。
现在应该已经足够了。您还可以查看avr-gcc
生成的程序集,看看它是如何定义其功能的。
【讨论】:
这对于宏来说是必要的,但是一个子程序可以被组装成一个单独的目标文件然后链接。这避免了文件范围标签名称或指令的任何错误。以上是关于如何在单独的 .asm 文件中定义子程序/宏?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 C 中引用在 Visual Studio 的 .asm 文件中定义的全局变量