-
[OS] 12. Kernel COS/OS from Scratch 2021. 6. 26. 15:41
서론
이번 강의에서는 C언어로 지금까지 작성했던 Low-Level 코드들을 만들겠습니다. 해당 Github 강의는 다음과 같습니다.
https://github.com/cfenollosa/os-tutorial/tree/master/12-kernel-c
cfenollosa/os-tutorial
How to create an OS from scratch. Contribute to cfenollosa/os-tutorial development by creating an account on GitHub.
github.com
이론
Linking
이 블로그에서 Linking에 대해 알기 쉽게 설명해 놓았습니다. A.cpp라는 파일을 컴파일하면 A.o라는 Object Code가 생성되는데, 이 Object Code는 기계어로 작성된 로직과 디버깅, Symbol 정보 등의 부가적인 정보들이 있는 파일입니다. 생성된 Object Code들은 Linker에 의해 Linking 되어 실행파일이 만들어집니다. 이 과정에서 여러 Object Code들을 하나로 합치고, 여기에 라이브러리 파일들을 합쳐 실행 파일을 만들게 됩니다.
코드
function.c
본 강의에서는 다음 C 코드를 이용해 실습을 진행하겠습니다.
int my_function() { return 0xbaba; }
Object Code
아래 명령어는 Object 파일을 만드는 코드입니다.
i386-elf-gcc -ffreestanding -c function.c -o function.o
Object 파일을 보기 위해서는 다음 명령어를 사용합니다.
i386-elf-objdump -d function.o
생성된 Assembly 코드는 Nasm Assembly와 문법이 달라 추후에 분석하도록 하겠습니다.
Link
앞서 언급했듯이 실행 파일을 만들기 위해서는 Linker가 여러 Object 파일을 하나의 Binary 파일로 만듭니다. Linking 과정에서 call <Label> 명령어들은 call 0x12345 와 같이 output 파일에서 Label이 저장되는 주소 offset으로 변환되게 됩니다. Link 하는 명령어는 다음과 같습니다.
i386-elf-ld -o function.bin -Ttext 0x0 --oformat binary function.o
위 명령어에서 -Ttext 0x0은 Linker에게 모든 데이터들이 저장되는 주소를 0x00에 대한 상대주소가 되게 합니다. 다시 말해, -Ttext 0x0은 이전 강의에서 본 org 명령어와 같은 역할을 해줍니다.
생성된 Binary 파일을 Disassemble 하는 명령어는 다음과 같습니다.
ndisasm -b 32 function.bin
이를 수행하면 다음 결과를 얻습니다.
00000000 55 push ebp 00000001 89E5 mov ebp,esp 00000003 B8BABA0000 mov eax,0xbaba 00000008 5D pop ebp 00000009 C3 ret 이하 중략...
위 코드를 조금 분석해보겠습니다. C언어는 지역 변수들을 Stack에 저장하는데 이를 위해 ebp 레지스터를 현재 Stack의 가장 위인 esp 레지스터의 값으로 지정해 비어있는 Stack을 생성합니다. 이 과정을 Stack Frame을 생성하는 과정이라 부르며, 이전 프로세스에서 사용 중인 ebp 레지스터의 값을 저장하기 위해 push ebp 명령어를 사용합니다.
function.c 에서는 return 0xbaba; 코드가 있었는데 이는 mov eax, 0xbaba로 번역됩니다. 즉 함수에서 리턴되는 값은 eax 레지스터에 저장되게 됩니다. 마지막으로 ret 명령어가 실행되기 전에 ebp 레지스터를 함수가 호출되기 전 상태로 돌려놓기 위해 pop ebp 명령어가 생성됩니다.
'OS > OS from Scratch' 카테고리의 다른 글
[OS] 14. Checkpoint (0) 2021.06.28 [OS] 13. Kernel Barebones (0) 2021.06.27 [OS] 11. Kernel Cross Compiler (0) 2021.06.23 [OS] 10. 32 bit Enter (0) 2021.06.23 [OS] 09. GDT (0) 2021.06.22