问题描述
我正在尝试为 STM32 微控制器找出一些 ARM 组件。当我尝试组装指令 mov r0,#0
时,我得到:
core.S:27: Error: cannot honor width suffix -- `mov r0,#0'
但是当我使用 movs r0,#0
时它可以工作。 Here,它表示“s”只影响条件标志是否更新。
我对 add r0,r0,#1
与 adds 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 选项,文档中定义的语法没有显示,因此取决于汇编程序作者,他们必须选择一个或弥补一些语法)。