assembly - ARM 汇编程序指令 "ADDS Rn, #1"与 "ADDS Rd, Rn, #1"

标签 assembly arm

  1. 添加 Rn,#1
  2. ADDS Rd, Rn, #1

ARM 文档指定在第一条指令中,如果 Rd 是可选的,如果省略,则 Rd 等于 Rn。所以编译时两条指令应该是相同的。 但是我们的编译器正在生成:

0x3F01 用于 SUBS R7,#1SUBS R7,R7,#1

的二进制 0x1E7F

使用指令解码 0x3F01 等于 001 11 111 00000001 001

001 -> add/substract/compare/move immediate

11 -> opcode is substract imm

111 -> R7

00000001 -> value 1

使用指令解码

0x1E7F 等于 000111 1 001 111 111

000111 -> add/substract register

1 -> substract immediate

001 -> value 1

111 -> R7

111 -> R7

所以两条指令都在执行相同的操作。知道编译器为什么会生成不同的二进制文件吗?

最佳答案

The ARM documentation specifies that in the first instruction if the Rd is optional and if ommitted Rd equals Rn. So both instructions should be the same when compiled.

首先,您应该注意到有两种不同的 ARM 指令集:“传统”32 位指令集和“Thumb”指令集。

您的 CPU 显然使用“Thumb”指令集。

许多关于 ARM 指令集的陈述都是指“传统”指令集。

在传统的指令集中,两种形式(SUBS R7, #1SUBS R7, R7, #1)确实会产生相同的指令: 0xE2577001

然而,在“Thumb”指令集中,有两种不同的编码方式:

SUBS Rd, Rn, #imm 允许为 RdRn 指定两个不同的寄存器,但只允许在范围 0...7。

SUBS Rd, #imm 只允许单寄存器形式但允许 0...255 范围内的立即值。

但是,SUBS R7, R7, #1SUBS R7, #1 做同样的事情。

Any idea why the the compiler might generate different binary?

如果您显式在汇编代码中键入SUBS R7, R7, #1SUBS R7, #1

因为您还可以键入 SUBS R7, R6, #1SUBS R7, #90。在这些情况下,编译器必须以不同方式处理这两种变体!

所以它总是以不同的方式处理这两个变体,因为它会更加努力地检查两个寄存器是否相等或检查立即值是否小于 8。

关于assembly - ARM 汇编程序指令 "ADDS Rn, #1"与 "ADDS Rd, Rn, #1",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71159030/

相关文章:

go - 具有回退功能的汇编函数实现

c - 不理解 Hopper 反编译器的输出

c++ - 为什么 ARM 文档建议只有 4 个函数参数?有更多的特定性能成本吗?

security - 上下文切换到安全模式的成本是多少(arm trustzone)

c - 如何保护 isr 和常规函数共享的全局变量?

c - 如何将动态可执行文件转换为静态可执行文件?

assembly - x86 子指令操作码混淆

linux - 汇编:将多行写入缓冲区

assembly - Cortex-A57可以双发出128位neon指令吗?

performance - 在 x86 中设置和清除零标志