GNU 스타일 ARM 어 셈 블 리 프로 그래 밍 실전 중 하나

8347 단어 ARM

참고 자료
1.:http://www.ethernut.de/en/documents/arm-inline-asm.html
  2. 《__asm__ __volatile__내장 어 셈 블 리 용법 약술:http://www.embedu.org/Column/Column28.htm
3.:http://wenku.baidu.com/view/72c12e4133687e21af45a990.html
2.C 와 어 셈 블 리 혼합 프로 그래 밍 개요
1. 준수 해 야 할 규칙
C 언어 를 사용 할 때 어 셈 블 리 언어 와 의 혼합 프로 그래 밍 을 사용 해 야 한다.어 셈 블 리 코드 가 간결 하면 어 셈 블 리 를 직접 내장 하 는 방법 을 사용 할 수 있다.그렇지 않 으 면 어 셈 블 리 프로그램 을 프로젝트 에 파일 형식 으로 추가 하고 ATPCS(ARM/thumb 프로 세 스 호출 기준,ARM/thumb Procedure Call Standard)의 규정 에 따라 C 프로그램 과 상호 호출 하고 방문 해 야 한다. 
C 프로그램 과 ARM 어 셈 블 리 프로그램 이 서로 호출 될 때 는 ATPCS 규칙 을 준수 해 야 한다.ATPCS 는 일부 서브루틴 간 호출 의 기본 규칙,어떤 레지스터 의 사용 규칙,스 택 의 사용 규칙 과 매개 변수의 전달 규칙 등 을 규정 했다.
2. ATPCS 규칙
2.1 레지스터 사용 규칙
레지스터 r0~r3:서브루틴 간 에 r0~r3 를 통 해 파 라 메 터 를 전달 합 니 다.매개 변수 개수 가 4 개 이상 일 때 스 택 을 사용 하여 파 라 메 터 를 전달 합 니 다.이때 r0~r3 는 A1~A4 로 기록 할 수 있다.
레지스터 r4~r11:서브루틴 에서 r4~r11 을 사용 하여 부분 변 수 를 저장 합 니 다.따라서 서브루틴 호출 을 할 때 이 레지스터 들 의 저장 과 복구 에 주의해 야 한다.이때 r4~r11 은 V1~V8 로 기록 할 수 있 습 니 다.
레지스터 r12:스 택 포인터 SP 를 저장 하 는 데 사 용 됩 니 다.하위 프로그램 이 돌아 올 때 이 레지스터 를 사용 하여 스 택 을 나 가 IP 로 기록 합 니 다.
레지스터 r13:스 택 포인터,SP 로 기록 합 니 다.
레지스터 r14:레지스터 를 연결 하고 LR 로 기록 합 니 다.서브루틴 의 반환 주 소 를 저장 합 니 다.
레지스터 r15:프로그램 카운터,PC 로 기록 합 니 다.
2.2 스 택 사용 규칙
ATPCS 는 스 택 이 전체 체감 유형(FD,Full Descending)을 사용 하도록 규정 하고 있다.즉,스 택 은 메모리 주 소 를 줄 여 아래로 늘 어 나 고 스 택 지침 은 유효 데이터 항목 이 포 함 된 최소 주 소 를 가리킨다.
2.3 매개 변수의 전달 규칙
정수 매개 변수:앞의 4 개 는 r0~r3 로 전달 하고 다른 매개 변 수 는 스 택 으로 전달 합 니 다.부동 소수점 파라미터:번호 가 가장 작고 수 요 를 만족 시 킬 수 있 는 연속 적 인 FP 레지스터 전달 파 라미 터 를 사용 합 니 다.
서브루틴 의 반환 결과 가 32 비트 정수 일 때 r0 을 통 해 돌아 갑 니 다.결 과 를 64 비트 정수 로 되 돌려 줄 때 r0 과 r1 을 통 해 되 돌려 줍 니 다.이에 따라 유추 하 다.결과 가 부동 소수점 일 때 부동 소수점 연산 위 젯 의 레지스터 F0,D0 또는 S0 을 통 해 되 돌 아 옵 니 다.
3. 어 셈 블 리 호출 C 프로그램
어 셈 블 리 프로그램의 작성 은 ATPCS 규칙 에 따라 프로그램 이 호출 될 때 매개 변수 가 정확하게 전달 되도록 해 야 한다.
어 셈 블 리 프로그램 에서 C 프로그램 을 호출 하 는 방법 은 다음 과 같다.우선 어 셈 블 리 프로그램 에서 IMPORT 의사 명령 을 사용 하여 호출 할 C 언어 함 수 를 설명 한다.그리고 BL 명령 을 통 해 C 함 수 를 호출 합 니 다.
예 를 들 어 C 소스 파일 에서 다음 과 같은 구 화 함 수 를 정의 합 니 다.
int add(int x,int y)
{
	return(x+y);
}

 
 
