2017-04-27 60 views
-1

我面对我的工作是开发Hadoop的源代码中的问题。我需要在asm库中使用函数。给出API,例如: uint32_t func(uint32_t var1,const char var2,uint64_t var3)。 如何使用此函数并获取C程序中的返回值?我总是得到undefined reference to "a function name(which I want to use asm api)"。 是否有一些典型的声明我必须添加在C或其他东西?如何使用asm函数用C

似乎很容易为专业的C程序员,没有值得质疑。但我是一位Java程序员,对ASM和C真的不熟悉。我希望能够有效地得到答案。谢谢。

+2

该API给出如何?有函数原型的头文件吗?你包括它吗? asm库是否添加到项目中以便它被链接? – Lundin

+1

“给出了API?”如果您有一个头文件,请确保将它包含在.c文件中,并确保您的库已添加到项目中并且已链接到项目。也许这个线程会帮助你:http://stackoverflow.com/questions/24991944/linking-c-with-nasm – 23ars

+0

你编程的操作系统和体系结构是什么?你能告诉我们相关的代码吗? – fuz

回答

1

让我们GNU例如,gcc和本身告诉我们,如果我们声明为静态函数那么它是不是提供给其他.c文件的语言。在gnu中,汇编语言和汇编语言是由汇编语言定义的,而不是某种通用语言标准,除非声明为全局语言,否则标签是本地的。

hello: 
.globl there 
there: 

我们将无法链接到hello,但我们可以链接到那里。

然后,你需要知道调用约定,你可以查找并阅读和/或做实验来弄明白。即使你读了它,以确保您使用的是符合您正在阅读的一个编译器,你还是应该做实验,你正在使用的编译器将符合任何标准它使用,而不是一个你希望它使用,这样会让你的ASM比赛......

unsigned int fun (unsigned int a, unsigned int b) 
{ 
    return((a<<2)+b); 
} 

00000000 <fun>: 
    0: e0810100 add r0, r1, r0, lsl #2 
    4: e12fff1e bx lr 

这是手臂,在这种情况下的参数在R0,R1,R2,R3它们是否适合通过,然后如果你有更多的话,请去堆栈。如果它适合返回值在r0中,则有很多例外。你可以在函数中销毁r0-r3,但必须保留r4(可能有一个例外)。所以在这种情况下,r0左移2并加到r1,所以r0是a,r1必须是b,并且返回值在本实验中为r0。

00000000 <fun>: 
    0: 0f 5f   rla r15  
    2: 0f 5f   rla r15  
    4: 0f 5e   add r14, r15 
    6: 30 41   ret 

使用其他指令集R15似乎是一个和R14 B和答案R15

00000000 <_fun>: 
    0: 1166   mov r5, -(sp) 
    2: 1185   mov sp, r5 
    4: 1d40 0004  mov 4(r5), r0 
    8: 0cc0   asl r0 
    a: 0cc0   asl r0 
    c: 6d40 0006  add 6(r5), r0 
    10: 1585   mov (sp)+, r5 
    12: 0087   rts pc 

返回,另一个指令集使用堆栈

我建议你原型您的ASM函数,你想从C调用C,然后编译它,并从那里反汇编并建立你的模块。实际组装它比试图使用内联汇编容易得多,这是一个高级主题,并且非常依赖编译器,如果不使用内联汇编,则它有更好的工作机会。

因此,例如,我想借此所学到的知识和创造

.globl myfun 
myfun: 
    add r0,r1,r0, lsl #2 
    bx lr 

然后我可以组装这一点,在任何人要调用myfun两个参数联系起来。或者我可以用这些知识用这两个参数来做其他事情来创建返回值。

+0

哇!真的很好的建议,加入asm和C在一起。我会进一步思考。你说内联汇编是一个高级主题和依赖编译器。你的意思是在C中使用原型asm可以避免编译器差异的问题吗? – AnyangWang

+0

为了让你的内联程序集不与编译器生成的程序集冲突,特别注册你想要使用的,或者更糟的是,如果你想将C中的变量与程序集连接起来,你必须学习该编译器关于如何执行此操作的语法,不仅仅是程序集,它还是其他编译器的东西,它不是永远不会被使用,但不常用,因此文档和/或外部人员数量较少。如果你想学习asm,学习asm,那么学习特定的编译器东西,C也学习C然后学习编译器特定的东西...或者... –

+0

或...从来不打扰编译器特定的东西,过着幸福的生活... –

0

如果您需要调用C或汇编从Java,使用JNI或其替代品。要调用汇编,请创建一个小的C封装函数来模拟程序集应该执行的操作,然后编译它并使用Java程序进行调试(验证是否可以传递参数,获取返回值)。

当这个工作,注重从调用C.这实际装配真的取决于“ASM库”,它应该有文档,如何把它从C

调用

注意装配库通常需要一定的CPU建筑。例如,如果该库适用于英特尔32位,则不能从Java VM调用64位ARM(至少,这不容易)。

+0

是的,我的目标汇编库是英特尔的。我成功构建它,并且我需要的功能可以在xxx.so文件中找到。就像你说的,我需要的只是一个C包装函数来连接java和程序集。 C代码已准备就绪。但是,我确切地知道如何在C和汇编之间进行引用。我觉得它只需要在C代码中进行一些声明。你能否给我一些线索? – AnyangWang

+0

英特尔库应该有一个体面的文档和一些例子。尝试找到它。通常他们应该有一些C包含文件又名“.h文件”。 – ddbug