객체 코드, 기계 코드 및 어셈블리 코드의 차이점은 무엇입니까?
차이점을 시각적으로 보여줄 수 있습니까?
객체 코드, 기계 코드 및 어셈블리 코드의 차이점은 무엇입니까?
차이점을 시각적으로 보여줄 수 있습니까?
답변:
머신 코드 는 CPU에서 직접 실행할 수있는 이진 (1 및 0) 코드입니다. 텍스트 편집기에서 컴퓨터 코드 파일을 열 수 있다면 당신은 인쇄 할 수없는 문자를 포함, 쓰레기를 볼 것입니다 (아니, 그 인쇄 할 수없는 문자)).
객체 코드 는 아직 완전한 프로그램에 연결되지 않은 기계 코드의 일부입니다. 완성 된 제품을 구성하는 특정 라이브러리 또는 모듈의 기계어 코드입니다. 또한 완료된 프로그램의 기계 코드에서 찾을 수없는 자리 표시 자 또는 오프셋이 포함될 수도 있습니다. 링커는 연결 모든 것을 함께 이러한 자리하고 오프셋을 사용합니다.
어셈블리 코드 는 일반 텍스트이며 사람이 읽을 수있는 사람이 읽을 수있는 소스 코드이며 대부분 기계 명령과 함께 직접적인 1 : 1 아날로그가 있습니다. 이것은 실제 명령어, 레지스터 또는 기타 리소스에 니모닉을 사용하여 수행됩니다. 예는 다음 JMP
과 MULT
는 CPU의 점프와 곱셈 지침. 머신 코드와 달리 CPU는 어셈블리 코드를 이해하지 못합니다. 일반적으로 CPU 명령어에서 더 추상화 된 고급 프로그래밍 언어와 관련된 컴파일러를 생각하지만 어셈블러 또는 컴파일러를 사용하여 어셈블리 코드를 기계로 변환 합니다.
완전한 프로그램을 구축 하려면 어셈블리 또는 C ++과 같은 고급 언어로 프로그램의 소스 코드 를 작성해야 합니다. 소스 코드는 객체 코드로 어셈블 (조립 코드 용) 또는 컴파일 (상위 언어 용)되어 있으며 개별 모듈은 서로 연결되어 최종 프로그램의 기계 코드가됩니다. 매우 간단한 프로그램의 경우 연결 단계가 필요하지 않을 수 있습니다. IDE (통합 개발 환경)와 같은 다른 경우에는 링커와 컴파일러가 함께 호출 될 수 있습니다. 다른 경우에는 복잡한 make 스크립트 또는 솔루션 파일을 사용하여 최종 애플리케이션을 빌드하는 방법을 환경에 알려줄 수 있습니다.
다르게 동작하는 해석 된 언어 도 있습니다 . 해석 된 언어는 특수 통역사 프로그램의 기계어 코드에 의존합니다. 기본 레벨에서 인터프리터는 소스 코드를 구문 분석하고 명령을 새 기계 코드로 즉시 변환하여 실행합니다. 런타임 환경 또는 가상 머신 이라고도하는 최신 통역사 는 한 번에 소스 코드의 전체 섹션을 평가하고 가능한 경우 캐싱 및 최적화하며 복잡한 메모리 관리 작업을 처리하는 것이 훨씬 더 복잡합니다. 해석 된 언어는 어셈블리 코드와 유사한 하위 수준의 중간 언어 또는 바이트 코드로 사전 컴파일 될 수도 있습니다.
다른 답변은 차이점에 대한 좋은 설명을 제공했지만 시각적으로도 요청했습니다. 다음은 C 코드에서 실행 파일로 이동하는 과정을 보여주는 다이어그램입니다.
어셈블리 코드는 사람이 읽을 수있는 기계 코드 표현입니다.
mov eax, 77
jmp anywhere
머신 코드는 순수한 16 진 코드입니다.
5F 3A E3 F1
객체 파일에서와 같이 객체 코드를 의미한다고 가정합니다. 이것은 링커가 채울 수 있도록 점프가 매개 변수화되는 것과 다른 기계 코드의 변형입니다.
어셈블러는 어셈블리 코드를 기계 코드 (객체 코드)로 변환하는 데 사용됩니다. 링커는 여러 객체 (및 라이브러리) 파일을 링크하여 실행 파일을 생성합니다.
한때 순수한 16 진수로 어셈블러 프로그램을 작성했습니다.
아직 언급되지 않은 점은 몇 가지 다른 유형의 어셈블리 코드가 있다는 것입니다. 가장 기본적인 형태에서 명령어에 사용 된 모든 숫자는 상수로 지정해야합니다. 예를 들면 다음과 같습니다.
$ 1902 : BD 37 14 : LDA $ 1437, X $ 1905 : 85 03 : STA $ 03 $ 1907 : 85 09 : STA $ 09 $ 1909 : CA : DEX $ 190A : 10 : BPL $ 1902
Atari 2600 카트리지의 주소 $ 1900에 저장된 위의 코드는 주소 $ 1437에서 시작하는 테이블에서 가져온 여러 색상의 행을 표시합니다. 일부 도구에서 위 줄의 가장 오른쪽 부분과 함께 주소를 입력하면 가운데 열에 표시된 값을 메모리에 저장하고 다음 주소로 다음 줄을 시작합니다. 이 형식으로 코드를 입력하는 것이 16 진수를 입력하는 것보다 훨씬 편리하지만 모든 정확한 주소를 알아야했습니다.
대부분의 어셈블러에서는 심볼 주소를 사용할 수 있습니다. 위의 코드는 다음과 같이 작성됩니다.
rainbow_lp : lda ColorTbl, x 스타 WSYNC sta COLUBK 덱스 bpl rainbow_lp
어셈블러는 LDA 명령어를 자동으로 조정하여 ColorTbl 레이블에 매핑 된 주소를 참조합니다. 이 스타일의 어셈블러를 사용하면 모든 주소를 직접 입력하고 유지 관리해야하는 경우보다 코드를 작성하고 편집하기가 훨씬 쉽습니다.
소스 코드, 어셈블리 코드, 머신 코드, 객체 코드, 바이트 코드, 실행 파일 및 라이브러리 파일.
이 모든 용어들은 종종 그들이 배타적이라고 생각 한다는 사실 때문에 대부분의 사람들에게 매우 혼란스러워합니다 . 관계를 이해하려면 다이어그램을 참조하십시오. 각 용어에 대한 설명은 다음과 같습니다.
사람이 읽을 수있는 프로그래밍 언어로 된 지침
C, C ++ 및 Java 프로그램과 같은 고급 (프로그래밍) 언어로 작성된 명령어
어셈블리 언어로 작성된 명령 (종류의 저수준 프로그래밍 언어). 컴파일 프로세스의 첫 번째 단계로 고급 코드가이 형식으로 변환됩니다. 어셈블리 코드는 실제 기계 코드로 변환됩니다. 대부분의 시스템에서이 두 단계는 컴파일 프로세스의 일부로 자동 수행됩니다.
예 : program.asm
컴파일 프로세스의 결과물입니다. 기계 코드 또는 바이트 코드 형식 일 수 있습니다.
예 : file.o
기계 언어로 된 지침.
예 : a.out
JVM과 같은 인터프리터에 의해 실행될 수있는 중간 형식의 명령어.
예를 들어, Java 클래스 파일
연결 과정의 결과물. 그것들은 CPU에 의해 직접 실행될 수있는 머신 코드입니다.
예를 들어 .exe 파일입니다.
일부 상황에서 바이트 코드 또는 스크립팅 언어 명령어가 포함 된 파일도 실행 가능한 것으로 간주 될 수 있습니다.
일부 코드는 재사용 성과 같은 여러 가지 이유로이 형식으로 컴파일되어 나중에 실행 파일에서 사용됩니다.
cc1
실행 파일 내에 내장 어셈블러를 사용하는 대신 별도의 어셈블러에 공급되는 asm 텍스트를 만듭니다 ). asm 서클은 "source"서클의 왼쪽에 튀어 나와야한다고 생각합니다. 일부 asm은 소스가 아니라 asm이기 때문입니다. 그것은 결코 객체 물론, 코드,하지만 일부 ASM은 소스에서 오브젝트 파일로가는 길의 단계입니다.
어셈블리는 CPU가 실제로 사용하는 기계어 코드로 직접 변환 될 수있는 인간이 이해할 수있는 짧은 용어입니다.
어셈블러는 인간이 다소 이해할 수 있지만 여전히 수준이 낮습니다. 유용한 작업을 수행하려면 많은 코드가 필요합니다.
대신 C, BASIC, FORTAN과 같은 고급 언어를 사용합니다. 컴파일하면 객체 코드가 생성됩니다. 초기 언어는 기계어를 객체 코드로 사용했습니다.
오늘날 JAVA 및 C #과 같은 많은 언어는 일반적으로 기계 코드가 아닌 런타임에 기계 코드를 생성하기 위해 쉽게 해석되는 바이트 코드로 컴파일됩니다.
프로그램의 소스 파일은 객체 파일로 컴파일 된 다음 링커는 이러한 객체 파일을 서로 연결하여 아키텍처의 기계 코드를 포함한 실행 파일을 생성합니다.
객체 파일과 실행 파일은 모두 텍스트 편집기로 열 때 인쇄 가능한 문자와 인쇄 할 수없는 문자 형태의 아키텍처 머신 코드를 포함합니다.
그럼에도 불구하고 파일 사이의 이분법은 객체 파일에 확인할 수없는 외부 참조 (예 : 등)가 포함될 수 있다는 것 printf
입니다. 따라서 다른 객체 파일과 연결해야 할 수도 있습니다. 즉, C / C ++ 런타임 라이브러리와 같은 다른 객체 파일과 연결하여 적절한 실행 가능 실행 파일을 얻으려면 해결되지 않은 외부 참조를 확인해야합니다. .