TIL 10월 28일 2023년

ORCASUIT·2023년 10월 28일
0
post-thumbnail

#CSAPP #til

개요

오늘은 리눅스 환경에서 C 프로그램의 인코딩 과정을 작성해 봅니다.

  1. C코드에 대한 컴파일러의 어셈블리 파일 인코딩
  2. 목적 파일에 대한 역어셈블리
  3. 링킹 후 파일 용량의 차이
  4. 실행 프로그램에 대한 역어셈블리

1. C코드에 대한 컴파일러의 어셈블리 파일 인코딩

long mult2(long, long);
void multstore(long x, long y, long *dest){
    long t = mult2(x, y);
    *dest = t;
}```
>linux> gcc -Og -S mstore.c 

GCC, 컴파일러를 실행하여 위 C파일을 어셈블리 파일을 만듭니다. 

```asm
multstore:
.LFB0:
	.cfi_startproc
	endbr64
	pushq	%rbx
	.cfi_def_cfa_offset 16
	.cfi_offset 3, -16
	movq	%rdx, %rbx
	call	mult2@PLT
	movq	%rax, (%rbx)
	popq	%rbx
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc

만들어진 어셈블리 파일을 까보면 왼쪽은 명령어, 오른쪽은 오퍼랜드들 입니다.

2. 목적 파일에 대한 역어셈블리

다음은 GCC에게 C코드를 컴파일, 어셈블하도록 명령해 목적 파일을 만들어 봅시다.

linux> gcc -Og -c mstore.c

이렇게 생성된 목적 파일 mstore.o에는 나열된 어셈블리 인스트럭션에 대응되는 16진수 데이터가 내장되어 있습니다.

여기서 알 수 있는 건 컴퓨터에 의해 실행된 프로그램은 단순히 일련의 인스트럭션(명령)을 인코딩한 바이트 라는 점입니다.

이제 이 목적 파일을 역어셈블 해보겠습니다.

linux> objdump -d mstore.o

Disassembly of section .text:

0000000000000000 <multstore>:
   0:   f3 0f 1e fa             endbr64 
   4:   53                      push   %rbx
   5:   48 89 d3                mov    %rdx,%rbx
   8:   e8 00 00 00 00          callq  d <multstore+0xd>
   d:   48 89 03                mov    %rax,(%rbx)
  10:   5b                      pop    %rbx
  11:   c3                      retq   

이전에 보았던 어셈블러 파일과는 다릅니다.

기계어 코드의 몇몇 특징과 역어셈블러 된 표현에 대한 것

  • 역어셈블러는 기계어 코드 파일의 바이트 순서에만 전적으로 의존합니다.
  • 역어셈블러는 GCC가 생성한 어셈블리 코드와는 다른 명명법을 씁니다.

3. 링킹 후 파일 용량의 차이

이제 실제 실행 가능한 코드를 생성하기 위해 링커를 목적코드에 실행합니다. 여기서 한 개의 파일은 main 함수를 포함해야 합니다.

#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;
}

linux> gcc -Og -o prog main.c mstore.c

링커를 통해 실행가능 프로그램인 prog 생성.

파일 크기가 늘어나는데 그 이유는 아래와 같습니다.

  • 두 개의 프로시저
  • 운영체제와 상호작용하기 위한 코드 추가
  • 프로그램을 시작하고 종료하기 위한 코드 추가

4. 실행 프로그램에 대한 역어셈블리

linux> objdump -d prog

이 프로그램을 다시 역어셈블 합니다.

00000000000011d5 <multstore>:
    11d5:       f3 0f 1e fa             endbr64 
    11d9:       53                      push   %rbx
    11da:       48 89 d3                mov    %rdx,%rbx
    11dd:       e8 e7 ff ff ff          callq  11c9 <mult2>
    11e2:       48 89 03                mov    %rax,(%rbx)
    11e5:       5b                      pop    %rbx
    11e6:       c3                      retq   
    11e7:       66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)
    11ee:       00 00 

이 어셈블러는 mstore.o 를 역어셈블해서 생성한 것과 거의 동일하지만 두가지 차이점이 있습니다.

  • 링커가 이 코드의 위치를 다른 주소 영역으로 이동 시켰다.
  • 링커가 callq 인스트럭션이 함수 mult2 를 호출 할때 사용해야하는 주소를 채웠다.

링커의 임무는 함수들을 위한 실행 코드의 위치들과 함수 호출을 일치 시키는 것 입니다.

0개의 댓글