컴파일러와 어셈블러간에 실제 차이점이 있습니까?


15

둘 사이에 어떤 차이가 있습니까? 당으로 Ullman은의 책 , 컴파일러는 다른 (일반적으로 낮은 수준) 언어로 하나 개의 언어를 변환하고, 그래서 어셈블러 않습니다. 두 사람은 어떻게 다릅니 까?


1
어셈블러 특정 작업 집합을 수행하는 컴파일러입니다. 용어는 실제로 다소 차이가 있지만 "컴파일러"의 기본 정의 (언어 간 번역)가 적용됩니다.
Raphael

모든 어셈블러는 한 언어를 다른 언어로 변환하기 때문에 (간단한) 컴파일러입니다. 모든 컴파일러가 어셈블러 인 것은 아닙니다.
user253751

답변:


16

어셈블러는 어셈블리 코드를 기계 코드로 변환합니다. 번역은 기계식이며 한 가지 방식으로 만 수행 할 수 있습니다. 반대로, 컴파일러는 관련 프로그래밍 언어를 컴파일 할 때 더 많은 자유가 있습니다. 예를 들어 최적화 할 수 있으며 최적화되지 않은 컴파일러조차도 다른 코드를 생성합니다. 또한 컴파일러는 "프론트 엔드"(프로그래밍 언어에 해당)와 "백 엔드"(컴퓨터 아키텍처에 해당)를 분리하는 방식으로 작성 될 수 있지만 어셈블러에서는 두 가지가 항상 동일합니다.


2
번역이 한 가지 방법으로 만 수행되는 이유는 무엇입니까? 이는 주어진 기계 코드 (및 대상 아키텍처)에 대해 원래 asm 코드를 생성 할 수 없음을 의미합니까? 그것은 나에게 직관적 인 소리입니다. 주어진 머신 코드 명령어가 여러 asm 명령어에 매핑 될 수 있다면 머신은 실행할 명령어를 어떻게 결정합니까? 뭔가 빠졌습니까?
Utku

3
()

또한 Ullman의 책에서 컴파일러에는 프론트 엔드와 백엔드가 있습니다. 내가 맞으면 백엔드는 중간 언어로 최적화, 기계어 코드 생성 및 기계어 코드 최적화를 수행하며 세 가지 작업 각각은 여러 가지 방법으로 수행 할 수 있습니다. "백엔드"부분은 어셈블러입니까? 중급 언어는 어셈블리 언어입니까? 당신의 대답은 어셈블러가 한 가지 방식으로 만 일한다고 언급합니다.
Tim

여기에 게시했습니다 cs.stackexchange.com/questions/98854/…
Tim

중급 언어는 일반적으로 기계와 무관 한 언어를 말합니다.
Yuval Filmus

11

결론은 더 재미 있다는 것입니다 은 어셈블러보다 컴파일러를 작성하는 . 어셈블리 언어는 일반적으로 구문 분석 및 유형 검사에 거의 사소하지 않도록 설계되었으며 많은 테이블 구동 생성기를 포함하는 경향이 있습니다 ( "추가를위한 opcode는 01110입니다", "로드 명령의 경우 대상 피연산자 레지스터는 비트 17에서 21까지 지정됨) "). 일반적으로 어셈블러에서 가장 흥미로운 부분은 기호 레이블을 숫자로 해석하는 부분입니다.

하나 대부분의 어셈블러는 소량의 산술을 수행 할 수 있으며 (예를 들어 작은 상수를 가진 기호 레이블을 함께 추가) 대부분의 어셈블러는 매크로 처리 기능을 갖추고 있거나 통합되어 있습니다. (대부분의 유닉스 시스템에서 매크로 기능은 실제로 어셈블리에 C 프리 프로세서를 실행하여 어셈블러에 전달함으로써 매크로 기능이 제공됩니다.)

