STM32F407 - 无法写入 RAM(汇编)

STM32F407 - can't write to RAM (assembly)

我正在使用 STM32F407 探索套件,当我尝试向 RAM 写入内容时它不起作用。

.thumb
.syntax unified
.cpu cortex-m4

.section .bss
NIZ: .space 4

// Start of text section
.section .text
///////////////////////////////////////////////////////////////////////////////
// Vectors
///////////////////////////////////////////////////////////////////////////////
// Vector table start
// Add all other processor specific exceptions/interrupts in order here
.long    __StackTop                // Top of the stack. from linker script
.long    _start +1                  // reset location, +1 for thumb mode

_start:
    adr r0, NIZ // address of the variable in RAM
    ldr r1, [r0] // load the value from RAM to r1
    ldr r1, =0xFE // store random value to r1
    str r1, [r0] // store value from r1 to RAM
    ldr r1, [r0] // here r1 should contain 0xFE but does not
end: b end

这是一个演示问题的示例程序。

加载到 r0 中的地址是 0x08000008,但这是错误的,因为 RAM 区域在链接器脚本中定义的 0x20000000 中:

/* linker script for STM32F407VG chip */

MEMORY {
    rom (rx)  : ORIGIN = 0x08000000, LENGTH = 1024K
    ram (rwx) : ORIGIN = 0x20000000, LENGTH =  128K
}

SECTIONS {
    .text ORIGIN(rom) :
    {
        KEEP(*(.vectors))  /* Vector table */
        *(.text*)          /* Program code */
        *(.rodata*)        /* Read only data */
        . = ALIGN(4);
        __etext = .;
    }

    _sidata = .;

    .data ORIGIN(ram) :  AT ( ADDR (.text) + SIZEOF (.text) )
    {
        __data_start__ = .;
        *(.data*)      /* Read-write initialized data */
        . = ALIGN(4);
        __data_end__ = .;
    }


    .bss ADDR (.data) + SIZEOF (.data):
    {
        __bss_start__ = .;
        . = ALIGN(4);
        *(.bss*)       /* Read-write zero initialized data */
        *(COMMON)
        . = ALIGN(4);
        __bss_end__ = .;
    }
}

__StackTop = ORIGIN(ram) + LENGTH(ram);
__text_size = SIZEOF (.text);
__data_size = SIZEOF (.data);
__bss_size  = SIZEOF (.bss);

我的项目是这个项目的克隆:https://github.com/fcayci/stm32f4-assembly

所以我的猜测是地址在某种程度上在错误的范围内,我不确定是什么原因造成的,也不知道如何解决。

编辑:

readelf -s Debug/stm32f4-asm.elf                                                         ✔ 

Symbol table '.symtab' contains 27 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 08000000     0 SECTION LOCAL  DEFAULT    1 .text
     2: 20000000     0 SECTION LOCAL  DEFAULT    2 .data
     3: 20000000     0 SECTION LOCAL  DEFAULT    3 .bss
     4: 00000000     0 SECTION LOCAL  DEFAULT    4 .ARM.attributes
     5: 00000000     0 SECTION LOCAL  DEFAULT    5 .debug_line
     6: 00000000     0 SECTION LOCAL  DEFAULT    6 .debug_info
     7: 00000000     0 SECTION LOCAL  DEFAULT    7 .debug_abbrev
     8: 00000000     0 SECTION LOCAL  DEFAULT    8 .debug_aranges
     9: 00000000     0 SECTION LOCAL  DEFAULT    9 .debug_str
    10: 00000000     0 FILE    LOCAL  DEFAULT  ABS ./test.o
    11: 20000000     0 NOTYPE  LOCAL  DEFAULT    3 NIZ
    12: 20000000     0 NOTYPE  LOCAL  DEFAULT    3 $d
    13: 08000008     0 NOTYPE  LOCAL  DEFAULT    1 _start
    14: 08000000     0 NOTYPE  LOCAL  DEFAULT    1 $d
    15: 08000008     0 NOTYPE  LOCAL  DEFAULT    1 $t
    16: 08000016     0 NOTYPE  LOCAL  DEFAULT    1 end
    17: 00000000     0 NOTYPE  GLOBAL DEFAULT  ABS __data_size
    18: 20000000     0 NOTYPE  GLOBAL DEFAULT    2 __data_start__
    19: 08000018     0 NOTYPE  GLOBAL DEFAULT    1 _sidata
    20: 08000018     0 NOTYPE  GLOBAL DEFAULT    1 __etext
    21: 00000004     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_size
    22: 20000000     0 NOTYPE  GLOBAL DEFAULT    3 __bss_start__
    23: 20000000     0 NOTYPE  GLOBAL DEFAULT    2 __data_end__
    24: 20000004     0 NOTYPE  GLOBAL DEFAULT    3 __bss_end__
    25: 20020000     0 NOTYPE  GLOBAL DEFAULT    3 __StackTop
    26: 00000018     0 NOTYPE  GLOBAL DEFAULT  ABS __text_size
readelf -s Debug/test.o                                                                  ✔ 

Symbol table '.symtab' contains 17 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 SECTION LOCAL  DEFAULT    1 .text
     2: 00000000     0 SECTION LOCAL  DEFAULT    3 .data
     3: 00000000     0 SECTION LOCAL  DEFAULT    4 .bss
     4: 00000000     0 NOTYPE  LOCAL  DEFAULT    4 NIZ
     5: 00000000     0 NOTYPE  LOCAL  DEFAULT    4 $d
     6: 00000008     0 NOTYPE  LOCAL  DEFAULT    1 _start
     7: 00000000     0 NOTYPE  LOCAL  DEFAULT    1 $d
     8: 00000008     0 NOTYPE  LOCAL  DEFAULT    1 $t
     9: 00000016     0 NOTYPE  LOCAL  DEFAULT    1 end
    10: 00000000     0 SECTION LOCAL  DEFAULT    7 .debug_info
    11: 00000000     0 SECTION LOCAL  DEFAULT    9 .debug_abbrev
    12: 00000000     0 SECTION LOCAL  DEFAULT    5 .debug_line
    13: 00000000     0 SECTION LOCAL  DEFAULT   12 .debug_str
    14: 00000000     0 SECTION LOCAL  DEFAULT   10 .debug_aranges
    15: 00000000     0 SECTION LOCAL  DEFAULT   13 .ARM.attributes
    16: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND __StackTop
readelf -l Debug/stm32f4-asm.elf                                                         ✔ 

Elf file type is EXEC (Executable file)
Entry point 0x8000000
There are 2 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x010000 0x08000000 0x08000000 0x00018 0x00018 R E 0x10000
  LOAD           0x020000 0x20000000 0x08000018 0x00000 0x00004 RW  0x10000

 Section to Segment mapping:
  Segment Sections...
   00     .text 
   01     .data .bss

So my guess is the address is somehow in the wrong range and I'm not sure what causes this or how to fix it.

很抱歉向您询问 readelf 的输出;我刚刚检查了我的电脑,发现它不是链接问题而是汇编程序问题。

下一行是问题所在:

ADR R0, NIZ

根据官方 ARM 文档(不是 GNU 文档),仅当符号(此处:NIZ)位于同一部分(和同一文件)时才允许使用 ADR 指令) 作为 ADR 指令。

GNU 汇编程序应该打印一条错误消息,因为符号 NIZADR 指令在不同的部分;但是,它会默默地忽略错误并生成错误代码!

以下行对我有用:

LDR R0, =NIZ