有人知道如何将程序放入ARM汇编程序中的内存中的任意地址吗?默认情况下,程序从地址0x0000008开始定位,但它必须位于例如地址0x20002000处。我尝试使用DCD 0x20002000,但这只改变了寄存器指针,而程序仍保留在旧地址。SPACE 0x400命令运行良好,但如果地址太大,则编译需要很长时间。告诉我,也许面对这个?
DCD 0x20002000
SPACE 0x400
的数据
txu3uszq1#
使用Keil控制代码区域的位置基本上有两种方法。“使用散布档,或使用建置选项对话方块中的“目的”标签。您可以定义一个IROM区域,其中包括您希望放置代码的区域。您也可以使用此对话框开始生成初始散布文件,然后根据Keil文档修改散布文件。但是,您在这里给出的位置在RAM区域中,这有点不寻常(可能效率不高,但有效)。你有没有考虑过如何初始化你的目标后,电源循环?最大的问题是,复位时,Cortex-M3总是从地址0、4(由于预取,还有8)读取。您需要提供一个初始堆栈指针(或者不使用堆栈)和您的重置向量(使用位0,即T位,set)。可能存在存储器Map的硬件存储(特定于设备),但程序员的观点是这些提取总是从地址0开始。
kninwzqo2#
您通常可以通过修改正在使用的链接器脚本,或通过向GNU ld提供某些命令行选项来实现此结果。根据您提供的信息,我假设您的代码当前正好在前两个向量条目表之后开始,即初始设定点值和重置值,并确保向量表位于0x 00000000。example1.s应该与您当前的代码大致相同:
.cpu cortex-m3 .thumb .syntax unified .global Reset_Handler .equ StackTop, 0x1000 .word StackTop .word Reset_Handler Reset_Handler: b . .end /opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-as -o example1.o -c example1.s /opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-ld -g -e Reset_Handler -Ttext-segment=0x00000000 -Map=example1.map -o example1.elf example1.o /opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-objdump -d example1.elf example1.elf: file format elf32-littlearm Disassembly of section .text: 00000000 <Reset_Handler-0x8>: 0: 00001000 .word 0x00001000 4: 00000008 .word 0x00000008 00000008 <Reset_Handler>: 8: e7fe b.n 8 <Reset_Handler>
字符串然后,代码将位于0x 00000008。example2.s定义了一个名为. vectors的新链接器部分。现在我们将使用GNU ld --section-start命令行选项强制.vectors部分驻留在0x 00000000,并仍然使用-Ttext-segment强制.text部分/ text段驻留在0x 20002000。实施例2.s:
.cpu cortex-m3 .thumb .syntax unified .global Reset_Handler .equ StackTop, 0x1000 .section .vectors .word StackTop .word Reset_Handler .section .text
型重设行程常式(_H):B .第一次会议
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-as -o example2.o -c example2.s /opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-ld -g -e Reset_Handler --section-start=.vectors=0x00000000 -Ttext-segment=0x20002000 -Map=example2.map -o example2.elf example2.o /opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-ld: warning: address of `text-segment' isn't multiple of maximum page size /opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-objdump -d -j .vectors -j .text -d example2.elf example2.elf: file format elf32-littlearm Disassembly of section .vectors: 00000000 <.vectors>: 0: 00001000 .word 0x00001000 4: 20002000 .word 0x20002000 Disassembly of section .text: 20002000 <Reset_Handler>: 20002000: e7fe b.n 20002000 <Reset_Handler> .end
型向量表仍位于正确的内存位置,但代码现在位于0x 20002000。为了描述在您使用的链接器脚本中实现相同结果所需的确切更改,我需要查看其内容。
2条答案
按热度按时间txu3uszq1#
使用Keil控制代码区域的位置基本上有两种方法。“使用散布档,或使用建置选项对话方块中的“目的”标签。
您可以定义一个IROM区域,其中包括您希望放置代码的区域。您也可以使用此对话框开始生成初始散布文件,然后根据Keil文档修改散布文件。
但是,您在这里给出的位置在RAM区域中,这有点不寻常(可能效率不高,但有效)。你有没有考虑过如何初始化你的目标后,电源循环?
最大的问题是,复位时,Cortex-M3总是从地址0、4(由于预取,还有8)读取。您需要提供一个初始堆栈指针(或者不使用堆栈)和您的重置向量(使用位0,即T位,set)。可能存在存储器Map的硬件存储(特定于设备),但程序员的观点是这些提取总是从地址0开始。
kninwzqo2#
您通常可以通过修改正在使用的链接器脚本,或通过向GNU ld提供某些命令行选项来实现此结果。
根据您提供的信息,我假设您的代码当前正好在前两个向量条目表之后开始,即初始设定点值和重置值,并确保向量表位于0x 00000000。
example1.s应该与您当前的代码大致相同:
字符串
然后,代码将位于0x 00000008。
example2.s定义了一个名为. vectors的新链接器部分。
现在我们将使用GNU ld --section-start命令行选项强制.vectors部分驻留在0x 00000000,并仍然使用-Ttext-segment强制.text部分/ text段驻留在0x 20002000。
实施例2.s:
型
重设行程常式(_H):
B .第一次会议
型
向量表仍位于正确的内存位置,但代码现在位于0x 20002000。
为了描述在您使用的链接器脚本中实现相同结果所需的确切更改,我需要查看其内容。