어셈블리 코드 대 머신 코드 대 객체 코드?


227

객체 코드, 기계 코드 및 어셈블리 코드의 차이점은 무엇입니까?

차이점을 시각적으로 보여줄 수 있습니까?


또한 "개체 코드"이름이 어디에서 유래했는지 궁금합니다. "객체"라는 단어의 의미는 무엇입니까? 그것은 객체 지향 프로그래밍이나 이름의 우연의 일치와 관련이 있습니까?
SasQ


개체 코드가 무엇인지 묻지 않고 있습니다. 대장님. 이름이 어디에서 왔으며 왜 "개체"코드라고 불리는 지 묻습니다.
BarbaraKwarc

답변:


296

머신 코드 는 CPU에서 직접 실행할 수있는 이진 (1 및 0) 코드입니다. 텍스트 편집기에서 컴퓨터 코드 파일을 열 수 있다면 당신은 인쇄 할 수없는 문자를 포함, 쓰레기를 볼 것입니다 (아니, 인쇄 할 수없는 문자)).

객체 코드 는 아직 완전한 프로그램에 연결되지 않은 기계 코드의 일부입니다. 완성 된 제품을 구성하는 특정 라이브러리 또는 모듈의 기계어 코드입니다. 또한 완료된 프로그램의 기계 코드에서 찾을 수없는 자리 표시 자 또는 오프셋이 포함될 수도 있습니다. 링커는 연결 모든 것을 함께 이러한 자리하고 오프셋을 사용합니다.

어셈블리 코드 는 일반 텍스트이며 사람이 읽을 수있는 사람이 읽을 수있는 소스 코드이며 대부분 기계 명령과 함께 직접적인 1 : 1 아날로그가 있습니다. 이것은 실제 명령어, 레지스터 또는 기타 리소스에 니모닉을 사용하여 수행됩니다. 예는 다음 JMPMULT는 CPU의 점프와 곱셈 지침. 머신 코드와 달리 CPU는 어셈블리 코드를 이해하지 못합니다. 일반적으로 CPU 명령어에서 더 추상화 된 고급 프로그래밍 언어와 관련된 컴파일러를 생각하지만 어셈블러 또는 컴파일러를 사용하여 어셈블리 코드를 기계로 변환 합니다.

완전한 프로그램을 구축 하려면 어셈블리 또는 C ++과 같은 고급 언어로 프로그램의 소스 코드 를 작성해야 합니다. 소스 코드는 객체 코드로 어셈블 (조립 코드 용) 또는 컴파일 (상위 언어 용)되어 있으며 개별 모듈은 서로 연결되어 최종 프로그램의 기계 코드가됩니다. 매우 간단한 프로그램의 경우 연결 단계가 필요하지 않을 수 있습니다. IDE (통합 개발 환경)와 같은 다른 경우에는 링커와 컴파일러가 함께 호출 될 수 있습니다. 다른 경우에는 복잡한 make 스크립트 또는 솔루션 파일을 사용하여 최종 애플리케이션을 빌드하는 방법을 환경에 알려줄 수 있습니다.

다르게 동작하는 해석 된 언어있습니다 . 해석 된 언어는 특수 통역사 프로그램의 기계어 코드에 의존합니다. 기본 레벨에서 인터프리터는 소스 코드를 구문 분석하고 명령을 새 기계 코드로 즉시 변환하여 실행합니다. 런타임 환경 또는 가상 머신 이라고도하는 최신 통역사 는 한 번에 소스 코드의 전체 섹션을 평가하고 가능한 경우 캐싱 및 최적화하며 복잡한 메모리 관리 작업을 처리하는 것이 훨씬 더 복잡합니다. 해석 된 언어는 어셈블리 코드와 유사한 하위 수준의 중간 언어 또는 바이트 코드로 사전 컴파일 될 수도 있습니다.


24
+1 : 훌륭하지만 다소 단순화 된 답변-모든 조립 명령이 기계 명령으로 1 : 1로 변환되는 것은 아니며, 객체 파일에는 다른 데이터 (이동 정보, 기호 테이블 등)도 포함될 수 있습니다.
Christoph

