GNU Arm 汇编器将 ORR 更改为 MOVW

2024-01-03

我正在组装以下汇编器:

.syntax unified
.cpu cortex-m4
.thumb

.section  .text

orr r1, #12800
orr r1, #12801

本质上,只有两个 OR 指令。如果我查看结果objdump, I get:

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 is 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 吗?


.syntax unified
.cpu cortex-m4
.thumb

.section  .text

orr r1, #12800
orr r1, #12801

臂无 eabi-as --版本 GNU 汇编器 (GNU Binutils) 2.29.1 版权所有 (C) 2017 自由软件基金会, Inc. 该程序是免费软件;您可以根据以下条款重新分发它 GNU 通用公共许可证版本 3 或更高版本。 该程序绝对没有任何保证。 该汇编器配置为“arm-none-eabi”目标。

build

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 相关。 (皮质-m23 和皮质-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;
}

ARM 文档已有 10 多年的历史,没有人指出它在这些指令方面存在错误。

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

更糟糕的是,这种情况在发布的 Gas 版本中已经存在了近一年。这怎么可能?

之所以可能,部分原因是 GCC 更清楚地将其编码为两个单独的指令。

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

因此,除了 GNU 世界中明显缺乏同行评审之外,要发现这一点,就需要人类尝试这一点。 ARM 立即编码规则比拇指规则更容易记住。人们总是在与立即数作斗争,这是 RISC 指令集的野兽本质。现在应该有人已经做到了这一点,现在已经有人做到了。

尝试硬件 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));

gas

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

result

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

output

00003200 
00003201 
000032FE 
00003201

MOV 是 MOV,不是 ORR。

