Search code examples
assemblygccarmclang

Assembly code that works for gcc but not for clang


I got this code working using gcc compiler for arm arch arm-none-eabi-gcc -c s.s.

.arch armv6-m
.thumb_func
MOVS  r0, lr
MOVS  r1, #0xF
AND   r0, r1

and when I try to assemble it using clang for arm arch clang --target=arm-none-abi -c s.s I got these errors

s.s:3:13: error: invalid operand for instruction
MOVS  r0, lr
            ^
s.s:5:1: error: invalid instruction
AND   r0, r1
^

I tried to disassemble the working gcc output I found it converted MOVS to MOV and AND to ANDS

$ arm-none-eabi-objdump -S s.o

s.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <.text>:
   0:   4670        mov r0, lr
   2:   210f        movs    r1, #15
   4:   4008        ands    r0, r1

so I changed the code to be like the assembled one and rerun the clang again and it passed fine but when I reran gcc I got this error

s.s:5: Error: instruction not supported in Thumb16 mode -- `ands r0,r1'
  1. Why is this instruction not supported although the gcc assembler changed it from AND to ANDS and worked before? and clang accepts it?
  2. Also why the gcc assembler changed MOVS to MOV?
  3. How to get a common code that works for the both compilers?

Solution

  • ARM unified syntax .syntax unified solved the ANDS unsuported instruction in Thumb16 mode, gcc error. As per gnu binutils documents, The unified syntax has this feature: All instructions set the flags if and only if they have an s affix.

    so the final common code that works for gcc and clang is:

    .arch armv6-m
    .syntax unified
    .thumb_func
    
    MOV  r0, lr
    MOVS r1, #0xF
    ANDS r0, r1