在 ARM cortex M3 汇编器中的任意地址编程

Program at any address in ARM cortex M3 assembler

有谁知道如何在 ARM 汇编程序中将程序放在内存中的任意地址?默认情况下,程序位于从地址 0x00000008 开始的位置,但它必须位于例如地址 0x20002000 处。我尝试使用 DCD 0x20002000,但这只会更改寄存器指针,而程序仍保留在旧地址。 SPACE 0x400命令效果很好,但是如果地址太大,那么编译时间会很长。告诉我,也许遇到过这个?

您通常可以通过修改您正在使用的链接描述文件,或通过向 GNU ld 提供某些命令行选项来实现此结果。

根据您提供的信息,我假设您的代码当前在前两个向量条目 table 之后开始,即初始 SP 值和重置值,并且您的向量 table 位于 0x00000000。

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>

代码将位于 0x00000008。

example2.s 定义了一个名为 .vectors 的新链接器部分。

我们现在将使用 GNU ld --section-start 命令行选项强制 .vectors 部分位于 0x00000000,并且仍然使用 -Ttext-segment 强制 .text 部分/文本段位于0x20002000.

example2.s:

    .cpu    cortex-m3                                                                                                                                                                                                                                              
    .thumb                                                                                                                                                                                                                                                                 
    .syntax unified                                                                                                                                                                                                                                                        
    .global Reset_Handler                                                                                                                                                                                                                                                  
    .equ    StackTop, 0x1000                                                                                                                                                                                                                                               

    .section .vectors                                                                                                                                                                                                                                                      
    .word   StackTop                                                                                                                                                                                                                                                       
    .word   Reset_Handler                                                                                                                                                                                                                                                  

    .section .text                                                                                                                                                                                                                                                         

Reset_Handler:
湾。

/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    

向量 table 仍然位于正确的内存位置,但代码现在位于 0x20002000。

为了描述您为获得相同结果而使用的链接描述文件中所需的确切更改,我需要查看其内容。

使用Keil控制代码区的位置基本上有两种方法。使用分散文件,或使用构建选项对话框中的 'target' 选项卡。

您可以定义一个 IROM 区域,其中包括您希望代码所在的区域。也可以先用这个对话框生成一个初始的scatter文件,然后根据Keil文档修改scatter文件。

但是,您在此处提供的位置是在 RAM 区域中,这有点不寻常(可能效率低下,但有效)。您是否考虑过如何在重启后初始化您的目标?

最大的问题是在重置时,Cortex-M3 将始终从地址 0、4(和 8 由于预取)读取。您需要提供一个初始堆栈指针(或不使用堆栈)和您的重置向量(设置位 0,即 T 位)。内存映射(特定于设备)可能存在硬件存储,但程序员的观点始终是这些提取从地址 0 开始。