3.2 Programming Encodings
- parent: 3. Machine Level Representation of Programs {CSAPP}
- p.169~176
인코딩이라는것이, 결국 변환이라는 작업을 뜻하는 것이었고, 컴파일러(특히 GCC 컴파일러)가 C 코드를 변환해 돌리려고 하는 아키텍처의 명령어셋의 언어로 쓰여진 이진파일로 만드는 과정을 보여준다.
대부분의 명령어셋 아키텍처(ISA)는 순차적으로 읽히고 실행되게끔 만들어졌지만, 더 높은 성능향상을 위해 기계는 동시에 여러 명령어들을 한 번에 가져와 실행시킨다. 이때 발생할 수 있는 오차를 줄이기 위한 일종의 방어장치도 있아고 한다 근데 그게 지금 단원이랑 어울리는 내용이기는 한가?
자문자답#
- 전처리에서 무슨 일을 해요?
- 어셈블러가 목적파일로 코드를 변환했다고 바로 실행할 수 없는 이유가 뭐예요?
- 라이브러리 함수들 (
printf
)은 어디에 있고 언제 불러와져요?
INDEX#
- 3.2.1. Machine Level Code
- 3.2.2. Code Examples
- 3.2.3. Notes on Formatting
3.2.1 Machine Level Code#
- 프로그래머로부터 가려진 중요한 프로그램의 상태들 (registers)
- PC(Program Counter): 다음 실행할 명령어의 위치를 저장하고 있음.
%rip
- 다양한 방식으로 활용될 수 있는 16개의 64비트 레지스터: 임시 값 저장, 인자, 지역변수, 리턴값
- 조건문에서 활용할 수 있는 레지스터는 if, for, while문 등에서 계산된 연산결과를 저장하고 있다가 요긴하게 쓰일 수 있다고 한다.
- x86-64에서는 벡터 데이터를 저장하는 레지스터도 있다고 하대?
- PC(Program Counter): 다음 실행할 명령어의 위치를 저장하고 있음.
- 어셈블리 단에서는 배열이나 구조체를 그저 바이트 뭉치로 볼 뿐이다. 더군다나 데이터의 타입도 분해되어 signed integer, unsigned integer, 포인터 등등을 전혀 구별하지 않는다. 우리는 무의미한 바이트의 집합으로부터 의미를 해석하는 작업을 하고 있었던 것이다.
p.457 disassembler로 뜯어본 바이너리 코드
- x86-64 명령어 셋은 그 크기가 1byte ~ 15byte로 다양하다. 단순하고 인자가 적은 명령어도 굳이 1워드를 가득 채울 필요가 없기 때문이다.
- 명령어 형식은 시작위치가 정해진 경우가 있다. 예를 들어
pushq rbx
명령은 바이트값 53으로 시작할 수 있다. - disassembler는 GCC의 이름규칙과 다르다는 점 참고.