2017-04-27 2 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에서 추가해야하는 몇 가지 일반적인 선언이 있습니까?C에서 asm 함수를 사용하는 방법

전문적인 C 프로그래머에게는 쉽지 않은 질문입니다. 하지만 저는 ASM과 C에 익숙하지 않은 자바 프로그래머입니다. 나는 대답을 효율적으로 얻을 수 있기를 희망합니다. 고맙습니다.

+2

API는 어떻게 제공됩니까? 함수 원형이있는 헤더 파일이 있습니까? 그것을 포함 시켰습니까? asm 라이브러리가 프로젝트에 추가 되었기 때문에 링크가 연결됩니까? – Lundin

+1

"API가 제공됩니까?" 헤더 파일을 가지고 있다면 .c 파일에 헤더 파일을 포함시키고 라이브러리가 프로젝트에 추가되고 프로젝트에 링크되어 있는지 확인하십시오. 어쩌면이 스레드가 도움이 될 것입니다 : http://stackoverflow.com/questions/24991944/linking-c-with-nasm – 23ars

+0

어떤 운영 체제 및 아키텍처를 프로그래밍하고 있습니까? 관련 코드를 보여줄 수 있습니까? – fuz

답변

1

예를 들어 gcc를 gcc로 가져 오면 언어 자체가 함수를 정적으로 선언하면 다른 .c 파일에서는 사용할 수 없음을 알 수 있습니다. gnu 어셈블러와 어셈블리 언어는 전역 언어로 선언되지 않은 한 어셈블러에서 정의한 언어 표준이 아니며 지역 레이블입니다.

hello: 
.globl there 
there: 

우리는 hello에 연결할 수 없지만 거기에 연결할 수 있습니다.

그러면 호출 규칙을 알아야합니다. 호출 규칙을보고 읽거나 실험을 통해 파악할 수 있습니다. 비록 당신이 읽고있는 컴파일러가 여전히 읽고 있어야하는 컴파일러를 준수하는지 확인하기 위해 그것을 읽었을지라도, 사용하고있는 컴파일러는 사용하고 싶은 표준이 아닌 사용하고있는 표준을 따를 것입니다 그래서

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에 전달하고 ... 당신은 ASM 일치합니다 갖고 계신다면 스택으로 가십시오. 반환 값은 적합하다면 r0에 있고 많은 예외가 있습니다. 당신은 함수에서 r0-r3을 파괴 할 수 있지만 r4를 보존해야합니다 (단 하나의 예외가있을 수 있습니다). 따라서이 경우 r0은 왼쪽으로 2 시프트되고 r1에 추가되므로 r0은 a이고 r1은 b가되어야하며 반환 값은이 실험에서 r0입니다. 다른 명령어 세트 r15를 사용

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

a와 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로 호출 한 다음 컴파일하고 역 어셈블하고 asm을 빌드합니다.인라인 어셈블리를 사용하려고 시도하는 것보다 실제로 어셈블하는 것이 훨씬 쉽습니다. 이는 고급 주제이며 컴파일러에 크게 의존하기 때문에 인라인 어셈블리를 사용하지 않으면 작업 할 수있는 가능성이 더 큽니다.

그래서 지식을 배운 걸릴 만들 것입니다 예를 들어

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

나는 그를 조립하고 두 개의 매개 변수와 함께 myfun 전화를 원하는 사람 누구에게나 그것을에 연결할 수 있습니다. 아니면 그 지식을 사용하여 리턴 값을 생성하기 위해이 두 매개 변수로 다른 일을 할 수 있습니다.

+0

와우! asm과 C를 함께 사용하는 것이 좋습니다. 나는 그것에 대해 더 생각할 것이다. 인라인 어셈블리는 고급 주제이자 컴파일러에 의존한다고했습니다. C에서 prototyping asm을 사용하면 컴파일러의 차이점을 피할 수 있습니까? – AnyangWang

+0

인라인 어셈블리가 컴파일러와 충돌하지 않도록하려면 생성 된 어셈블리 특별히 컴파일하려는 레지스터를 사용하고 싶다면 어셈블리에서 C로 변수를 연결하려면 컴파일러의 구문을 배워야합니다. 그냥 다른 컴파일러 물건, 결코 사용되지 않지만 일반적으로 사용되지 않는 문서 및/또는 거기 밖으로 사람들의 숫자가 적은 어셈블리입니다. asm을 배우고 싶다면 asm을 배우고 그 다음에 특정 컴파일러에 대해 배우십시오. C와 함께 C를 배우고 컴파일러의 특정 내용을 배우십시오. ... 또는 ... –

+0

또는 ... 컴파일러 특정 사항에 신경 쓰지 않고 계속 행복하게 살고 있습니다. ... –

0

Java에서 C 또는 어셈블리를 호출해야하는 경우 JNI 또는 그 대안을 사용하십시오. 어셈블리를 호출하려면 작은 C 래퍼 함수를 ​​만들어 어셈블리에서 수행해야 할 작업을 시뮬레이션 한 다음 컴파일하고 Java 프로그램을 사용하여 디버그합니다 (매개 변수를 전달하고 반환 값을 얻을 수 있는지 확인).

이 작품

, C.이의 실제 어셈블리를 호출에 초점을 정말 "ASM 라이브러리",이 방법 C.

에서 호출하는

참고 해당 어셈블리 라이브러리는 일반적으로 특정 CPU를 필요로 문서를 가져야에 따라 달라집니다 건축물. 예를 들어, 라이브러리가 Intel 32 비트 용인 경우 64 비트 ARM 용 Java VM에서 호출 할 수 없습니다 (적어도 쉽지는 않음).

+0

예, 타겟 어셈블리 라이브러리는 Intel입니다. 나는 그것을 성공적으로 만들었고 필요한 기능은 xxx.so 파일에서 찾을 수 있습니다. 당신이 말했듯이, 내가 필요로하는 것은 자바와 어셈블리를 연결하는 C 래퍼 함수이다. C 코드가 준비되었습니다. 그러나, 나는 C와 어셈블리 사이의 참조를 만드는 방법을 정확히 알고 있습니다. C 코드에서 몇 가지 선언 만 있으면됩니다. – AnyangWang

+0

인텔 라이브러리에는 적절한 문서와 몇 가지 예제가 있어야합니다. 그것을 찾으십시오. 전형적으로 그들은 C 파일 인 ".h file"을 포함해야합니다. – ddbug

관련 문제