assembly adr在thumb2中不起作用?

lhcgjxsq  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(115)

我用的是Arduino due board。我写了下面这段代码。

#include <Arduino.h>
#include <SPI.h>
#include <Ethernet.h>

extern "C" unsigned int asm_add ();

extern "C" volatile unsigned int x;
extern "C" volatile unsigned int y;
extern "C" volatile unsigned int z;

void setup()
{
    Serial.begin(115200);
    Serial.println("exiting setup");
}
void loop()
{
    Serial.print("x - ");
    Serial.println(x);
    Serial.print("y - ");
    Serial.println(y);
    Serial.print("z before add is - ");
    Serial.println(z);

    Serial.println("calling asm_add");
    z = asm_add();
    Serial.print("asm_add addition result is - ");
    Serial.println(z);
    Serial.println("exiting loop");
    delay(3000);
    z=500;
}

字符串
这里是组装部分:

.syntax unified
.section .text
.thumb
.thumb_func
.cpu cortex-m3
.align 2

.type asm_add2 STT_FUNC
.global asm_add
.global x
.global y
.global z

asm_add:

    ldr r0, =x
    //adr r0, x
    ldr r0, [r0]
    ldr r1, =y
    ldr r1, [r1]

    add r0, r1
    ldr r1, =z
    str r0, [r1]
    bx lr

.section .data
.align 2
x:
    .word 0x10
y:
    .word 0x20
z:
    .word 0x100


当我在asm函数中使用ldr语句时,我得到以下输出-

x - 16
y - 32
z before asm_add
asm_add addition result is - 48
exiting loop


但是,当我在asm_add中更改地址加载以使用adr而不是ldr(注解的那个,不是所有三个ldr)时,我得到了以下输出。那么为什么ADR声明不起作用。

exiting setup
x - 16
y - 32
z before add is - 256
calling asm_add
asm_add addition result is - 324303
exiting loop

mxg2im7a

mxg2im7a1#

根据“arm.com“上的ARM文档,“adr”指令有一些限制。
其中一个限制是“adr”只能用于与“adr”指令有一定距离的地址。这也意味着不可能在另一个部分中使用“adr”作为地址(“x”符号在“.data”部分中,而“adr”指令在“.code”部分中)。
然而,这个文档是关于“官方”行为的,而GNU汇编程序的行为通常与官方行为不同,所以我测试了GNU汇编程序的行为:

  • 我测试的GNU汇编程序的两个版本中,有一个总是在我尝试使用“adr”访问不同部分中的地址时打印错误消息
  • 另一个版本在Thumb代码中打印错误消息,但在ARM(非Thumb)代码中生成错误代码(没有任何警告消息)
  • 显然,Arduino工具包附带的版本也会为Thumb代码生成错误代码,而不会发出警告消息。

相关问题