适用于 gcc 但不适用于 clang 的汇编代码
Assembly code that works for gcc but not for clang
我使用 arm arch 的 gcc 编译器得到了这段代码 arm-none-eabi-gcc -c s.s
。
.arch armv6-m
.thumb_func
MOVS r0, lr
MOVS r1, #0xF
AND r0, r1
当我尝试 assemble 它使用 clang 作为手臂拱形时 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
^
我试图取消assemble 工作的 gcc 输出,我发现它将 MOVS 转换为 MOV 并将 AND 转换为 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
所以我将代码更改为类似于 assembled 的代码并再次重新运行 clang 并且它通过了很好但是当我重新运行 gcc 时我得到了这个错误
s.s:5: Error: instruction not supported in Thumb16 mode -- `ands r0,r1'
- 尽管 gcc assembler 将它从 AND 更改为 ANDS 并且之前可以工作,但为什么不支持该指令? clang 接受了吗?
- 还有为什么 gcc assembler 将 MOVS 更改为 MOV?
- 如何获得适用于两种编译器的通用代码?
.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
(为 armv6-m 构建的 clang)
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
(回到第一个拇指支持,汇编器可以自由地做他们想做的事)
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'
没有。
ARM统一语法.syntax unified
解决Thumb16模式下ANDS不支持指令,gcc错误。根据 gnu binutils documents,统一语法具有此功能:所有指令设置标志当且仅当它们具有 s 词缀时。
所以适用于 gcc 和 clang 的最终通用代码是:
.arch armv6-m
.syntax unified
.thumb_func
MOV r0, lr
MOVS r1, #0xF
ANDS r0, r1
我使用 arm arch 的 gcc 编译器得到了这段代码 arm-none-eabi-gcc -c s.s
。
.arch armv6-m
.thumb_func
MOVS r0, lr
MOVS r1, #0xF
AND r0, r1
当我尝试 assemble 它使用 clang 作为手臂拱形时 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
^
我试图取消assemble 工作的 gcc 输出,我发现它将 MOVS 转换为 MOV 并将 AND 转换为 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
所以我将代码更改为类似于 assembled 的代码并再次重新运行 clang 并且它通过了很好但是当我重新运行 gcc 时我得到了这个错误
s.s:5: Error: instruction not supported in Thumb16 mode -- `ands r0,r1'
- 尽管 gcc assembler 将它从 AND 更改为 ANDS 并且之前可以工作,但为什么不支持该指令? clang 接受了吗?
- 还有为什么 gcc assembler 将 MOVS 更改为 MOV?
- 如何获得适用于两种编译器的通用代码?
.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
(为 armv6-m 构建的 clang)
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
(回到第一个拇指支持,汇编器可以自由地做他们想做的事)
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'
没有。
ARM统一语法.syntax unified
解决Thumb16模式下ANDS不支持指令,gcc错误。根据 gnu binutils documents,统一语法具有此功能:所有指令设置标志当且仅当它们具有 s 词缀时。
所以适用于 gcc 和 clang 的最终通用代码是:
.arch armv6-m
.syntax unified
.thumb_func
MOV r0, lr
MOVS r1, #0xF
ANDS r0, r1