GNU Arm汇编程序将ORR更改为MOVW

时间:2018-02-01 11:06:05

标签: assembly arm gnu

我正在组装下面的汇编程序:

.syntax unified
.cpu cortex-m4
.thumb

.section  .text

orr r1, #12800
orr r1, #12801

基本上,只有两个OR指令。如果我用objdump查看结果,我会得到:

bla.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <.text>:
   0:   f441 5148   orr.w   r1, r1, #12800  ; 0x3200
   4:   f243 2101   movw    r1, #12801  ; 0x3201

第二个OR默默地变成MOVW!汇编程序运行如下:arm-none-eabi-gcc -g -Wall -c bla.s并且它没有显示任何警告。

as的版本为GNU assembler version 2.29.51 (arm-none-eabi) using BFD version (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 2.29.51.20171128,在OSX上运行。

知道为什么将第二个OR改成MOV?

2 个答案:

答案 0 :(得分:3)

.syntax unified
.cpu cortex-m4
.thumb

.section  .text

orr r1, #12800
orr r1, #12801

arm-none-eabi-as --version GNU汇编程序(GNU Binutils)2.29.1 版权所有(C)2017 Free Software Foundation,Inc。 这个程序是免费软件;你可以根据条款重新分配 GNU通用公共许可证版本3或更高版本。 该计划绝对没有保修。 这个汇编程序配置为`arm-none-eabi&#39;。

的目标

构建

arm-none-eabi-as so.s -o so.o
arm-none-eabi-objdump -D so.o

so.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <.text>:
   0:   f441 5148   orr.w   r1, r1, #12800  ; 0x3200
   4:   f243 2101   movw    r1, #12801  ; 0x3201

杰斯特在评论中有答案,你应该赞成这一点。

2.30刚刚在几天前发布。它也会产生相同的结果。

向后处理2.27.1和2.28之间的问题。该版本的tc-arm.c更改与armv8m的添加有关。 (Cortex-m23和cortex-m33)

这是气体中的错误

  /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
 UINT16 (T3 encoding), MOVW only accepts UINT16.  When
 disassembling, MOV is preferred when there is no encoding
 overlap.
 NOTE: MOV is using ORR opcode under Thumb 2 mode.  */
  if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
  && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
  && !((newval >> T2_SBIT_SHIFT) & 0x1)
  && value >= 0 && value <=0xffff)
{
  /* Toggle bit[25] to change encoding from T2 to T3.  */
  newval ^= 1 << 25;
  /* Clear bits[19:16].  */
  newval &= 0xfff0ffff;
  /* Encoding high 4bits imm.  Code below will encode the
     remaining low 12bits.  */
  newval |= (value & 0x0000f000) << 4;
  newimm = value & 0x00000fff;
}

现在已经超过10年的ARM文档,没有任何人表明它存在关于这些说明的错误。

是的,有一个未使用的ORR编码用作MOV编码,这在指令集设计中是典型的,并非罕见。没有,形状,或 这是否意味着MOV是ORR。此外,一旦误认为MOV是ORR,则选择其他MOV编码。我无语。

更糟糕的是,已发布的天然气版本已经存在了将近一年。怎么可能?

可能的一部分是GCC知道它更好地将其编码为两个单独的指令。

orr r1,#0x3200
orr r1,#0x0001

因此,除了在gnu世界中明显缺乏同行评审之外,已经找到了这个,本来可以让人类尝试这个。 ARM立即编码规则比拇指规则更容易记住。人们总是在挣扎,因为它是RISC指令集的野兽的本质。到现在为止,有人应该知道这一点,现在有人。

尝试使用硬件a cortex-m7

test.s

.cpu cortex-m7
.syntax unified
.thumb

.thumb_func
.globl test1
test1:
    orr r0,#0x3200
    bx lr

.thumb_func
.globl test2
test2:
    orr r0,#0x3201
    bx lr

运行并打印出结果

hexstring(test1(0x0000));
hexstring(test2(0x0000));
hexstring(test1(0x00FE));
hexstring(test2(0x00FE));

气体

arm-none-eabi-as --version
GNU assembler (GNU Binutils) 2.30

结果

0800005c <test1>:
 800005c:   f440 5048   orr.w   r0, r0, #12800  ; 0x3200
 8000060:   4770        bx  lr

08000062 <test2>:
 8000062:   f243 2001   movw    r0, #12801  ; 0x3201
 8000066:   4770        bx  lr

输出

00003200 
00003201 
000032FE 
00003201

MOV是MOV而不是ORR。

你在gnu汇编程序中发现了一个非常讨厌的错误,我建议你提交这个bug。尽管这个bug有多么明显,但我很好奇看到会发生什么。我过去曾提出过其他错误,他们找借口而不是修复,并留下了错误。如果您选择提交此文件,请将该链接发布到评论中,以便我们都能看到他们对此做了什么。

bada43421274615d0d5f629a61a60b7daa71bc15 tc-arm.c:23596是正确的提交和位置。

答案 1 :(得分:3)

天然气团队已确认这是一个错误,并已检查补丁。 Bugzilla条目可以在https://sourceware.org/bugzilla/show_bug.cgi?id=22773

找到