adr没有在thumb2工作?

时间:2014-07-16 04:02:49

标签: assembly arm cortex-m3 cortex-m

我正在使用arduino应有的董事会。我写了下面这段代码。

#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(注释的那个,而不是所有三个ldrs)时,我得到了这个输出。那么为什么adr语句不起作用。

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

1 个答案:

答案 0 :(得分:0)

根据关于“arm.com”的ARM文档,“adr”指令有一些限制。

其中一个限制是“adr”只能用于与“adr”指令相距一定距离的地址。这也意味着不能对另一部分的地址使用“adr”(“x”符号在“.data”部分,而“adr”指令在“.code”部分)。

然而,这个文档是关于“官方”行为,而GNU汇编程序的行为通常与官方行为不同,所以我测试了GNU汇编程序的行为:

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