ARM GCC 내장 어 셈 블 리

http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended-Asm
http://hi.baidu.com/wypnewbie/blog/item/563916ed2fe0c736269791ba.html
이 문서 에 대하 여
ARM 기반 RISC 프로세서 에 대해 GNU C 컴 파 일 러 는 C 코드 에 어 셈 블 리 를 삽입 하 는 기능 을 제공 합 니 다.이러한 매우 멋 진 특성 은 C 코드 에 없 는 기능 을 제공 합 니 다. 예 를 들 어 소프트웨어 의 관건 적 인 부분의 코드 를 수 동 으로 최적화 하고 관련 된 프로세서 명령 을 사용 합 니 다.
이 문 서 는 ARM 어 셈 블 리 매 뉴 얼 이 아니 기 때문에 독자 들 이 ARM 어 셈 블 리 프로그램 을 능숙 하 게 작성 하 는 독자 라 고 구상 했다.C 언어 수첩 도 아니다.
이 문 서 는 GCC 4 버 전 을 사용한다 고 가정 하지만 초기 버 전에 도 유효 하 다.
GCC asm 성명
간단 한 예 로 시작 합 시다.C 의 성명 처럼 아래 의 성명 코드 가 당신 의 코드 에 나타 날 수 있 습 니 다.
  /* NOP */
asm("mov r0,r0");


이 문장의 역할 은 r0 을 r0 으로 이동 시 키 는 것 이다.다시 말 하면 그 는 결코 어떤 일 도 하지 않 는 다.전형 적 인 것 은 NOP 명령 이 고, 작용 은 짧 은 시간의 지연 이다.
이 성명 은 당신 이 생각 하 는 다른 C 문구 와 같 지 않 기 때문에 이 문 서 를 읽 고 공부 하 세 요.내장 어 셈 블 리 는 어 셈 블 리 명령 을 사용 하 는 것 이 순 어 셈 블 리 프로그램 에서 사용 하 는 방법 과 같다.하나의 asm 성명 에 여러 개의 어 셈 블 리 명령 을 쓸 수 있다.그러나 프로그램의 가 독성 을 높이 기 위해 서 는 모든 어 셈 블 리 명령 을 한 줄 씩 두 는 것 이 좋다.
  asm(
"mov r0, r0
\t"
"mov r0, r0
\t"
"mov r0, r0
\t"
"mov r0, r0"
);


줄 바 꿈 문자 와 탭 문자 의 사용 은 명령 목록 을 아름 답 게 만 들 수 있다.처음 엔 좀 이상해 보일 수도 있 지만 C 컴 파일 러 가 C 문 구 를 컴 파일 하 는 것 은 기다 리 는 것 입 니 다. 그것 은 바로 위 (줄 바 꾸 기와 탭) 에 따라 어 셈 블 리 를 만 드 는 것 입 니 다.지금까지 어 셈 블 리 명령 은 네가 쓴 순 어 셈 블 리 프로그램의 코드 와 별 차이 가 없다.그러나 다른 C 성명 에 비해 asm 의 상수 와 레지스터 의 처 리 는 다르다.통용 되 는 내장 어 셈 블 리 모델 은 이렇다.asm(code : output operand list : input operand list : clobber list);
어 셈 블 리 와 C 문 구 를 연결 하 는 것 은 위의 asm 성명 에서 선택 할 수 있 는 output operand list 와 input operand list 입 니 다.Clobber list 뒤에 말씀 드 리 겠 습 니 다.
다음은 C 언어의 정형 변 수 를 어 셈 블 리 에 전달 하고 논리 가 왼쪽으로 한 자 리 를 옮 긴 후에 C 언어 에 전달 하 는 또 다른 정형 변수 입 니 다./* Rotating bits example */
asm("mov %[result], %[value], ror #1" : [result] "=r" (y) : [value] "r" (x));


모든 asm 문 구 는 사칭 (:) 으로 네 부분 으로 나 뉘 었 다.
l         어 셈 블 리 명령 은 첫 번 째 부분 중의 "중간 에 놓 여 있다.
  "mov %[result], %[value], ror #1"
l         다음은 콜론 이후 선택 할 수 있 는 output operand list 입 니 다. 각 항목 은 [] (괄호) 와 그 에 포 함 된 기호 명 으로 구성 되 어 있 습 니 다. 그 뒤 에는 제한 적 인 문자열 이 따 르 고 그 뒤 에는 괄호 와 묶 여 있 는 C 변수 입 니 다.이 예 에는 항목 이 하나 밖 에 없다.
  [result] "=r" (y)
l         이 어 콜론 뒤 에는 입력 연산 자 목록 이 있 습 니 다. 문법 은 입력 작업 목록 과 같 습 니 다.
  [value] "r" (x)