您在 gnu 汇编器中发现了一个非常令人讨厌的错误,我建议您将这个错误归档。尽管这个错误非常明显,但我很好奇会发生什么。我过去曾提交过其他错误,但他们只是找借口而不是修复,并将错误保留在原处。如果您选择提交此问题,请将票证链接作为评论发布,以便我们都可以看到他们对此做了什么。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GNU Arm 汇编器将 ORR 更改为 MOVW 的相关文章

  • 如何使用 Neon SIMD 将无符号字符转换为有符号整数

    如何转换变量的数据类型uint8 t to int32 t使用霓虹灯 我找不到执行此操作的任何内在因素 假设您想要将 16 x 8 位整数的向量转换为 4 个 4 x 32 位整数的向量 您可以通过首先解压缩为 16 位 然后再次解压缩为
  • 为什么 i2c_smbus 函数不可用? (I2C——嵌入式Linux)

    有很多参考使用i2c smbus 开发嵌入式 Linux 软件时在 I2C 总线上进行通信的函数 什么时候i2c smbus函数如i2c smbus read word data在软件项目中引用了 ARM8 处理器错误 例如 i2c smb
  • 装配中出现奇怪的字符?

    我写了以下代码 386 model small stack 100h data text db Paper 0 code start lea dx text mov ah 9h int 21h mov ah 4ch int 21h end
  • 产生并处理软件中断

    有人可以告诉我如何在Linux下生成软件中断然后用request irq处理它吗 或者也许这是不可能的 您可以使用软中断来代替 您可以通过编辑 include linux interrupt h 来定义您的 sofirq 然后使用函数 ra
  • 使用 Android NDK 使用 -fsigned-char 进行构建安全吗?

    为了与其他平台保持一致 我需要使用signed char在我正在处理的一些本机代码中 但默认情况下在Android NDK上char类型是unsigned 我尝试明确使用signed char类型 但它生成太多警告differ in sig
  • 遍历内存编辑每个字节

    我正在编写汇编代码 提示用户输入一串小写字符 然后输出包含所有大写字符的相同字符串 我的想法是迭代从特定地址开始的字节 并从每个字节中减去 20H 将小写变为大写 直到到达具有特定值的字节 我对 Assembly 相当缺乏经验 所以我不确定
  • 什么时候汇编比C更快? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的
  • 如何让c代码执行hex机器代码?

    我想要一个简单的 C 方法能够在 Linux 64 位机器上运行十六进制字节码 这是我的 C 程序 char code x48 x31 xc0 include
  • 了解 ctags 文件格式

    我使用 Exhuberant ctags 来索引我的 c 项目中的所有标签 c project 是 Cortex M7 微控制器的嵌入式软件 结果是一个标签文件 我正在尝试阅读该文件并理解所写的内容 根据我找到的 ctags 和 Exhub
  • 无法在 R 中安装插入符号包(在我的 Linux 机器中)

    我在尝试在 R 中安装插入符号包时遇到以下错误 g error tmp Rtmp2Tos7n R INSTALL2e6e30153a74 nloptr nlopt 2 4 2 lib libnlopt cxx a No such file
  • 是否可以将 SpaCy 安装到 Raspberry Pi 4 Raspbian Buster

    我一整天都在安装 SpaCy sudo pip install U spacy Looking in indexes https pypi org simple https www piwheels org simple Collectin
  • 在 x86-64 CPU 上通过交叉修改代码重现意外行为

    Question 对于可能在 x86 或 x86 x64 系统上触发意外行为的交叉修改代码有哪些想法 在这些系统中 交叉修改代码中的所有操作均已正确完成 但在执行处理器之前执行序列化指令除外修改代码 如下所述 我有一个 Core 2 Duo
  • 使用 Easy 68K (68000) 组装范围内的随机数

    我正在使用 Easy 68K 模拟器创建一个简单的黑杰克游戏 需要使用随机数来分配牌 我的牌必须在 2 到 11 的范围内 我似乎每次都得到相同的数字 但它不在我预期的范围内 我的卡值需要以 D3 结束 因此我有以下随机数代码 CLR L
  • Beaglebone Black 的 U-boot 无法构建 - 目标 CPU 不支持 THUMB 指令

    我正在尝试按照 Chris Simmonds 的 掌握嵌入式 Linux 编程 中的说明为 Beagle Bone Black 构建 u boot 我已经构建了交叉工具链 现在正在尝试使用该工具链构建 Das U boot 但由于不支持 T
  • 如何设置 CMake 与 clang 交叉编译 Windows 上的 ARM 嵌入式系统?

    我正在尝试生成 Ninja makefile 以使用 Clang 为 ARM Cortex A5 CPU 交叉编译 C 项目 我为 CMake 创建了一个工具链文件 但似乎存在错误或缺少一些我无法找到的东西 当使用下面的工具链文件调用 CM
  • Makefile 和通配符

    好吧 这是我当前的 makefile 设置 有一些文件名为public01 c public02 c等等 我正在尝试使用以下方法为每个人制作目标文件public o带有通配符的标签 public o public c hashtable h
  • 为什么如果内存组织为字,则程序计数器加 1;如果内存组织为字节,则程序计数器加 2?

    如果在计算机中一条指令是 16 位 并且如果存储器被组织为 16 位字 则通过在当前指令的地址中加 1 来计算下一条指令的地址 如果内存是按字节组织的 可以单独寻址 那么我们需要在当前指令地址上加二 得到顺序执行的下一条指令的地址 为什么会
  • 阴影空间示例

    EDIT 我接受了下面的答案 并添加了我自己的代码的最终修订版 希望它向人们展示影子空间分配的实际示例 而不是更多的文字 编辑 2 我还设法在 YouTube 视频 所有内容 的注释中找到了一个调用约定 PDF 的链接 其中有一些关于 Li
  • AOSP 的“午餐”组合是什么意思?我需要选择什么?

    我是 Android 设备 ROM 开发的新手 无论如何 我现在正在为具有 64 位处理器的中国设备构建 AOSP 我按照 source android com 上的菜单进行操作 当我运行 午餐 命令时 终端显示 午餐菜单 选择一个组合 我
  • 如何将 x86 GCC 风格的 C 内联汇编转换为 Rust 内联汇编?

    我在 C 中有以下内联汇编 unsigned long long result asm volatile byte 15 byte 49 shlq 32 rdx orq rdx rax a result rdx return result

随机推荐