Chap3_프로그램의 기계수준 표현
3.2 프로그램의 인코딩
시스템은 보다 간단한 추상화 모델을 이용하여,
세부 구현 내용은 감추며, 추상화의 여러 형태를 사용한다
이들 중 기계 수준 프로그래밍에서 중요한 추상화는
-
- 인스트럭션 집합구조(ISA)
- 명령어의 집합을 정의하는 ‘아키첵쳐’
(일종의 인터페이스 역할을 한다)
- 인스트럭션 집합구조(ISA)
-
- 가상 주소
- 기계 수준 프로그램이 사용하는 주소
- 가상 주소
컴파일러는 전체 컴파일 순서에서 ‘C’에서 제공하는 추상화된 실행모델로 표현된
프로그램을 프로세서가 실행하는 명령어들로 변환하는 일을 수행한다
-
- 프로그램 카운터(PC)
- 실행할 다음 명령어의 메모리 주소를 가리킨다
(x86-64에선 %rip 라고도 한다)
- 프로그램 카운터(PC)
-
- 정수 레지스터 파일
- 64비트 값을 저장하기 위한, 16개의 이름을 붙인 위치를 갖는다.
주소, 정수 데이터를 저장하고, 일부는 프로그램의 상태를 추적하는데 사용하며,
다른 레지스터들은 함수의 리턴값, 프로시저의 지역변수와 인자 같은 임시값을
저장하는데 사용한다
(프로시저 : 함수 혹은 메서드, 서브루틴 등으로 불리우는 코드 블록)
- 정수 레지스터 파일
- 조건코드 레지스터
:가장 최근에 실행한 산술,논리 명령어에 관한 상태 정보를 저장한다
이후, 분기 명령어 사용시, 이들이 저장한 데이터를 이용한다 -
- 벡터 레지스터
- 여러 개의 데이터 요소들을 저장
병렬 연산, SIMD 아키텍쳐 지원시 해당 레지스터가 사용된다
- 벡터 레지스터
C에서는 다양한 종류의 데이터 타입을 선언하고 메모리에 데이터를 할당하지만,
기계어 코드에선 그저 연속된 바이트 들의 표시이다
프로그램 메모리는 프로그램의 실행 기계어 코드,
운영체제를 위한 일부 정보, 프로시저 호출과 리턴을 관리하는 런타임 스택
사용자에 의해 할당된 메모리 블록을 포함한다
이러한 ‘프로그램 메모리’는 실제 운영체제(OS)에서
실제 물리적 메모리(RAM)으로 할당될 때,
서로 떨어진 위치에 할당될 수 있다
(오히려 그런 경우가 더 많음)
운영체제는 ‘가상 주소’를 실제 물리적 주소값으로
번역해주는 역할을 한다
- 컴퓨터에 의해 실제 실행된 프로그램은
단순히 일련의 명령어를 인코딩한 일련의 바이트라는 점이다
이는 ‘명령어’들이 생성된 ‘소스코드’에 대한 정보가 거의 없다는 말이다
x86-64 명령어들은 1에서 15 바이트의 길이를 가진다.
명령어 인코딩 시, 자주 사용되는 명령어와 오퍼랜드는 적을 수록 짧은 길이를 가지며,
많을 수록 더 긴 명령어 길이를 가지도록 한다
(오퍼랜드(operand) : 연산자(operator)가 작업을 수행하는 대상 데이터 or 값
주로 상수 or 리터럴, 변수, 식 등이 이러한 형태이다)
=> 이는 메모리의 효율성과 성능 등 다양한 요소를 고려한 것이다
명령어 형식은
‘주어진 시작 위치에서부터 바이트들을 기계어 명령어로 유일하게 디코딩할 수 있도록 설계한다’
이 말의 뜻은
- 명령어 형식은 주어진 바이트 스트림에서
유일하게 디코딩 되어야 한다
(다양한 명령어로 해석되지 않는다 -> 중첩, 모호성 없음) - 명령어의 디코딩은 특정한 위치에서 시작되며,
그 위치로부터 일정한 바이트 수를 읽은 뒤,
명령어로 디코딩한다 - 디코딩된 명령어는 컴퓨터의 기계어 명령어로 해석된다
이는 프로세서가 직접 실행하는 명령어이기에,
명령어 인코딩은 프로세서의 동작을 정의한다
많은 명령어들은 접미어 ‘q’를 생략할 수 있다
q 는 ‘Quadword’를 나타내며 이는 64 비트 데이터를 의미한다
실제 실행시킬 때,
‘callq’ 명령어는 ‘링커’가
실제 함수의 위치를 채워준다
(링킹 단계 시, 비워져 있는 심볼을 채워주므로)
실제 명령어의 길이가 16바이트 이하인 경우,
nop 명령어가 삽입되어 명령어의 길이를 보완할 수 있다
nop 명령어는 아래의 상황에서 사용될 수 있다
-
- 코드 정렬
- 명령어가 4의 배수 주소에서 실행되기 위하여, nop를 삽입하여 길이를 맞춤
- 코드 정렬
- 캐시 라인 정렬
프로세서의 명령어 캐시는 일반적으로 고정된 크기의 블록(캐시 라인)으로
데이터를 가져오며, 명령어가 여러 캐시 라인에 걸쳐 있으면 캐시 미스가 발생할 수 있음
이 때, 명령어를 경계에 정렬하여, 캐시 미스를 최소화 하기 위하여 nop 명령어가 사용됨 - 패딩
명령어를 패딩하기 위하여 nop 명령어가 삽입될 수 있음
nop 명령어는 CPU에서는 무시된다
## 3.3 데이터의 형식
8비트 : Byte
16비트 : WORD
32비트 : Double Word
64비트 : Quad Word
이러한 형식으로 명령어들은 오퍼랜드의 크기를 나타내는 단일 접미사를 가지게 돤다
ex) mov
movb , movw, movl, movq
(참고로 32비트의 경우 l 인데, 이는 long word를 뜻한다)
3.4 정보 접근하기
-
- 오퍼랜드 식별자(specifier)
- 대부분의 명령어는 하나 이상의 오퍼랜드를 가진다
오퍼랜드는 연산을 수행할 소스 값과 그 결과를 저장할
목적지의 위치를 명시한다
오퍼랜드는 3가지 타입이 있다.
- immeditate : 상수
- register : 레지스터의 내용
- 메모리 참조 : 유효 주소라고 부르는 계산된 주소에 의해, 메모리 위치에 접근
- 오퍼랜드 식별자(specifier)
댓글남기기