tgool
Tgool
tgool
전체 방문자
오늘
어제
  • 분류 전체보기
    • Data Science
      • AI
      • Data Mining
      • ML(Machine Learning)
    • Computer Science
      • 자료구조
      • 알고리즘
      • 시스템 프로그래밍
      • 운영체제
      • 컴퓨터 구조
      • 컴퓨터 네트워크
      • 데이터 베이스
      • 파이썬
      • 자바
      • 아두이노
    • Math
      • 통계학
      • 확률론
      • 선형대수학
      • 수리통계학
      • 회귀분석
    • TOFEL
    • Git
    • Plan
    • Book
    • Working out
      • 영양과 생활
      • 운동 정보
      • 운동 기록

인기 글

최근 글

최근 댓글

hELLO · Designed By 정상우.
tgool
Computer Science/컴퓨터 구조

[CSAPP] 3.2 Program Encoding(프로그램의 인코딩)

Computer Science/컴퓨터 구조

[CSAPP] 3.2 Program Encoding(프로그램의 인코딩)

2023. 1. 21. 01:09

3.2 Program Encoding(프로그램의 인코딩)

  • optimization(최적화)

$gcc -Og -o p p1.c p2.c

💡 -Og ~ -O3 : 최적화 수준을 지정, 높을 수록 더 높은 최적화

 

최적화 수준을 올리면 프로그램은 더 빨리 동작한다.

but, 컴파일 시간이 증가하고 디버깅 도구를 실행하기 어려워진다. 또한, 코드가 많이 변경되어 본래의 코드와 기계어 코드 간의 관계를 파악하기에 어려워진다.

  • gcc 동작 과정
  1. 전처리 과정 : 전처리기에 의해 .i 파일 생성

⇒ #include로 명시된 헤더 파일 삽입 → #define으로 선언된 매크로 치환

  1. 컴파일 과정 : C 컴파일러를 통해.s 파일 생성
  2. 어셈블 과정 : 어셈블러에 의해서 .o (기계어 코드) 파일 생성
  3. 링킹 과정 : 링커를 통해서 실행 파일 p (기계어 코드)생성

3.2.1 Machine-Level Code

  • Machine-Level 프로그램
  1. 형식과 동작은 명령어 집합구조(ISA)에 의해 정의된다. ISA는 프로세서의 상태, 명령어의 형식, 프로세서 상태에 대한 명령어들의 영향들을 정의한다. 이때, ISA는 명령어들이 순차적 실행을 하는 것처럼 동작을 설명하지만 실제로는 프로세서가 여러 명령어들을 동시에 실행한다. 이에 따라, ISA에 의한 순차적 동작과 일치하는 전체 동작이 나타나도록 하는 안전장치가 존재한다.
  2. 가상주소를 사용하여 메모리가 매우 큰 배열인 것처럼 보이게하는 모델을 제공한다. 실제 메모리는 여러 개의 메모리 하드웨어와 운영체제 소프트웨어로 구현되어 있다.

💡 어셈블리 코드를 이해하는 것이 중요하다!!!

 

3.2.2 Code Example

long mult2(long, long);
void multstore(long x, long y, long *dest) {
		long t = mult2(x, y);
		*dest = t;
}

이를 $gcc -Og -S mstore.c 로 컴파일하면 msotre.s 어셈블리 파일이 생성된다.

mstore.s는 아래의 내용을 포함해서 다양한 선언을 포함한다.

multstore:
	pushq  %rbx
movq  %rdx, %rbx
call  mult2
movq  %rax, (%rbx)
popq  %rbx
ret

이를 $ gcc -Og -c mstore.c 로 컴파일하면 다음과 같은 목적코드 파일 mstore.c를 생성한다.

53 48 89 d3 e8 00 00 00 00 48 89 03 5b c3

중요한 건, 프로그램은 단순히 명령어들로 인코딩된 바이트 시퀀스일 뿐이라는 점이다. 즉, 명령어들이 생성된 소스 코드에 대해 최소한의 정보만을 갖는다.

기계어 코드를 파악하려면 disassemblers라는 프로그램이 주요하다.

$objdump -d mstore.o

리눅스에서 실행한 결과는 다음과 같다

0000000000000000 <multstore>:
Offset       Bytes           Equivalent assembly language
     0:      53              push %rbx
     1:      48 89 d3        mov %rdx,%rbx
     4:      e8 00 00 00 00  callq 9 <multstore+0x9>
     9:      48 89 03        mov %rax,(%rbx)
     c:      5b              pop %rbx
     d:      c3              retq

