2010-06-19 2 views
7

ARM 어셈블러 코드에서 LONG_MIN 및 LONG_MAX와 같은 외부 정의를 사용하려면 어떻게해야합니까?ARM 어셈블러에서 C 정의를 사용하는 방법

의이 my_arm.h가 다음과 같다고 가정 해 보겠습니다

int my_arm(int foo); 

의 다음과 같이 나는 my_main.c 있다고 가정 해 봅시다 :

.text 
    .align 2 
    .global my_arm 
    .type my_arm, %function 
my_arm: 
    ... 
    ADDS r1, r1, r2 
    BVS overflow 
    ... 
overflow: 
    LDR r0, LONG_MAX @ this is probably wrong, how to do it correctly? 
    BX lr @ return with max value 
:

... 
#include <limits.h> 
#include "my_arm.h" 
... 
int main (int argc, char *argv[]) 
{ 
    int foo=0; 
... 
    printf("My arm assembler function returns (%d)\n", my_arm(foo)); 
... 
} 

그리고 my_arm.s은 다음과 같습니다

두 번째 줄부터 마지막 ​​줄까지 정확하게로드하는 방법을 모르겠지만 어딘가에서 읽는 것을 막연하게 기억하고 있습니다. LONG_MAX는 .global이지만 더 이상 작동하는 예제에 대한 링크를 찾을 수 없습니다.

나는 팔 - 리눅스 - gnueabi-GCC 버전 4.3.2

==================

UPDATE로 컴파일 오전 : 제안을 감사합니다 ! 불행히도 구문에 문제가 있습니다.

... 
.include "mylimits.h" 
... 
ldr r7, =MY_LONG_MIN @ when it was working it was ldr r7, =0x80000000 
... 

두 가지 문제 :

첫째, 나는 다음과 같은 my_arm.S에서

#define MY_LONG_MIN 0x80000000 

내가 추가 (.S와 같은 디렉토리에 지금은) 약간의 헤더 파일 mylimits.h했다 이 접근법. .include 날 <limits.h>, 나는 mylimits에 그를 추가해야합니다 포함하지 않는 구문 :

우선 가장 큰 문제 : 심볼 MY_LONG_MIN가 인식되지는 ... 그래서 뭔가는 여전히

둘째 옳지 않다. h, 조금 kludgy 보인다,하지만 그건 괜찮아요 :)

모든 포인터?

시스템 소프트웨어 설계 및 최적화 [2004] 및 ARM 아키텍처 참조 설명서 [2000]에 액세스 할 수 있지만 대상은 XScale-IXP42x 제품군 2 (v5l)입니다.

+4

카일 ARM을 위해 작동하지만 경우 MIPS에서 .S의 확장자로 이름을 변경하여 C의 전처리 파일을 만듭니다. – Tom

+0

#include는 .include가 아니며 .S는 .s가 아니며 대답과 같습니다. 이 방법을 사용하면 gcc 기능을 악용 할 수 있습니다. 물론 x86에서의 테스트와 마찬가지로 어셈블리는 따로 떨어져야합니다. – ShinTakezou

답변

11

대개 소문자 파일 확장자 .s은 어셈블러가 c 전 처리기를 통해 전달되면 안되는 것을 의미하지만 대문자 확장자 인 .S은 포함해야한다는 것을 의미합니다. (gcc 포트는 일반적으로 그렇지만)이 규칙을 따르는 것은 컴파일러의 몫입니다. 따라서 문서를 확인하십시오.

(EDIT : #include 지시문을 사용할 수 있음을 유의하십시오. 그러나 포함 할 파일의 대부분은 일반적으로 유효한 어셈블러가 아닙니다 (단, 전체적으로 #define 개의 itions로 구성되어 있지 않은 경우). 당신의 자신의 헤더) 오년 후


편집 :

의 armcc의 V5 컴파일러는 리눅스에서이 동작을 다음 있습니다 ...하지만 창문에.

+4

GCC 툴체인을 사용하는 경우 어셈블리 파일을 사전 처리 할 때 '__ASSEMBLER__' 매크로가 정의됩니다. 이 파일은 필요한 경우 .h 파일 작업 (asm 및 C)을 지원하는 데 사용할 수 있습니다. 그러나 가능한 경우 두 세계에서 작동해야하는 항목을 별도의 머리글로 분리하는 것이 가장 좋습니다. 표준 헤더에 정의되어있는'LONG_MAX '와 같은 것이기는하지만, 많은 것을 제어 할 수는 없습니다 ... –

+0

예, 표준 헤더에는별로 사용되지 않습니다! (목적을 위해 설계된 메모리 매핑 된 IO 주소 같은 것을 정의하는 아키텍처 헤더를 제외하고) – James

0

나는 gcc에게 어셈블러 소스를 제공하는 것으로 보았을 뿐이지 만 가스는 어셈블러에서 C와 같은 일을 할 수있게 해준다. 실제로 작동하기 위해 gcc를 가스의 프론트 엔드로 사용해야하는 상황을 경험할 때 실제로는 약간 무서운 것이지만 그것은 또 다른 이야기입니다.

1

는 내가하고 결국은 이것이다 : my_arm.S

ldr r8, =my_LONG_MAX 
ldr r10, [r8] 

그것은 convuluted보고가있다 (플러스 휴대 이익

#include <limits.h> 
... 
int my_LONG_MAX=LONG_MAX; 

다음 my_main.c에서

이 접근법에서는 의심 스럽다).

어셈블리에서 LONG_MAX에 직접 액세스 할 수있는 방법이 있어야합니다. 그런 식으로 전 대답으로 기꺼이 받아 들일 것입니다.

+0

누군가가 더 나은 솔루션을 추가하려는 경우 기꺼이 대답을 수락합니다 – Sint

+0

이것은 매우 못생긴 것입니다. 어쨌든 어셈블러에서 타입 - 크기 관련 정의를 사용하려고하는 이유는 무엇입니까? 단일 아키텍처 (asm에 내재 된)가 있다면 문자 그대로 상수를 씁니다. 그것은 변하지 않을 것입니다! –

+0

아, 그건 끔찍한 일입니다. :) 이것은 라이브러리 함수의 구현입니다. 나는 내 길을 가졌다면 나는 그것을 상수로 직접 쓰려고했을 것이다. – Sint

2

gcc와 해당 어셈블러를 사용하는 경우 간단합니다. 파일의 이름을 .S으로 지정한 다음 처음에 #include <limits.h>을 추가하고 상수가 필요한 곳이면 어디에서나 사용하십시오. ldr r0, SOMETHING; 내가 가지고있는 것이기 때문에 나는 x86으로 테스트를했다. 그러나 gcc 기능이기 때문에 똑같이 작동한다.

0

사용 armasm에서 옵션 --cpreproc 및 my_arm.s에

#include "my_arm.h" 

를 추가합니다.

그것은 그나마 ARM에 대해 알고

관련 문제