add()함 수 를 호출 하 는 어 셈 블 리 프로그램 구 조 는 다음 과 같 습 니 다.
IMPORT add ;      C  
……
MOV r0,1
MOV r1,2
BL add ;  C  add
……

 
 
함수 호출 을 진행 할 때 r0 과 r1 을 사용 하여 매개 변 수 를 전달 하고 결 과 를 r0 에서 가 져 옵 니 다.함수 호출 이 끝 난 후 r0 의 값 은 3 으로 변 합 니 다.
4. C 프로그램 호출 어 셈 블 리 프로그램
C 프로그램 이 어 셈 블 리 프로그램 을 호출 할 때 어 셈 블 리 프로그램의 작성 도 ATPCS 규칙 에 따라 프로그램 이 호출 될 때 매개 변수 가 정확하게 전달 되도록 해 야 한다.
C 프로그램 에서 어 셈 블 리 서브루틴 을 호출 하 는 방법 은 다음 과 같 습 니 다.우선 어 셈 블 리 프로그램 에서 EXPORT 의사 명령 으로 호출 된 서브루틴 을 사용 하여 이 서브루틴 이 다른 파일 에서 호출 될 것 임 을 표시 합 니 다.그리고 C 프로그램 에서 extern 키 워드 를 사용 하여 호출 할 어 셈 블 리 서브루틴 을 외부 함수 로 설명 합 니 다.
예 를 들 어 어 어 셈 블 리 소스 파일 에서 다음 과 같은 요구 와 함 수 를 정의 합 니 다.
EXPORT add ;  add           
……
add ;     add
ADD r0,r0,r1
MOV pc,lr
……

 
 
C 프로그램의 main()함수 에서 add 어 셈 블 리 서브루틴 을 호출 하 였 습 니 다.
extern int add (int x,int y); //  add     

void main(){
	int a=1,b=2,c;
	c=add(a,b); //  add   
	...
}

       main()함수 가 add 어 셈 블 리 서브루틴 을 호출 할 때 변수 a,b 의 값 은 r0 과 r1 에 게 주 고 결 과 는 r0 에서 가 져 오 며 변수 c 에 값 을 부여 합 니 다.함수 호출 이 끝나 면 변수 c 의 값 이 3 으로 변 합 니 다.
5. C 프로그램 에 어 셈 블 리 문 구 를 삽입 합 니 다.
       C 언어 에 어 셈 블 리 문 구 를 삽입 하면 일부 고급 언어 가 실현 되 지 못 하거나 실현 하기 어 려 운 기능 을 실현 할 수 있다.시간 이 촉박 한 기능 도 C 언어 에 어 셈 블 리 문 구 를 삽입 해 실현 할 수 있다.내 장 된 어 셈 블 리 는 대부분의 ARM 명령 과 Thumb 명령 을 지원 하지만 PC 를 직접 수정 하여 점프 를 실현 하 는 바 텀 기능 은 지원 되 지 않 으 며 C 언어의 변 수 를 직접 참조 할 수 없습니다.
3.C 프로그램 에 어 셈 블 리 문 구 를 삽입 합 니 다.
  
내 연 어 셈 블 리 형식 은 다음 과 같다.
__asm__ __volatile__(
	"Instruction List" 
	:Output Operand List
	:Input Operand List
	:Clobber/Modify List
);

다음은 간단 한 내장 어 셈 블 리 샘플 입 니 다.
#include   