각 바이트 그룹은 하나의 명령어로, 오른쪽에 나타난 어셈블리어와 동일하다.

이에 대해 disassembler의 몇가지 특징을 알아볼 수 있다.

  1. x86-64 명령어들은 1~15바이트 길이를 갖는다. 사용되는 명령어와 오퍼랜드(연산에 필요한 데이터)가 적을 수록 짧은 길이를 갖도록 인코딩한다.
  2. 명령어는 주어진 시작 위치로부터 특정 바이트로만 해석될 수 있도록 설계된다. 예를 들면, push %rbx만이 바이트 값 53으로 시작될 수 있다.
  3. 온전히 기계어 코드의 바이트 시퀀스에만 기반하여 어셈블리 코드를 생성한다.
  4. gcc가 생성한 어셈블리 코드와는 다르게 많은 명령어에서 접미어 ‘q’를 생략했다. 이때, ‘q’는 크기를 나타내며 대부분 생략할 수 있다. 반대로 call과 ret에는 ‘q’를 붙인다. 이들 또한 생략이 가능하다.
#include <stdio.h>
void multstore(long, long, long *);
int main() {
	long d;
	multstore(2, 3, &d);
	printf("2 * 3 --> %ld\\n", d);
	return 0;
}

long mult2(long a, long b) {
	long s = a * b;
	return s;
}

실행 가능한 파일 prog를 다음과 같이 생성할 수 있다.

$gcc -Og -o prog main.c mstore.c

파일을 다음과 같이 disassembble할 수 있다

$objdump -d prog

결과는 다음과 같다

0000000000400540 <multstore>:
400540: 53                push %rbx
400541: 48 89 d3          mov %rdx,%rbx
400544: e8 42 00 00 00    callq 40058b <mult2>
400549: 48 89 03          mov %rax,(%rbx)
40054c: 5b                pop %rbx
40054d: c3                retq
40054e: 90                nop
40054f: 90                nop

이 코드와 mstore.c를 disassemble해서 생성한 코드와의 주요한 차이점을 몇가지 살펴볼 수 있다.

  1. 좌측의 주소가 다르다. 링커가 이 코드의 위치를 다른 주소영역으로 이동시켰다.
  2. callq 명령어가 함수 mult2를 호출할 때 사용해야하는 주소를 받았다. 링커는 함수 호출과 함수를 위한 실행코드를 일치시킨다.
  3. 마지막 두 줄이 추가되었다. 리턴 이후에 발생하였으니 프로그램에는 영향이 없다. 이는 코드 길이를 16바이트로 늘려, 다음 블록을 메모리 면에서 더 잘 배치하기 위해서이다.

3.2.3 Notes on Formatting

gcc가 생성하는 어셈블리 코드는 직관적이지 못하기 때문에 ‘.’으로 시작하는 라인(디렉티브)들의 대부분을 생략하고, 명령어를 설명하는 주석을 추가했다. 이것이 정형화된 형식이다. 예시는 다음과 같다.

*void multstore(long x, long y, long *dest)
x in %rdi, y in %rsi, dest in %rdx*
1  **multstore:**
2  **pushq  %rbx**   *Save %rbx*
3  **movq  %rdx, %rbx**   *Copy dest to %rbx*
4  **call  mult2**   *Call mult2(x, y)*
5  **movq  %rax, (%rbx)**   *Store result at *dest*
6  **popq  %rbx**   *Restore %rbx*
7  **ret**   *Return*

 

'Computer Science > 컴퓨터 구조' 카테고리의 다른 글

[CSAPP] 3.4 Accessing Information(정보 접근하기)  (1) 2023.01.21
[CSAPP] 3.3 Data Formats(데이터의 형식)  (1) 2023.01.21
[CSAPP] 3.1 A Historical Perspective(역사적 관점)  (0) 2023.01.21
[CSAPP] 2.4 Floating Point(부동소수점)  (0) 2023.01.19
[CSAPP] 2.3 Integer Arithmetic(정수 연산)  (0) 2023.01.19
  • 3.2 Program Encoding(프로그램의 인코딩)
  • 3.2.1 Machine-Level Code
  • 3.2.2 Code Example
  • 3.2.3 Notes on Formatting
  •  
'Computer Science/컴퓨터 구조' 카테고리의 다른 글
  • [CSAPP] 3.4 Accessing Information(정보 접근하기)
  • [CSAPP] 3.3 Data Formats(데이터의 형식)
  • [CSAPP] 3.1 A Historical Perspective(역사적 관점)
  • [CSAPP] 2.4 Floating Point(부동소수점)
tgool
tgool

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.