반응형


!실행파일 구조


 - 리눅스 :ELF


 - 윈도우즈: PE


 - 유닉스: COFF


#>xxd hello.o


오브젝트 파일을 hxd로 열어본거처럼 보여줍니다




ELF는 파일 시그니처가 7f45 4c46임을 알 수 있습니다.



! 프로그램 & 프로세스


1. 프로그램


 - 실행중이지 않은 상태


2. 프로세스 


 - 실행중인 상태


 - 운영체제가 관리하는 작업의 단위


 - 파일이 메모리에 존재


 - 눈에 보이는 프로세스 : 포그라운드 프로세스


 - 눈에 보이지 않은 프로세스: 백그라운드 프로세스


 - 우리가 실행을 하면 커널에 의해서 메모리로 올라갑니다.


 - 커널이 이 파일이 뭔지 알고 올려야 하므로 이런 실행파일 구조를 만들었습니다.




#>objdump 



-x  --all-headers        Display the contents of all headers


#>objdump -x hello.o



ELF 정보


hello.o:     file format elf32-i386

hello.o

architecture: i386, flags 0x00000011:

HAS_RELOC, HAS_SYMS

start address 0x00000000


sections가 실제 실행할 프로그램을 보여줍니다

실제 실행할 코드가 포함되어있습니다


Sections:

Idx Name          Size      VMA       LMA       File off  Algn

  0 .text         00000022  00000000  00000000  00000040  2**4

                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE

  1 .data         00000000  00000000  00000000  00000064  2**2

                  CONTENTS, ALLOC, LOAD, DATA

  2 .bss          00000000  00000000  00000000  00000064  2**2

                  ALLOC

  3 .note         00000014  00000000  00000000  00000064  2**0

                  CONTENTS, READONLY

  4 .rodata       0000000f  00000000  00000000  00000078  2**0

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

  5 .comment      0000003d  00000000  00000000  00000087  2**0

                  CONTENTS, READONLY


VMA는 virtual machine address로 linking 과정에서 계산됩니다.

ELF 헤더구간

0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
0000010: 0100 0300 0100 0000 0000 0000 0000 0000  ................
0000020: 1401 0000 0000 0000 3400 0000 0000 2800  ........4.....(.
0000030: 0b00 0800 0000 0000 0000 0000 0000 0000  ................

text구간

0000040: 5589 e568 1027 0000 6800 0000 00e8 fcff  U..h.'..h.......
0000050: ffff 83c4 0831 c0eb 078d b426 0000 0000  .....1.....&....
0000060: c9c3

readonly로 바뀝니다



1. text 섹션(세그먼트)
 
 - 실행코드가 존재하는 영역

 - 읽기전용

 - 실행가능한 메모리영역

2. DATA 섹션(세그먼트)

 - 읽기/쓰기 가능한 메모리 영역

 - 초기화된 데이터 영역


3. BSS 섹션(세그먼트)

 - 읽기/쓰기 가능한 메모리 영역

 - 초기화 되지 않은 데이터 영역

전역변수 크기가 여기에 할당됩니다

메모리에 올라갈때 크기가 커집니다

4. 스택

 - 파일 상에서는 나타나지 않는다.

#>objdump -d hello.o
-d  --disassemble        Display assembler contents of executable sections




software engineering(소프트웨어 공학)

 - 소프트웨어를 만드는 전체 과정

 - 기획 -> 설계 -> 구현 -> 배포 -> 유지보수


어셈블 프로그래밍

 - 각 섹션(세그먼트)들을 직접 정의

 ;;; 어셈블 주석

#>vi hello.asm


이렇게 어셈블리 코드를 짭니다

일단 c 라이브러리에서 printf를 들고오는 방식으로 짜겠습니다


nasm을 이용해서 파일구조는 elf로 오브젝트 파일로 만듭니다



objdump를 이용해서 보면 잘 만들어진걸 볼 수 있습니다



원래는 ld를 이용해서 linking을 해야하지만 C언어 라이브러리를 모으는게 복잡하므로 GCC보고 대신 하달라고 하겠습니다



출력이 잘 됌을 볼 수 있습니다



이제 C에서 printf 라이브러리를 들고 오지 않고 짜보도록 하겠습니다.

#>vi hello2.asm


이렇게 코드를 짭니다



이번에는 ld를 써서 linking을 하였습니다.


출력이 잘 됌을 볼 수 있습니다.



둘의 크기 차이를 볼 수 있습니다



c라이브러리가 없이 linking한 hello2가 훨씬 크기가 작음을 볼 수 있습니다.



리눅스 메모리


4기가


하위 3기가


- 프로세스가 사용합니다.


0x0번부터 0x08까지 쓰지않습니다 (unused)



0x08048000


0x96바이트 + padding(r-x) (4kb)


0x08049000

(rw-) (4kb)


상위 1기가: 마지막주소 0xffffffff


- 커널이 사용합니다


어셈블리 숫자형 표현


10진수 100d

8진수 100o

16진수 100h

2진수 100b


  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기