Код на ассемблере, который работает для gcc, но не для clang

#assembly #gcc #arm #clang

#сборка #gcc #arm #clang

Вопрос:

Я получил этот код, работающий с использованием компилятора gcc для arm arch arm-none-eabi-gcc -c s.s .

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

и когда я пытаюсь собрать его с помощью clang для arm arch clang --target=arm-none-abi -c s.s , я получаю эти ошибки

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

Я попытался разобрать рабочий вывод gcc, я обнаружил, что он преобразовал MOVS в MOV и И в 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
  

итак, я изменил код, чтобы он был похож на собранный, и снова запустил clang, и все прошло нормально, но когда я повторно запустил gcc, я получил эту ошибку

 s.s:5: Error: instruction not supported in Thumb16 mode -- `ands r0,r1'
  
  1. Почему эта инструкция не поддерживается, хотя ассемблер gcc изменил ее с AND на ANDS и работал раньше? и clang принимает это?
  2. Также почему ассемблер gcc изменил MOVS на MOV?
  3. Как получить общий код, который работает для обоих компиляторов?

Комментарии:

1. попробуйте mov вместо movs

2. язык ассемблера специфичен для инструмента gnu assembler и gcc разные, clang — еще один. нет причин ожидать какой-либо совместимости. затем добавьте эту ошибку arms с унифицированным синтаксисом, что делает все это большим беспорядком, поскольку различные инструменты пытались как-то поддержать это (у них нет требований поддерживать это в любом случае, гораздо меньше синтаксиса, документированного arms).

3. Согласно сайту clang, я думал, что clang полностью совместим с gcc даже с ассемблером! clang.llvm.org

4. Похоже, вы доказали, что это неправильно. Подождите, я не вижу языка ассемблера, упомянутого на этой странице, это язык ассемблера, а не C. Он искажен через интерфейс C, но это не C.

5. Похоже, вы говорите, что вам также нужно было сообщить об ошибке в llvm, прежде чем обращаться к SO, чтобы задать этот вопрос. Что они сказали, когда вы отправили ошибку в clang / llvm?

Ответ №1:

Унифицированный синтаксис ARM .syntax unified разрешил неподтвержденную инструкцию ANDS в режиме Thumb16, ошибка gcc. Согласно документам gnu binutils, унифицированный синтаксис обладает такой особенностью: все инструкции устанавливают флаги тогда и только тогда, когда они имеют s-аффикс.

итак, окончательный общий код, который работает для gcc и clang, является:

 .arch armv6-m
.syntax unified
.thumb_func

MOV  r0, lr
MOVS r1, #0xF
ANDS r0, r1
  

Ответ №2:

 .arch armv6-m
.thumb
mov r0,lr

arm-none-eabi-gcc -c test.s -o test.o
arm-none-eabi-objdump -D test.o

test.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <.text>:
   0:   4670        mov r0, lr
  

(clang создан для armv6-m)

 clang test.s -c -o test.o
arm-none-eabi-objdump -d test.o

test.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <.text>:
   0:   4670        mov r0, lr
  

Но с movs

 .arch armv6-m
.thumb
movs r0,lr

arm-none-eabi-gcc -c test.s -o test.o
arm-none-eabi-objdump -d test.o

test.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <.text>:
   0:   4670        mov r0, lr
  

(возвращается к поддержке first thumb, ассемблер может делать то, что хочет)

 clang test.s -c -o test.o
test.s:4:1: error: invalid instruction, any one of the following would fix this:
movs r0,lr
^
test.s:4:9: note: operand must be an immediate in the range [0,255]
movs r0,lr
        ^
test.s:4:9: note: operand must be a register in range [r0, r7]
movs r0,lr
        ^
  

и теперь это

 .arch armv6-m
.thumb
.syntax unified
movs r0,lr

arm-none-eabi-gcc -c test.s -o test.o
test.s: Assembler messages:
test.s:5: Error: cannot honor width suffix -- `movs r0,lr'
  

(только потому, что это armv6-m, а не armv7-m)

 clang test.s -c -o test.o
test.s:5:1: error: invalid instruction, any one of the following would fix this:
movs r0,lr
^
test.s:5:9: note: operand must be an immediate in the range [0,255]
movs r0,lr
        ^
test.s:5:9: note: operand must be a register in range [r0, r7]
movs r0,lr
  

и это

 .arch armv6-m
.thumb
.syntax unified
mov r0,lr

arm-none-eabi-gcc -c test.s -o test.o
arm-none-eabi-objdump -d test.o

test.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <.text>:
   0:   4670        mov r0, lr

clang test.s -c -o test.o
arm-none-eabi-objdump -d test.o

test.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <.text>:
   0:   4670        mov r0, lr
  

ваш код

 .arch armv6-m
.thumb_func
movs r0,lr

arm-none-eabi-gcc -c test.s -o test.o
arm-none-eabi-objdump -d test.o

test.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <.text>:
   0:   4670        mov r0, lr
  

Опять плохой вкус, но ассемблер может делать то, что хочет.

Я исправлен.thumb_func интересно, что здесь что-то делает

 .arch armv6-m
movs r0,lr
  

не имеет смысла, ну да ладно…

 arm-none-eabi-gcc -c test.s -o test.o
test.s: Assembler messages:
test.s:3: Error: attempt to use an ARM instruction on a Thumb-only processor -- `movs r0,lr'
  

Хм…

 .arch armv6-m
mov r0,lr

arm-none-eabi-gcc -c test.s -o test.o
test.s: Assembler messages:
test.s:3: Error: attempt to use an ARM instruction on a Thumb-only processor -- `mov r0,lr'
  

Нет.

Комментарии:

1. Перед запуском любого языка ассемблера вам понадобится документация как по процессору, так и по ассемблеру. Какую часть документации arm вы не поняли?

2. Я не писал никакого ассемблерного кода, я портировал приложение C для компиляции с clang. Этот небольшой ассемблерный код был встроен в приложение, и тогда я столкнулся с этой проблемой!

3. сборка — это сборка, с которой вы хотите возиться, получите документы. был ли этот код, который вы нашли для armv7-m, а не для armv6-m? SO здесь не для того, чтобы читать документы за вас. Как только вы увидели вывод инструментов, следующим шагом будет поиск инструкции. или свяжитесь с автором.

4. Когда вы связались с автором этого кода, который вы используете, что они сказали?

5. Это armv6-m, поскольку он работает на arm cortex 0, и автор ушел!