【发布时间】:2019-08-09 05:51:10
【问题描述】:
为了结合 .c 和汇编,我想传递 我的 .c 代码的起始地址,然后对微控制器进行编程以知道其程序从该地址开始.当我在汇编中编写我的启动文件时,我需要将.c代码起始地址传递给汇编,然后将此地址写入微控制器的特定内存区域(所以微控制器可以在RESET之后在这个地址上开始执行)
尝试在 Keil 中为 stm32f103 创建一个具有这种结构的项目:
一些 .c 文件,例如 main.c(用于程序的主要部分)。
汇编语言的启动文件。它获取写入某个 .c 文件中的函数的入口地址,以传递给 Reset_Handler
分散文件,这样写的:
LR_IROM1 0x08000000 0x00010000 { ; load region size_region
ER_IROM1 0x08000000 0x00010000 { ; load address = execution address
*.o (RESET, +First) ; RESET is code section with I.V.T.
* (InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x00005000 { ; RW data
.ANY (+RW +ZI)
}
}
问题在于将入口点传递给 .c 函数。需要__main传递的.c入口点(起始地址)的Reset_Handler,看起来是这样的:
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
LDR R0, =__main
BX R0
ENDP
关于入口点 __main,作为对question 的一个程序集的回答:
__main() 是编译器为您的 C 代码提供的入口点。它不是您编写的 main() 函数,而是为 标准库、静态数据、调用“main()”之前的堆 功能。
那么,如何在我的程序集文件中获取这个入口点?
编辑>> 如果有人对 KEIL 的解决方案感兴趣,就在这里,就是这么简单!
简单程序集startup.s文件:
AREA STACK, NOINIT, READWRITE
SPACE 0x400
Stack_top
AREA RESET, DATA, READONLY
dcd Stack_top
dcd Reset_Handler
EXPORT _InitMC
IMPORT notmain
AREA PROGRAM, CODE, READONLY
Reset_Handler PROC
bl notmain
ENDP
_InitMC PROC ;start of the assembly procedure
Loop
b Loop ;infinite loop
ENDP
END
简单的c文件:
extern int _InitMC();
int notmain(void) {
_InitMC();
return 0;
}
链接器与上面提到的相同。 项目构建成功。
【问题讨论】:
-
您的问题到底是什么?你有什么错误吗?如果有,是什么?
-
嘿@Jester。我只是不知道如何通过它。当我编译所有内容时,编译器将 .c 代码放在某个地址,在这种特殊情况下,对于 stm32f103c8,它将类似于 0x2000 xxxx。但我事先并不知道,所以我可以将此地址写入 0x0800 0004(这是 RESET 向量的地址)-这意味着在 RESET 上,微控制器将从该地址开始执行。
-
address orred 准确地说是 1,并且从加电开始,sram 中没有代码,所以你当然不能在那里有“c”代码。备份,并解释你要做什么。制作一个非常简单的程序 main ( ) { return 5;或类似的东西,带有最小的链接器脚本,显示反汇编等,然后你不喜欢什么并想要改变......
-
如果您正在编写引导代码,则输入您的 C 入口点的地址,然后如果您希望它不必是 main 或 __main() 或其他任何东西,则可以将其称为 pickle()。了解您可能会失去库支持。从我上面描述的程序中检查你正在使用的工具链提供的引导代码,如果你有一个可以为这个目标构建的代码。这应该回答你所有的问题,但如果他们不这样做,如果我们能看到它,它就是一个很好的话题。
-
你希望工具链用 1 btw 完成 orr...