MIPS 어셈블러는이를 넘어서서 흥미로운 코드 생성 결정을 내리고 소량의 최적화를 수행했습니다. 예를 들어 MIPS 기계 언어는 다른 상수를로드하기 위해 다른 코드 시퀀스가 ​​필요하므로, 상수를 생성 한 후 어셈블러는 코드 시퀀스를 선택해야했습니다 . 또한 MIPS 기계 코드에는 지연 슬롯 이라는 개념이 있지만이를 추상화하고 컴파일러에보다 "일반적인"추상 어셈블리 언어를 제공하는 것은 어셈블러의 책임입니다. 따라서 MIPS 어셈블러는 일부 로컬 명령어 스케줄링을 수행해야합니다.

구별 더의 일부가 흐릿 노먼 램지 특히, '작품 자신의 C-- 휴대용 어셈블리 언어에 . (관련 논문은 Ramsey와 Peyton Jones, "예외의 다중 구현을 지원하는 단일 중급 언어", Lang. Impl. 및 Dsgn. , (PLDI-21) : 285–298, 2000) . 마지막으로 또한 메모리 안전성을 보장 할 수있는 어셈블러가있는 David Walker와 Greg Morrisett 의 Typed Assembly Language 입니다.


0

여기에 약간의 간단한 대답이 있습니다. 현실은 더 복잡합니다. 어셈블러 (A)와 컴파일러 (C)의 차이점은 다음과 같습니다.

  1. 한 줄의 소스 코드는 하나의 CPU opcode와 직접 관련되거나 (A)
  2. 실제 CPU (A) 또는 시스템 독립성 (C)에 크게 의존

우리는 어셈블리 언어를 "낮은 수준"이라고 부르는 경향이 있으며, 컴파일러는 "높은 수준"을 이해하는 소스 언어를 사용합니다.

어셈블리 언어에서는 다음과 같이 말해서 추가 작업을 수행 할 수 있습니다.

  • a, b를 추가하십시오 (하나의 특정 CPU에 대해)
  • R5, R6 추가 (다른 CPU 용)
  • (A5), D2 추가 (다른 CPU 용)

고급 언어로 다음을 작성할 수 있습니다.

  • x = y + z;

그리고 여러 상황에 따라 하나의 명령어 또는 수백 개의 명령어가 발생할 수 있습니다. 하나는 컴파일러가 명령어를 생성하는 CPU입니다.

보시다시피 어셈블리 소스 언어는 가장 빈번합니다. (A) 한 줄의 소스 코드는 한 줄의 CPU opcode를 제공하며 어떤 CPU를 대상으로하는지에 따라 달라집니다. 고급 언어 (C) 컴파일러는 이러한 모든 세부 사항을 처리합니다. 한 줄의 소스 코드는 0이 될 수 있고 하나 또는 많은 CPU opcode가 될 수 있으며 컴파일러는 CPU가 수행 할 수있는 작업의 세부 사항을 처리합니다.

오늘날 컴파일러는 종종 여러 단계로 구성됩니다. 그것들은 프론트 엔드 / 백엔드 또는 다른 것들이라고 불리는 꿀벌 일 수 있습니다. 나는 보통 그것들을 네 단계로 본다 :

  1. 첫 번째 단계는 실제 소스 코드를 읽고 내부 표현을 만듭니다. 이 단계에서는 실제 소스 언어를 알고 있습니다.
  2. 두 번째 단계는 내부 표현을보고 여러 가지 최적화를 수행합니다. 요즘 컴파일러는 일반적으로 프로그램이 더 빨라지고 더 커지면 신경 쓰지 않아도됩니다. 최적화는 내부 표현에서 수행됩니다. 흥미롭게도, 이것의 일부는 여러 다른 언어에서 일반적 일 수 있습니다.
  3. 세 번째 단계는 내부 표현을 취하여 선택한 CPU에 대한 실제 코드를 작성합니다. 이 단계에는 다른 CPU를 대상으로하는 여러 가지 버전이있을 수 있습니다. 실제로 소스 코드를 한 번 작성한 다음 다른 CPUS 용으로 컴파일 할 수 있습니다.
  4. 프로그램 "패키징"에 대한 최종 준비 (이 단계는 링커 일 수 있음).

좋은 컴파일러를 작성하는 것은 고도로 숙련 된 직업입니다. 장난감 언어 컴파일러는 오후에 amatuer (또는 약간 더 길어질 수 있음)로 만들 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.