为什么不允许使用 THUMB 指令“mov r0, #0”?

问题描述

我正在尝试为 STM32 微控制器找出一些 ARM 组件。当我尝试组装指令 mov r0,#0 时,我得到:

core.S:27: Error: cannot honor width suffix -- `mov r0,#0'

但是当我使用 movs r0,#0 时它可以工作。 Here,它表示“s”只影响条件标志是否更新。

我对 add r0,r0,#1adds r0,#1 有类似的问题。

谁能解释一下为什么 movs 有效而 mov 无效?

解决方法

因此,目前在 STM32 世界中,您有四种基于 armv6m、armv7m 和 armv8m 的不同指令集。从技术上讲,目前 armv8m 基线匹配 armv6m,armv8m 主线扩展匹配 armv7m。

因此,理论上 armv6m 指令集目前适用于所有 cortex-ms,它使用传统的所有拇指变体(回到 armv4t 的拇指指令集)add 和 mov。

.cpu arm7tdmi
.thumb
.syntax unified
mov r1,#1
movs r1,#1

so.s: Assembler messages:
so.s:4: Error: cannot honor width suffix -- `mov r1,#1'

.cpu arm7tdmi
.thumb
.syntax unified
movs r1,#1

Disassembly of section .text:

00000000 <.text>:
   0:   2101        movs    r1,#1
   2:   2101        movs    r1,#1

.cpu cortex-m0
.thumb
.syntax unified
mov r1,#1'

.cpu cortex-m3
.thumb
.syntax unified
mov r1,#1

Disassembly of section .text:

00000000 <.text>:
   0:   f04f 0101   mov.w   r1,#1
   4:   2101        movs    r1,#1

现在 ARMv7m 文档是这样说的:

Encoding T1  All versions of the Thumb instruction set.
MOVS <Rd>,#<imm8>  Outside IT block.
MOV<c> <Rd>,#<imm8> Inside IT block.

armv6m 没有 it 指令,所以这是一种误导,所有拇指变体都支持 movs 编码,但其他变体不支持。

.cpu cortex-m3
.thumb
.syntax unified

itt ne
movne r1,#1
mov r1,#2
mov r1,#3

so.s: Assembler messages:
so.s:7: Error: instruction not allowed in IT block -- `mov r1,#2'

所以你也不能在那里使用它。

.cpu cortex-m3
.thumb
.syntax unified

itt ne
movne r1,#1
movsne r1,#3

Disassembly of section .text:

00000000 <.text>:
   0:   bf1c        itt ne
   2:   2101        movne   r1,#1
   4:   f05f 0102   movsne.w    r1,#2
   8:   f04f 0103   mov.w   r1,#3

简短的回答是你不能,因为指令不存在。如果您使用的统一语法文档掩盖了支持哪些指令集,那么您和其他许多人一样,陷入了统一语法主要失败的陷阱。对 ARM 来说,真是糟糕透了。只需像其他人一样完成指令集即可。

stm32 太宽泛了,你有 cortex-m0、m0+、m3、m4、m7 和 m8 的味道。 m0 和 m0+ 以及一些 m8 基本上是 armv6m 并且不以任何方式支持此指令。 m3、m4、m7 和一些 m8 的它作为拇指 2 扩展或在 it 块中具有条件规范。

使用统一的语法和拇指,最好添加 s 除非您绝对不想要它然后希望最好。

如果您使用原始的 gnu 汇编程序拇指语法,那么,由于我假设结合了 ARM 的文档(当时)和 gnu 人员,您不能拥有 s(对于某些说明)

.arch armv5t
.thumb
mov r1,#3
movs r1,#3
add r1,r2,r3
adds r1,r3

so.s: Assembler messages:
so.s:6: Error: instruction not supported in Thumb16 mode -- `adds r1,r3'
.arch armv5t
.thumb
.syntax unified
mov r1,r3

so.s: Assembler messages:
so.s:4: Error: cannot honor width suffix -- `mov r1,#3'
so.s:6: Error: cannot honor width suffix -- `add r1,r3'

最后但并非最不重要的一点是,汇编语言(语法)特定于工具(汇编器)而不是目标(arm/thumb)。因此,以上所有内容都是支持各种类型的拇指指令集的许多版本的 gnu 汇编程序。您可以查看 armasm(来自 ARM 而不是 GNU 的工具)以及其他工具,它们的规则可能会有所不同。因此,在 armasm 中,它很可能是正确的语法,如这些最后示例中所示的 mov r1,#1

.arch armv5t
.thumb
mov r1,r3

Disassembly of section .text:

00000000 <.text>:
   0:   2103        movs    r1,#3
   2:   2103        movs    r1,#3
   4:   18d1        adds    r1,r3

表示。 (还要注意反汇编人员和汇编人员也不同意,我没有统一语法前时代的 binutils 来查看它显示的内容)。

ARM 的文档将不针对任何工具,因为架构的作者与工具创建者/维护者不同。或者他们可能会尝试相处并使架构文档与他们的内部工具相匹配。但这绝不意味着 gnu 必须符合,可悲的是,将目标移植到 gnu 汇编器的人似乎习惯于不完全支持处理器供应商的语法,这通常会带来痛苦或烦人的转折。

(您如何阅读 ARM ARM,您可以使用 s 选项,因为它显示了与 arm 等效的选项,使用 s 选项,文档中定义的语法没有显示,因此取决于汇编程序作者,他们必须选择一个或弥补一些语法)。