l         파괴 부적 목록, 이 예 에서 사용 되 지 않 음
위의 NOP 예 와 같이 asm 성명 의 4 개 부분 중 맨 끝 에 사용 되 지 않 은 부분 만 생략 할 수 있 습 니 다.그러나 주의해 야 할 것 은 위의 4 개 부분 중 뒤의 것 만 사용 해 야 하고 앞의 부분 은 사용 하지 않 아 도 생략 할 수 없 으 며 비 워 야 하지만 사칭 은 유지 해 야 한 다 는 점 이다.다음 예 는 ARM Soc 의 CPSR 레지스터 를 설정 하 는 것 입 니 다. input 이 있 지만 output operand 가 없습니다.  asm("msr cpsr,%[ps]" : : [ps]"r"(status))
어 셈 블 리 코드 가 사용 되 지 않 더 라 도 코드 부분 은 빈 문자열 을 유지 해 야 합 니 다.다음 의 예 는 컴 파일 러 메모리 가 수정 되 었 음 을 알 리 기 위해 특별한 파괴 자 를 사용 했다.이곳 의 파괴 부 호 는 아래 의 최적화 부분 에서 설명 하고 있다.  asm("":::"memory");
코드 의 가 독성 을 높이 기 위해 서 는 줄 바 꿈, 빈 칸, 그리고 C 스타일 의 주석 을 사용 할 수 있 습 니 다.asm("mov %[result], %[value], ror #1"

: [result]"=r" (y) /* Rotation result. */
: [value]"r" (x) /* Rotated value. */
: /* No clobbers */
);

코드 부분% 뒤에 따 르 는 것 은 뒤의 두 부분 괄호 중의 기호 로 같은 기호 조작 목록 의 한 항목 을 가리킨다.
% [result] 는 두 번 째 부분의 C 변수 y 를 나타 내 고% [value] 는 세 부분의 C 변수 x 를 나타 낸다.
기호 연산 자의 이름 은 독립 된 네 임 스페이스 를 사용 합 니 다.이것 은 그것 이 다른 기호 표를 사용 한 다 는 것 을 의미한다.쉽게 말 하면 사용 할 기호 명 은 C 코드 에서 이미 사용 되 었 다 는 것 이다.초기 C 코드 에서 순환 이동 의 예 는 이렇게 써 야 합 니 다.asm("mov %0, %1, ror #1" : "=r" (result) : "r" (value))
어 셈 블 리 코드 에서 조작 수의 인용 은% 뒤에 있 는 숫자 를 사용 합 니 다.% 1 은 첫 번 째 조작 수,% 2 코드 두 번 째 조작 수 를 의미 합 니 다. 앞으로 유추 합 니 다.이 방법 은 현재 최신 컴 파일 러 가 지원 되 고 있다.하지만 코드 를 유지 하기 가 쉽 지 않 습 니 다.생각해 보 세 요. 어 셈 블 리 명령 의 코드 를 많이 썼 습 니 다. 조작 수 를 삽입 하려 면 조작 수 번 호 를 새로 수정 해 야 합 니 다.
http://hi.baidu.com/yeyingxian/blog/item/57fb553427b4614e241f14c7.html
몇 가지 간단 한 예 {    uint32_t __hi;     uint32_t __lo;     uint32_t __result;     asm("smull  %0, %1, %3, %4\t"         "movs   %0, %0, lsr %5\t"         "adc    %2, %0, %1, lsl %6"         : "=&r" (__lo), "=&r" (__hi), "=r" (__result)         : "%r" (x), "r" (y),         "M" (SCALEBITS), "M" (32 - (SCALEBITS))         : "cc"); }
static INLINE real_t _MulHigh(real_t x, real_t y) {     uint32_t __lo;     uint32_t __hi;     asm("smull\t%0, %1, %2, %3"         : "=&r"(__lo),"=&r"(__hi)         : "%r"(x),"r"(y)         : "cc");     return __hi; }
static __inline__ int MULSHIFT32(int x, int y) {     int zlow;     __asm__ volatile ("smull %0,%1,%2,%3" : "=&r" (zlow), "=r" (y) : "r" (x), "1" (y) : "cc");     return y; }
1. asm 은 ANSI C 의 표준 키워드 가 아니 므 로 로 바 꿔 야 합 니 다.asm__
2. asm 뒤에 volatile 또는 를 추가 할 수 있 습 니 다.volatile__,컴 파일 러 에 게 asm 블록 의 내용 을 최적화 하지 말 라 고 알려 주세요.기본적으로 출력 결 과 를 사용 하지 않 을 때 GCC 는 asm 의 내용 을 삭제 하거나 명령 순 서 를 흐 트 러 뜨 려 최적화 합 니 다.
3. C / C + 표현 식 이 있 는 내 연 어 셈 블 리 형식 은:asm__ __volatile__("Instruction List" : Output : Input : Clobber/Modify);
4. 구속 부 함 의 ` r '     A register operand is allowed provided that it is in a general      register. `0', `1', `2', ... `9'      An operand that matches the specified operand number is allowed.      If a digit is used together with letters within the same      alternative, the digit should come last. `='      Means that this operand is write-only for this instruction: the      previous value is discarded and replaced by output data. `+'      Means that this operand is both read and written by the      instruction. `&'      Means (in a particular alternative) that this operand is an      "earlyclobber" operand, which is modified before the instruction is      finished using the input operands.  Therefore, this operand may      not lie in a register that is used as an input operand or as part      of any memory address. `%'      Declares the instruction to be commutative for this operand and the      following operand.  This means that the compiler may interchange      the two operands if that is the cheapest way to make all operands      fit the constraints.  GCC can only handle one commutative pair in      an asm; if you use more, the compiler may fail. `M'      Integer in the range 0 to 32
5、 If your assembler instruction can alter the condition code register, add `cc' to the list of clobbered registers.  GCC on some machines represents the condition codes as a specific hardware register; `cc' serves to name this register.  On other machines, the condition code is handled differently, and specifying `cc' has no effect.  But it is valid no matter what the machine.

좋은 웹페이지 즐겨찾기