So currently within the STM32 world you have four different instruction sets based on armv6m, armv7m and armv8m. Technically for now the armv8m baseline matches armv6m and armv8m mainline extensions matches armv7m.
So the armv6m instruction set in theory works for all cortex-ms at this time and it uses the tranditional all thumb variants (going back to armv4t's thumb instruction set) add and 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
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
movs r1,#1
so.s: Assembler messages:
so.s:4: Error: cannot honor width suffix -- `mov r1,#1'
.cpu cortex-m3
.thumb
.syntax unified
mov r1,#1
movs r1,#1
Disassembly of section .text:
00000000 <.text>:
0: f04f 0101 mov.w r1, #1
4: 2101 movs r1, #1
Now the ARMv7m document says this:
Encoding T1 All versions of the Thumb instruction set.
MOVS <Rd>,#<imm8> Outside IT block.
MOV<c> <Rd>,#<imm8> Inside IT block.
armv6m does not have the it instruction so this is a touch misleading, the movs encoding is supported by all thumb variants, but not the other.
.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'
so you cannot use it there either.
.cpu cortex-m3
.thumb
.syntax unified
itt ne
movne r1,#1
movsne r1,#2
mov 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
The short answer is that you cannot because the instruction does not exist. If you are using unified syntax documentation that glosses over which instruction sets are supported, then you have, as many others, fallen into the trap of the major failing of the unified syntax. A pretty serious oops, on ARM's part. Just have instruction sets like every one else, done.
stm32 is too broad you have cortex-m0, m0+, m3, m4, m7, and flavors of m8. m0 and m0+ and some m8's are basically armv6m and this instruction is not supported in any way. The m3,m4,m7 and some m8's it is as a thumb2 extension or with a condition specification within an it block.
With the unified syntax and thumb it is best to add the s unless you definitely do not want it then hope for the best.
If you are using the original gnu assembler thumb syntax, then, thanks to I assume a combination of ARM's documentation (at that time) and the gnu folks, you can't have the s (for some instructions)
.arch armv5t
.thumb
mov r1,#3
movs r1,#3
add r1,r2,r3
adds r1,r2,r3
so.s: Assembler messages:
so.s:6: Error: instruction not supported in Thumb16 mode -- `adds r1,r2,r3'
.arch armv5t
.thumb
.syntax unified
mov r1,#3
movs r1,#3
add r1,r2,r3
adds r1,r2,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,r2,r3'
And last but not least, assembly language (the syntax) is specific to the tool (the assembler) not the target (arm/thumb). So all of the above is gnu assembler for many of the versions that support various flavors of the thumb instruction sets. You can look at armasm (tool from ARM not GNU) as well as perhaps others, and their rules may vary. So within armasm it may very well be proper syntax as the mov r1,#1 shown in these last examples
.arch armv5t
.thumb
mov r1,#3
movs r1,#3
add r1,r2,r3
Disassembly of section .text:
00000000 <.text>:
0: 2103 movs r1, #3
2: 2103 movs r1, #3
4: 18d1 adds r1, r2, r3
indicates. (also note the disassembler folks and assembler folks disagree as well, I do not have a binutils from the pre-unified-syntax era to see what it showed).
ARM's documentation is going to be either specific to no tool as the authors of the architecture are different than the tool creator/maintainers. Or they may attempt to get along and have the architecture documents match their internal tools. But that in no way means gnu has to conform and sadly people that port targets to gnu assembler seem to have a habit of not supporting the processor vendors syntax completely, there is often a painful or annoying twist.
(How you read that ARM ARM, you could have used the s option as it shows the arm equivalent, with the s option, the defined syntax in the doc did not show that so depending on the assembler author, they had to pick one or make up some syntax).