5
첫 번째 문제에 대한 족제비 단어를 추가하고 두 번째 문제를보다 명확하게하기 위해 편집했습니다.
Joel Coehoorn

2
@Christoph : "모든 조립 설명서가 1 : 1 기계 명령어로 번역 된 것은 아닙니다"라고 예를 들어주십시오.
Olof Forshell

5
@Olof : RISC 아키텍처는 때때로 어셈블리 레벨 가상 명령어 세트를 제공합니다 (예 : MIPS 의사 명령어 ( en.wikipedia.org/wiki/MIPS_architecture#Pseudo_instructions )
Christoph

3
@Panzercrisis 어셈블러가 추가 한 항목이 없습니다. 실제 기계 명령어에 작성한 내용을 직접 번역 한 것입니다. 그리고 컴파일러가 불필요한 코드를 "불필요한"것으로 부르지 않을 것입니다
Joel Coehoorn

125

다른 답변은 차이점에 대한 좋은 설명을 제공했지만 시각적으로도 요청했습니다. 다음은 C 코드에서 실행 파일로 이동하는 과정을 보여주는 다이어그램입니다.


3
나는 이것이 정말 도움이 있지만, "기계 코드"라벨이 없습니다
알렉스 로슈

실행 코드 수준에있을 때 머신 코드와 같은가요?
CMCDragonkai

3
이 다이어그램의 맥락에서 "개체 코드"는 기계어 코드입니다.
Graphics Noob

5
실제로 객체 코드와 실행 코드는 모두 기계 코드입니다. 차이점은 객체 코드가 완성 된 프로그램이 아니라는 것입니다. 완전한 실행 가능한 프로그램 / 코드를 형성하려면 다이어그램에 표시된대로 다른 도우미 라이브러리 / 모듈 코드와 결합되어야합니다.
okey_on

@okeyxyz는 프로세서가 직접 실행한다고 말하는 것이 어떤 수준입니까? 링커 후, 로더 후, 어셈블러 후 마이크로 컨트롤러로 변환 된 후?
Celeritas

49

어셈블리 코드는 사람이 읽을 수있는 기계 코드 표현입니다.

mov eax, 77
jmp anywhere

머신 코드는 순수한 16 진 코드입니다.

5F 3A E3 F1

객체 파일에서와 같이 객체 코드를 의미한다고 가정합니다. 이것은 링커가 채울 수 있도록 점프가 매개 변수화되는 것과 다른 기계 코드의 변형입니다.

어셈블러는 어셈블리 코드를 기계 코드 (객체 코드)로 변환하는 데 사용됩니다. 링커는 여러 객체 (및 라이브러리) 파일을 링크하여 실행 파일을 생성합니다.

한때 순수한 16 진수로 어셈블러 프로그램을 작성했습니다.


76
아니 아니 아니 아니. 머신 코드는 16 진 코드가 아닙니다. 순수한 바이너리입니다. 16 진수 코드는 편리한 이진 표현입니다.
Breton

56
우리가 이진이 아닌 극단으로 가고 있다면 회로에 저장된 전기량입니다. ;-)
Toon Krijthe

17
네 물론 이죠 16 진수와 "기계 코드"라고하는 관계가 있지만 16 진수 기계 코드 라고 말하는 것은 정확하지 않습니다 . 그것이 내가 말하려는 전부입니다.
Breton

9
@Breton 그런 의미에서 "16 진 코드"와 같은 것은 없습니다. "육각 코드"는 기계 코드를 보는 방법입니다. 머신 코드는 16 진수, 2 진수, 8 진수, 10 진수 또는 원하는대로 볼 수 있습니다. 또한 그런 의미에서 "이진 코드"도 없습니다. "이진 코드"는 기계 코드를 보는 방법 일뿐입니다.
Utku

9
@Breton 당신이 말하는 것은 실제로 이해가되지 않습니다 .. 바이너리는 16 진수처럼 표현의 방법입니다. 16 진수가 아니면 이진도 아닙니다.
Koray Tugay

18

8B 5D 32 기계 코드입니다

mov ebx, [ebp+32h] 조립이다

lmylib.so포함하는 8B 5D 32객체 코드


8

아직 언급되지 않은 점은 몇 가지 다른 유형의 어셈블리 코드가 있다는 것입니다. 가장 기본적인 형태에서 명령어에 사용 된 모든 숫자는 상수로 지정해야합니다. 예를 들면 다음과 같습니다.

$ 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 레이블에 매핑 된 주소를 참조합니다. 이 스타일의 어셈블러를 사용하면 모든 주소를 직접 입력하고 유지 관리해야하는 경우보다 코드를 작성하고 편집하기가 훨씬 쉽습니다.


1
+1. 추가로 한 가지 더 지적해야 할 점은 다양한 어셈블리 언어 구문이 있으며, 가장 유명한 것은 Intel 및 AT & T 입니다.
informatik01

1
@ informatik01 : Intel 8080 니모닉과 Zilog Z80은 어떻습니까? 나는 그것이 인텔 대 AT & T 구문 전쟁에 앞서 있다고 생각합니다.
supercat

논쟁의 여지없이, 나는 그 측면 (다른 구문)을 언급했으며 가장 널리 알려진 / 잘 알려진 / 유명한 구문의 예를 제시했습니다.
informatik01

4

소스 코드, 어셈블리 코드, 머신 코드, 객체 코드, 바이트 코드, 실행 파일 및 라이브러리 파일.

이 모든 용어들은 종종 그들이 배타적이라고 생각 한다는 사실 때문에 대부분의 사람들에게 매우 혼란스러워합니다 . 관계를 이해하려면 다이어그램을 참조하십시오. 각 용어에 대한 설명은 다음과 같습니다.


코드의 종류


소스 코드

사람이 읽을 수있는 프로그래밍 언어로 된 지침


고급 코드


C, C ++ 및 Java 프로그램과 같은 고급 (프로그래밍) 언어로 작성된 명령어


조립 코드

어셈블리 언어로 작성된 명령 (종류의 저수준 프로그래밍 언어). 컴파일 프로세스의 첫 번째 단계로 고급 코드가이 형식으로 변환됩니다. 어셈블리 코드는 실제 기계 코드로 변환됩니다. 대부분의 시스템에서이 두 단계는 컴파일 프로세스의 일부로 자동 수행됩니다.
예 : program.asm


객체 코드

컴파일 프로세스의 결과물입니다. 기계 코드 또는 바이트 코드 형식 일 수 있습니다.
예 : file.o


기계 코드

기계 언어로 된 지침.
예 : a.out


바이트 코드

JVM과 같은 인터프리터에 의해 실행될 수있는 중간 형식의 명령어.
예를 들어, Java 클래스 파일


실행 가능 파일

연결 과정의 결과물. 그것들은 CPU에 의해 직접 실행될 수있는 머신 코드입니다.
예를 들어 .exe 파일입니다.

일부 상황에서 바이트 코드 또는 스크립팅 언어 명령어가 포함 된 파일도 실행 가능한 것으로 간주 될 수 있습니다.


라이브러리 파일

일부 코드는 재사용 성과 같은 여러 가지 이유로이 형식으로 컴파일되어 나중에 실행 파일에서 사용됩니다.


1
모든 어셈블리가 사람이 작성 및 / 또는 유지하는 가장 엄격한 코드 의미에서 소스 가되는 것은 아니라고 주장합니다 . 종종 소스에서 기계로 생성되고 사람이 소비하지 않도록 의도합니다 (예를 들어 gcc는 실제로 cc1실행 파일 내에 내장 어셈블러를 사용하는 대신 별도의 어셈블러에 공급되는 asm 텍스트를 만듭니다 ). asm 서클은 "source"서클의 왼쪽에 튀어 나와야한다고 생각합니다. 일부 asm은 소스가 아니라 asm이기 때문입니다. 그것은 결코 객체 물론, 코드,하지만 일부 ASM은 소스에서 오브젝트 파일로가는 길의 단계입니다.
Peter Cordes

@PeterCordes 댓글 주셔서 감사합니다. 나는 gcc의 작동에 대해 당신이 무엇을 말했는지 몰랐습니다. 그러나 나는 당신에게 완전히 동의 할 수 있는지 두려워합니다. 내 말은, 소스 코드는 사람이 읽을 수있는 프로그래밍 언어를 사용하여 작성된 것입니다. 인간이 작성하거나 유지하지 않을 수 있습니다. 나는 당신이 트랜스 컴파일러를 알고있을 것이라고 확신한다. 당신의 관점에서, 그러한 컴파일러의 제품을 어떤 범주에 넣을 것인가? 소스 코드 또는 다른 것? 내가 틀렸다면 정정 해주세요. 추가 의견은 언제나 환영합니다.
버트 램 길 포일

1

어셈블리 코드는 여기에서 설명 합니다 .

"조립 언어는 컴퓨터 프로그래밍을위한 저수준 언어입니다. 특정 CPU 아키텍처를 프로그래밍하는 데 필요한 숫자 기계 코드 및 기타 상수를 상징적으로 표현합니다."

머신 코드는 여기에서 설명 합니다 .

"기계 코드 또는 기계 언어는 컴퓨터의 중앙 처리 장치에서 직접 실행되는 명령 및 데이터 시스템입니다."

기본적으로 어셈블러 코드는 언어이며 어셈블러 (컴파일러와 유사)에 의해 객체 코드 (CPU가 실행하는 기본 코드)로 변환됩니다.


1

이것이 주요한 차이점이라고 생각합니다

  • 코드의 가독성
  • 코드가하는 일을 제어

가독성은 코드를 작성하고 6 개월 후에 코드를 개선하거나 대체 할 수 있도록하는 반면, 성능이 중요한 경우에는 프로덕션 환경에있는 특정 하드웨어를 대상으로 저수준 언어를 사용하고자 할 수 있습니다. 빠른 실행.

오늘날 IMO 컴퓨터는 프로그래머가 OOP로 빠른 실행을 얻을 수있을 정도로 빠릅니다.


1

어셈블리는 CPU가 실제로 사용하는 기계어 코드로 직접 변환 될 수있는 인간이 이해할 수있는 짧은 용어입니다.

어셈블러는 인간이 다소 이해할 수 있지만 여전히 수준이 낮습니다. 유용한 작업을 수행하려면 많은 코드가 필요합니다.

대신 C, BASIC, FORTAN과 같은 고급 언어를 사용합니다. 컴파일하면 객체 코드가 생성됩니다. 초기 언어는 기계어를 객체 코드로 사용했습니다.

오늘날 JAVA 및 C #과 같은 많은 언어는 일반적으로 기계 코드가 아닌 런타임에 기계 코드를 생성하기 위해 쉽게 해석되는 바이트 코드로 컴파일됩니다.


Java 및 C #에 대한 귀하의 의견-바이트 코드가 해석되지 않도록 Just In Time 컴파일을 사용합니다. C # (. NET)은 보통 중간 언어 (IL)로 컴파일 된 다음 대상 CPU의 기본 기계 언어로 JIT됩니다.
Craig Shearer

-1

프로그램의 소스 파일은 객체 파일로 컴파일 된 다음 링커는 이러한 객체 파일을 서로 연결하여 아키텍처의 기계 코드를 포함한 실행 파일을 생성합니다.

객체 파일과 실행 파일은 모두 텍스트 편집기로 열 때 인쇄 가능한 문자와 인쇄 할 수없는 문자 형태의 아키텍처 머신 코드를 포함합니다.

그럼에도 불구하고 파일 사이의 이분법은 객체 파일에 확인할 수없는 외부 참조 (예 : 등)가 포함될 수 있다는 것 printf입니다. 따라서 다른 객체 파일과 연결해야 할 수도 있습니다. 즉, C / C ++ 런타임 라이브러리와 같은 다른 객체 파일과 연결하여 적절한 실행 가능 실행 파일을 얻으려면 해결되지 않은 외부 참조를 확인해야합니다. .

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