为什么MOV指令被ADD指令代替

Why MOV instruction is replaced by ADD instruction

我的汇编代码中有以下指令:mov r1, r7 但在查看反汇编后,我发现实际生成的代码是 adds r1, r7, #0

我查看了 ARMv6-M 体系结构参考手册,发现有 MOVS <Rd>,<Rm> 指令 (A6.7.40) 不同于 ADDS

虽然这不是什么大问题,但我仍然不明白为什么汇编程序会用不同的操作码替换我编写的代码。根据我正在阅读的书,所有非跳转指令都需要 1 个周期(而且我更希望汇编程序是愚蠢的,而不是试图为我优化某些东西)。

我正在使用 Raspberry Pi Pico SDK,它使用 GNU 汇编器,AFAIK。

我所有的代码都是用helloworld.S写的,完整的源代码是:

.thumb_func
.global main

main:
mov r7, #0
bl stdio_init_all
loop:
ldr r0, =helloworld
add r7, #1
mov r1, r7
bl printf
mov r0, #250
bl sleep_ms
b loop
.data
.align 4
helloworld: .asciz "Hello World %d\n"

我可以建议你添加:

.syntax unified

在文件的开头?之后,您将必须为所有指令显式添加后缀,以标记它们是否设置标志以及它们是否有条件,但您可能会发现更容易显式控制所使用的操作码。

这是您在编译器资源管理器中的代码: https://godbolt.org/z/zo8nnc9sh

您正在编写 Thumb 模式汇编代码,RPi Pico 支持 Thumb-2,这意味着实际输出将在 UAL format.

如果参考ARMv6-M reference manual,table D4-1指定将pre-UAL Thumb语法转换为UAL语法,特别是:

Pre-UAL Thumb syntax Equivalent UAL Syntax Notes
MOV <Rd>, <Rm> ADDS <Rd>, <Rm>, #0 If <Rd> and <Rm> are both R0-R7.
MOV <Rd>, <Rm> Otherwise.

按照Tom的建议,如果要编写UAL代码(然后将实际组装as-is),可以添加.syntax unified

Thumb 指令有 16 位长,这不是很多位。因为 mov rx, ryadds rx, ry, #0 做同样的事情而 adds rx, ry, # 0 更通用,仅支持 adds 版本并且 mov 被汇编程序转换为 *adds”。所以 mov 本质上变成了 pseudo-instruction.

其他 ISA 也做类似的事情。 RISC-V 在 RV32I ISA 中没有 mv 指令。它被类似地编码为 addi。重点是节省操作码编码space,有限的资源