C 내 연 어 셈 블 리

4099 단어 어 셈 블 리
C 를 사용 하 는 프로그램 은 직접 어 셈 블 리 프로그램 을 사용 하 는 것 보다 더욱 간결 하고 가 독성 이 좋 지만 효율 은 어 셈 블 리 프로그램 보다 못 할 수 있다. 왜냐하면 C 프로그램 은 컴 파 일 러 를 통 해 어 셈 블 리 코드 를 생 성 해 야 하기 때문이다. 비록 현대 컴 파 일 러 의 최적화 가 잘 되 었 지만 손 으로 쓴 어 셈 블 리 코드 보다 못 하기 때문이다.또한 일부 플랫폼 과 관련 된 명령 은 반드시 손 으로 써 야 한다. C 언어 에 등가 의 문법 이 없다. C 언어의 문법 과 개념 은 각종 플랫폼 에 대한 추상 이기 때문에 각종 플랫폼 특유 의 일부 물건 은 C 언어 에 나타 나 지 않 는 다. 예 를 들 어 x86 은 포트 I / O 이 고 C 언어 는 이런 개념 이 없 기 때문에 in/out 명령 은 반드시 어 셈 블 리 로 써 야 한다.
C 언어 는 간결 하고 읽 기 쉬 우 며 규모 가 큰 코드 를 조직 하기 쉽 고 어 셈 블 리 효율 이 높 으 며 특수 명령 을 쓸 때 반드시 어 셈 블 리 를 사용 해 야 한다. 이 두 가지 장점 을 모두 차지 하기 위해 gcc 은 확장 문법 을 제공 하여 C 코드 에서 내 연 어 셈 블 리 (Inline Assembly) 를 사용 할 수 있다.가장 간단 한 형식 은 __asm__("assembly code");, 예 를 들 어 __asm__("nop"); 이다. , nop  이 명령 은 아무것도 하지 않 고 CPU 로 하여 금 명령 실행 주 기 를 공전 하 게 할 뿐이다.여러 개의 어 셈 블 리 명령 을 실행 해 야 한다 면
\t
으로 각 명령 을 분리 해 야 한다. 예 를 들 어:
__asm__("movl $1, %eax
\t" "movl $4, %ebx
\t" "int $0x80");

보통 C 코드 의 내 연 어 셈 블 리 는 C 의 변수 와 연결 되 어야 하 며 완전한 내 연 어 셈 블 리 형식 을 사용 해 야 합 니 다.
__asm__(assembler template 

	: output operands                  /* optional */

	: input operands                   /* optional */

	: list of clobbered registers      /* optional */

	);

이 형식 은 네 부분 으로 구성 되 어 있 으 며, 첫 번 째 부분 은 어 셈 블 리 명령 입 니 다. 위의 예 와 마찬가지 로 두 번 째 부분 과 세 번 째 부분 은 제약 조건 입 니 다. 두 번 째 부분 은 어 셈 블 리 명령 의 연산 결 과 를 어떤 C 작업 수 에 출력 해 야 하 는 지, C 작업 수 는 왼쪽 값 표현 식 이 어야 합 니 다. 세 번 째 부분 은 어 셈 블 리 명령 이 어떤 C 작업 수 에서 입력 해 야 하 는 지 를 표시 합 니 다.네 번 째 부분 은 어 셈 블 리 명령 에서 수 정 된 레지스터 목록 으로 컴 파일 러 의 어떤 레지스터 의 값 이 이 __asm__ 문 구 를 실행 할 때 변 하 는 지 알려 줍 니 다.뒤의 세 부분 은 모두 선택 할 수 있 고 있 으 면 작성 하고 없 으 면 비 워 서 : 번 만 쓴다.예 를 들 면:
예. 19.6. 인 라인 어 셈 블 리
#include <stdio.h>



int main() 

{

        int a = 10, b;



	__asm__("movl %1, %%eax
\t" "movl %%eax, %0
\t" :"=r"(b) /* output */ :"r"(a) /* input */ :"%eax" /* clobbered register */ ); printf("Result: %d, %d
", a, b); return 0; }

 
이 프로그램 은 변수 a 의 값 을 b 에 부여 합 니 다."r"(a) 지시 컴 파일 러 는 레지스터 저장 변수 a 의 값 을 할당 하고 어 셈 블 리 명령 의 입력, 즉 명령 중의 %1 (제약 조건 의 순서에 따라 b%0, a1% 에 대응 하 는 것) 에 대해 %1 이 어떤 레지스터 를 대표 하 는 지 는 컴 파일 러 가 스스로 결정 한다.어 셈 블 리 명령 은 먼저 %1 이 대표 하 는 레지스터 의 값 을 eax (%1 과 같은 자리 표시 자 를 구분 하기 위해 eax 앞 에 % 호 두 개 를 추가 하 라 고 요구) 에 전달 한 다음 에 eax 의 값 을 %0 이 대표 하 는 레지스터 에 다시 전달 하 라."=r"(b)%0 이 대표 하 는 레지스터 의 값 을 변수 b 에 출력 하 는 것 을 나타 낸다.이 두 명령 을 실행 하 는 과정 에서 레지스터 eax 의 값 이 바 뀌 었 기 때문에 "%eax" 을 네 번 째 부분 에 쓰 고 컴 파일 러 에 게 이 __asm__ 문 구 를 실행 할 때 eax 을 고 쳐 야 하 므 로 이 기간 에 eax 으로 다른 값 을 저장 하지 말 라 고 알려 주 었 다.
우 리 는 이 프로그램의 어 셈 블 리 결 과 를 살 펴 보 자.
        __asm__("movl %1, %%eax
\t" 80483dc: 8b 55 f8 mov -0x8(%ebp),%edx 80483df: 89 d0 mov %edx,%eax 80483e1: 89 c2 mov %eax,%edx 80483e3: 89 55 f4 mov %edx,-0xc(%ebp) "movl %%eax, %0
\t" :"=r"(b) /* output */ :"r"(a) /* input */ :"%eax" /* clobbered register */ );

이 를 통 해 알 수 있 듯 이 %0%1 은 모두 edx 레지스터 를 대표 한다. 먼저 변수 a (ebp-8 에 있 는 위치) 의 값 을 edx 에 전달 한 다음 에 내 연 된 어 셈 블 리 의 두 가지 명령 을 집행 한 다음 에 edx 의 값 을 b (ebp-12 에 있 는 위치) 에 전달한다.
내 연 어 셈 블 리 에 관 해 이렇게 많은 것 을 소개 하 는데, 이 책 은 깊이 토론 하지 않 는 다.

좋은 웹페이지 즐겨찾기