Search code examples
assemblyarm

How to write MOVS in terms of mov and other commands in ARM


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!


Solution

  • 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
    

    Arm dedicated comparisons

    Comparison Arithmetic
    cmp subs
    cmn adds
    tst ands
    teq eors

    Ie, these four instructions perform the arithmetic equivalent, but do not write the results to a destination. The only effect is to set condition codes, as if the arithmetic instruction was used.

    In order to properly port this, it would be good to resolve what the intent of the original movs is. It is quite possible that the condition codes are not needed and this was a limitation of the architecture the code was originally targeting.