ARM中uint8_t变量的LDR行为?

问题描述 投票:0回答:1

我在任何地方都找不到直接的答案。 ARM的寄存器是32位的,我知道LDRB将字节大小的值加载到寄存器中,并将剩余的3个字节清零,即使您将其提供的值大于字节,它也将仅采用第一个字节值。

我的程序将C与ARM Assembly结合在一起。我在C中有一个extern变量,可以直接将其加载到寄存器中。

但是,如果我仅在此字节变量上调用LDR,可以保证它加载该字节,什么也没有,或者是否会从内存中附近的东西加载剩余3字节空间中的随机数,以填充整个32位注册?

我只问是因为我做了LDR R0,= var并总是从大约一亿次执行中获得了正确的价值(软件运行了很长时间并且经过了彻底的测试/重新编译了很多次,才提出这个问题。另一种设置)。

[但是其他人使用不同的设置(没有什么不同,编译器是我认为的相同版本)成功地编译了代码,但是加载到R0中的值被变量周围存储器中的随机位污染了。他们必须进行LDRB修复。

这是编译器吗?它可以检测到并自动将其切换到LDRB吗?还是我很幸运,由于一些优化,变量的周围内存仅为零?

附带说明,编译器为ARM GCC 9.2.1

c gcc assembly arm gnu
1个回答
0
投票

因为我做了LDR R0, =var

是否要加载变量的地址

[通常,指令LDR R0, =var会将变量var的地址写入寄存器R0,而不是值。

并且变量的地址始终是32位ARM CPU上的32位值-与数据类型无关。

但是如果我仅在此字节变量上调用LDR,则...

如果加载变量的(例如,使用LDR R1, [R0],则可能会发生两件事:

  • 寄存器的高24位可能包含随机值,具体取决于内存中变量后面的字节。如果幸运的话,字节始终为零。
  • 取决于确切的CPU类型,由于对齐可能会出现问题(例如,对齐异常或什至是完全未定义的行为)
© www.soinside.com 2019 - 2024. All rights reserved.