我想调用x264中的arm.S文件,我创建了一个test.S文件,在改文件中定义如下:
#include "asm.S"
.text
function x264_prefetch_ref_arm
sub r2, r2, #1
add r0, r0, #64
and r2, r2, r1
add r0, r0, r2, lsl #3
add r2, r1, r1, lsl #1
pld [r0]
pld [r0, r1]
pld [r0, r1, lsl #1]
add r3, r0, r1, lsl #2
pld [r0, r2]
pld [r3]
pld [r3, r1]
pld [r3, r1, lsl #1]
pld [r3, r2]
bx lr
endfunc
编译的时候报错:
bad instruction `endfunc'
bad instruction `function x264_prefetch_ref_arm'
这个是跟编译器有关系吗?
我用的是的linaro编译器gcc-linaro-arm-linux-gnueabihf-4.9-2014.09。
另外有个疑问,汇编中直接使用#include<>的对吗?不是应该用.include<>吗?
我吧#改成.后,发现编译错误又变成:
bad instruction `elf .hidden EXTERN_ASMx264_prefetch_ref_arm'
bad instruction `elf .size x264_prefetch_ref_arm,.-x264_prefetch_ref_arm'
bad instruction `elf .type EXTERN_ASMx264_prefetch_ref_arm,%function'
bad instruction `func .endfunc'
bad instruction `func .func EXTERN_ASMx264_prefetch_ref_arm'
麻烦帮我解答下,谢谢。
1、GAS汇编中其实不支持function与endfunc这两个关键字,如果你所实现的函数需要被外部引用, 则需要使用.globl关键字来声明。 function与endfunc可以使用macro来实现: .macro function _name .globl \_name \_name: .endm .macro endfunc _name .type \_name, %fuction .size \_name, . - \_name .endm
2、汇编文件中使用#include <> 时,在as之前,会先调用预处理器来进行预处理(宏替换啥的)。 注意此时汇编文件名需要以.S作为结尾。 汇编文件中也可以使用.include <>, 此种include不会调用预处理器。
我想直接在我的eclipse中创建的工程中直接调用x264 arm.S汇编文件, 该文件中的前面一部分定义是这样的:
#include "config.h"
#ifdef PREFIX
# define EXTERN_ASM _
#else
# define EXTERN_ASM
#endif
#ifdef __ELF__
# define ELF
# define ELF #
#ifdef __MACH__
# define MACH
# define MACH #
#if HAVE_AS_FUNC
# define FUNC
# define FUNC #
.macro function name, export=0, align=2
.macro endfunc
ELF .size \name, . - \name
FUNC .endfunc
.purgem endfunc
.endm
.align \align
.if \export
.global EXTERN_ASM\name
ELF .type EXTERN_ASM\name, %function
FUNC .func EXTERN_ASM\name
EXTERN_ASM\name:
.else
ELF .type \name, %function
FUNC .func \name
\name:
.endif
.macro const name, align=2
.macro endconst
.purgem endconst
ELF .section .rodata
MACH .const_data
.macro movrel rd, val
#if defined(PIC) && defined(__APPLE__)
adrp \rd, \val@PAGE
add \rd, \rd, \val@PAGEOFF
#elif defined(PIC)
adrp \rd, \val
add \rd, \rd, :lo12:\val
ldr \rd, =\val
#define GLUE(a, b) a ## b
#define JOIN(a, b) GLUE(a, b)
#define X(s) JOIN(EXTERN_ASM, s)
#define FDEC_STRIDE 32
#define FENC_STRIDE 16
我自己的汇编文件test.S 中直接调用#include"arm.S",
test.S去使用arm.S中宏定义的function和endfunc 是失败的,编译器不识别,感觉是#include" arm.S" 失败, 不知道哪里出错了。按照你的说法应该不会有什么问题的。
不好意思, 我说的是x264里面的asm.S, 我说成 arm.S了,asm.S全部内容:
.syntax unified
#if HAVE_NEON
.arch armv7-a
#elif HAVE_ARMV6T2
.arch armv6t2
#elif HAVE_ARMV6
.arch armv6
.fpu neon
# define ELF @
# define FUNC @
.macro require8, val=1
ELF .eabi_attribute 24, \val
.macro preserve8, val=1
ELF .eabi_attribute 25, \val
.macro function name, export=1
.align 2
.if \export == 1
ELF .hidden EXTERN_ASM\name
ELF .hidden \name
#if HAVE_ARMV6T2 && !defined(PIC)
movw \rd, #:lower16:\val
movt \rd, #:upper16:\val
.macro movconst rd, val
#if HAVE_ARMV6T2
.if \val >> 16
.macro HORIZ_ADD dest, a, b
.ifnb \b
vadd.u16 \a, \a, \b
vpaddl.u16 \a, \a
vpaddl.u32 \dest, \a
.macro SUMSUB_AB sum, diff, a, b
vadd.s16 \sum, \a, \b
vsub.s16 \diff, \a, \b
.macro SUMSUB_ABCD s1, d1, s2, d2, a, b, c, d
SUMSUB_AB \s1, \d1, \a, \b
SUMSUB_AB \s2, \d2, \c, \d
.macro ABS2 a b
vabs.s16 \a, \a
vabs.s16 \b, \b
// dist = distance in elements (0 for vertical pass, 1/2 for horizontal passes)
// op = sumsub/amax (sum and diff / maximum of absolutes)
// d1/2 = destination registers
// s1/2 = source registers
.macro HADAMARD dist, op, d1, d2, s1, s2
.if \dist == 1
vtrn.16 \s1, \s2
vtrn.32 \s1, \s2
.ifc \op, sumsub
SUMSUB_AB \d1, \d2, \s1, \s2
vabs.s16 \s1, \s1
vabs.s16 \s2, \s2
vmax.s16 \d1, \s1, \s2
.macro TRANSPOSE8x8 r0 r1 r2 r3 r4 r5 r6 r7
vtrn.32 \r0, \r4
vtrn.32 \r1, \r5
vtrn.32 \r2, \r6
vtrn.32 \r3, \r7
vtrn.16 \r0, \r2
vtrn.16 \r1, \r3
vtrn.16 \r4, \r6
vtrn.16 \r5, \r7
vtrn.8 \r0, \r1
vtrn.8 \r2, \r3
vtrn.8 \r4, \r5
vtrn.8 \r6, \r7
.macro TRANSPOSE4x4 r0 r1 r2 r3
.macro TRANSPOSE4x4_16 d0 d1 d2 d3
vtrn.32 \d0, \d2
vtrn.32 \d1, \d3
vtrn.16 \d0, \d1
vtrn.16 \d2, \d3
david_xia帮忙看了一下,觉得steven说的是有道理的,鉴于这个是和GNU汇编有关的问题,转为自由讨论
我局的steven说的不太对,他可能没有看过x264 arm.S里面的代码,里面是有宏定义function和endfunc 关键字的,麻烦再看看,因为自己的test.S 汇编#include“arm.S”,编译失败,感觉是gcc编译器没有识别#include,以及#define 类似的
好的,也请david_xia和steven帮忙再看一下。 大家一起想想办法,谢谢
因为我这没有config.h文件,为了编译通过,做了如下更改:
asm.S文件中去掉了#include "config.h" 和 .syntax unified 和.fpu neon这三行,
用gcc-linaro-4.9-2015.02-x86_64_armeb-linux-gnueabihf 工具链可以编译通过,在test.S中增加main函数,可以生成可执行文件。
所用的编译命令为:./gcc-linaro-4.9-2015.02-x86_64_armeb-linux-gnueabihf/bin/armeb-linux-gnueabihf-gcc -o test test.S
readelf -h test
ELF Header:
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, big endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x102c1
Start of program headers: 52 (bytes into file)
Start of section headers: 5212 (bytes into file)
Flags: 0x5800402, has entry point, Version5 EABI, BE8, <unknown>
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 8
Size of section headers: 40 (bytes)
Number of section headers: 38
Section header string table index: 35
是否是编译器版本还是别的原因就不清楚了。
你好,我按照你的方法吧 test.S 中的函数x264_prefetch_ref_arm定义放到asm.S 文件中,还是编译有错误
错误如下:
..\asm.S:188: Error: bad instruction `elf .hidden EXTERN_ASMx264_prefetch_ref_arm'
..\asm.S:188: Error: bad instruction `elf .type EXTERN_ASMx264_prefetch_ref_arm,%function'
..\asm.S:188: Error: bad instruction `func .func EXTERN_ASMx264_prefetch_ref_arm'
..\asm.S:204: Error: bad instruction `elf .size x264_prefetch_ref_arm,.-x264_prefetch_ref_arm'
..\asm.S:204: Error: bad instruction `func .endfunc'
附件是我编译的文件,你那边能否用我的这个版本编译器编译下试试,我使用的编译器gcc-linaro-arm-linux-gnueabihf-4.9-2014.09。这个编译器linaro官网是有的。
我用了gcc-linaro-arm-linux-gnueabihf-4.9-2014.05_linux/bin/arm-linux-gnueabihf-gcc -o test test.S 编译也是可以的,你说的那个版本我这不方便下载,你要是下载方便的话,可以换成我的工具链版本试试。
你好,我知道和你的区别了,你用的是gcc编译的是汇编文件,我用的是as编译的汇编文件,你试试用as编译汇编文件;
我在eclipse中,cross gcc compiler command 是gcc,cross gcc linker command 也是gcc,cross gcc assembler command 是as。
有个疑问.S汇编文件不应该是用as编译吗?
嗯,确实如果用as直接编译你的.S文件会报错。我的第一个回复中提过,如果汇编文件是.S结尾(不是.s哦),用gcc编译时,其会先调用CPP做预处理。而你的.S文件中不仅有#inlcude,而且还有#define等宏定义,这些是需要经过CPP的。而as不会调用CPP,这就造成了你的错误。
我看了x264里面arm汇编都是以.S结尾的,但是不明白他们编译汇编文件为什么没有这种错,不知道你有什么好的解决办法没有?
好几天过去了,不知道这个问题有没有什么解决办法?
david_xia能否也帮忙给点建议?谢谢,是否需要请这位用户联系我们的AE解决问题。