添加 Rn,#1
ADDS Rd, Rn, #1
ARM 文档指定在第一条指令中,如果 Rd 是可选的,如果省略,则 Rd 等于 Rn。所以编译时两条指令应该是相同的。 但是我们的编译器正在生成:
0x3F01 用于 SUBS R7,#1
和
SUBS R7,R7,#1
使用指令解码 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, #1
和SUBS R7, R7, #1
)确实会产生相同的指令: 0xE2577001。
然而,在“Thumb”指令集中,有两种不同的编码方式:
SUBS Rd, Rn, #imm
允许为 Rd
和 Rn
指定两个不同的寄存器,但只允许在范围 0...7。
SUBS Rd, #imm
只允许单寄存器形式但允许 0...255 范围内的立即值。
但是,SUBS R7, R7, #1
和 SUBS R7, #1
做同样的事情。
Any idea why the the compiler might generate different binary?
如果您显式在汇编代码中键入SUBS R7, R7, #1
或SUBS R7, #1
?
因为您还可以键入 SUBS R7, R6, #1
或 SUBS R7, #90
。在这些情况下,编译器必须以不同方式处理这两种变体!
所以它总是以不同的方式处理这两个变体,因为它会更加努力地检查两个寄存器是否相等或检查立即值是否小于 8。
关于assembly - ARM 汇编程序指令 "ADDS Rn, #1"与 "ADDS Rd, Rn, #1",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71159030/