I'm working on a project where I'm trying not to use the MOVS command but a combination of MOV and other commands.
mov r3, #-2147483648
str r3, [r7, #36]
mvn r3, #-2147483648
str r3, [r7, #32]
movs r3, #0
str r3, [r7, #28]
movs r3, #0
str r3, [r7, #24]
As you can see movs is used twice here, what could be its equivalent? Possibly using ldr and mov? Thanks!
CodePudding user response:
tst reg,reg
sets flags according to the value, so mov dst,src
tst dst,dst
would be the naive drop-in replacement for any case.
Or in your case, your str
instructions don't depend on flags so you could just use mov r3, #0
. (Once; reading it with str
doesn't destroy the value so there's no need to set it again).
But if you really want to also set flags according to the 0
value, you could zero a register inefficiently with ands r3, #0
. (Setting to all-ones inefficiently with orrs r3, #-1
isn't possible in ARM mode; the immediate isn't encodeable. But it is in Thumb mode with Thumb-2 available.)
(Or eors r3,r3
or subs r3,r3
to borrow the x86 zeroing idiom, but note that ARM CPUs won't special case that and run it efficiently. In fact they're not allowed to do so: the memory-ordering model has data-dependency ordering like C 11 std::memory_order_consume
was supposed to expose, but is otherwise weakly ordered. eors
and subs
, like all ALU instructions, are guaranteed to carry a data dependency on their inputs, regardless of any special cases.)
For copying a register, adds reg, reg, #0
should do the trick. This is apparently a separate instruction with a separate opcode even in Thumb mode.
.syntax unified
.thumb_func
adds r1, r2, #0
movs r1, r2
arm-none-eabi-gcc -mcpu=cortex-a53 -c arm.s && arm-none-eabi-objdump -d arm.o
0: 1c11 adds r1, r2, #0
2: 0011 movs r1, r2