int main(int argc, char **argv)  
{    
	int in = 100;   
	int out;  

   	__asm__ __volatile__(  
		"mov r0, %[input]
" "mov %[output], r0
" :[output]"=r"(out) :[input]"r"(in) :"r0" ); printf("out = %d
", out); return 0; }

 
 (1).
 __asm__GCC 키워드 asm 의 매크로 정의 입 니 다.asm__또는 asm 는 내 연 어 셈 블 리 표현 식 을 설명 하 는 데 사용 되 기 때문에 모든 내 연 어 셈 블 리 표현 식 은 그것 으로 시작 하 므 로 없어 서 는 안 됩 니 다.
#define __asm__ asm

  (2). __volatile__GCC 키워드 volatile 의 매크로 정의 입 니 다.volatile__아니면 volatile 은 선택 할 수 있 습 니 다.이 를 사용 하면 GCC 에 이 내 연 어 셈 블 리 의 최 적 화 를 허용 하지 않 는 다 고 선언 합 니 다.그렇지 않 으 면 최적화 옵션(-O)을 사용 하여 컴 파일 할 때 GCC 는 자신의 판단 에 따라 이 내 연 어 셈 블 리 표현 식 의 명령 을 최적화 할 지 여 부 를 결정 합 니 다.
#define __volatile__ volatile

  (3). "Instruction List 는 명령 목록 입 니 다.모든 명령 은 반드시 쌍 따옴표 로 묶 여야 한다.두 명령 은 반드시 줄 을 바 꾸 거나 번 호 를 나 누 어야 한다.헤어지다
  (4). Output Operand List 는 현재 내 연 된 어 셈 블 리 문장의 출력 연산 자 목록 을 지정 합 니 다.모든 출력 조작 자 는 세 부분 으로 구성 되 어 있 습 니 다.괄호[]의 기호 이름,문자열'=r',괄호()의 C 표현 식 으로 구성 되 어 있 습 니 다.출력 연산 자 사이 에 쉼표 를 사용 합 니 다.","분할 합 니 다.즉:[out1]"=r"(value 1), [out2]"=r"(value2), ... [outn]"=r"(valuen)
  (5). Input Operand List 는 현재 내 연 된 어 셈 블 리 문장의 입력 연산 자 목록 을 지정 합 니 다.방법즉:[in1]"=r"(value 1),[in2]"=r"(value 2),...[in1]"=r"(valen).
  (6). Clobber/Modify List 는 GCC 에 현재 내 연 된 어 셈 블 리 문 구 를 일부 레지스터 나 메모리 에 수정 할 수 있 음 을 알 립 니 다.GCC 가 컴 파일 할 때 이 점 을 고려 할 수 있 기 를 바 랍 니 다.이러한 상황 은 일반적으로 하나의 레지스터 가"Instruction List"에 나타 나 지만,Input/Output 조작 표현 식 이 지정 한 것 이 아니 며,일부 Input/Output 조작 표현 식 이"r"제약 을 사용 할 때 GCC 가 선택 한 것 도 아니 며,동시에 이 레지스터 는"Instruction List"의 명령 에 의 해 수정 되 었 으 며,이 레지스터 는 현재 내 연 어 셈 블 리 에 임시 적 으로 사용 되 는 경우 에 만 발생 합 니 다.
내 연 된 어 셈 블 리 문장의 Clobber/Modify 도 메 인 에'memory'가 존재 한다 면 GCC 는 이 내 연 된 어 셈 블 리 전에 메모리 의 내용 이 레지스터 에 불 러 오 면 이 내 연 된 어 셈 블 리 후에 이 메모리 의 내용 을 사용 해 야 한다 면 레지스터 에 저 장 된 복사 본 을 사용 하지 않 고 이 메모리 에서 다시 읽 을 것 을 보증 합 니 다.이 럴 때 레지스터 의 복사 가 메모리 의 내용 과 일치 하지 않 을 가능성 이 높 기 때문이다.
상술 한 설명 을 종합 하면 일반적인 내장 어 셈 블 리 는 다음 과 같이 표시 할 수 있다.
__asm__ __volatile__(
	"Instruction 1
" "Instruction 2
" ... "Instruction n
" :[out1]"=r"(value1), [out2]"=r"(value2), ... [outn]"=r"(valuen) :[in1]"=r"(value1), [in2]"=r"(value2), ... [inn]"=r"(valuen) :"r0", "r1", ... "rn" );

 
입력/출력 연산 자 목록 의 구성 부분 중 하 나 는 제한 문자열 입 니 다.ARM 프로세서 에 대해 GCC 4 는 다음 과 같은 제한 을 제공 합 니 다.
Constraint
Usage in ARM state
Usage in Thumb state
f
Floating point registers f0 .. f7
Not available
h
Not available
Registers r8..r15
G
Immediate floating point constant
Not available
H
Same a G, but negated
Not available
I
Immediate value in data processing instructions e.g. ORR R0, R0, #operand
Constant in the range 0 .. 255 e.g. SWI operand
J
Indexing constants -4095 .. 4095 e.g. LDR R1, [PC, #operand]
Constant in the range -255 .. -1 e.g. SUB R0, R0, #operand
K
Same as I, but inverted
Same as I, but shifted
L
Same as I, but negated
Constant in the range -7 .. 7 e.g. SUB R0, R1, #operand
l
Same as r
Registers r0..r7 e.g. PUSH operand
M
Constant in the range of 0 .. 32 or a power of 2 e.g. MOV R2, R1, ROR #operand
Constant that is a multiple of 4 in the range of 0 .. 1020 e.g. ADD R0, SP, #operand
m
Any valid memory address
N
Not available
Constant in the range of 0 .. 31 e.g. LSL R0, R1, #operand
O
Not available
Constant that is a multiple of 4 in the range of -508 .. 508 e.g. ADD SP, #operand
r
General register r0 .. r15e.g. SUB operand1, operand2, operand3
Not available
w
Vector floating point registers s0 .. s31
Not available
X
Any operand
 
제한 문 자 는 하나의 수정자 로 표시 할 수 있 습 니 다.수정자 가 표시 하지 않 은 기본 값 은 읽 기 전용 연산 자 입 니 다.
조작 부호
설명 하 다.
=
동작 만 쓰 고 모든 출력 연산 자 에 사용 합 니 다.
+
읽 기와 쓰기 연산 자 는 출력 연산 자 에 사용 해 야 합 니 다.
&
출력 에 만 사용 할 수 있 는 레지스터 입 니 다.입력 동작 수 와 같은 레지스터 를 사용 할 수 없습니다.

좋은 웹페이지 즐겨찾기