我正在组装下面的汇编程序:
.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?
答案 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
找到