mirror of
https://github.com/cfenollosa/os-tutorial.git
synced 2024-10-27 20:34:19 +00:00
lesson 12
This commit is contained in:
parent
32355dbc28
commit
dec0890a90
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/*/*.bin
|
/*/*.bin
|
||||||
|
/*/*.o
|
||||||
/*/*.swp
|
/*/*.swp
|
||||||
|
62
12-kernel-c/README.md
Normal file
62
12-kernel-c/README.md
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
*Concepts you may want to Google beforehand:*
|
||||||
|
|
||||||
|
**Goal: Learn to write the same low-level code as we did with assembler, but in C**
|
||||||
|
|
||||||
|
|
||||||
|
Compile
|
||||||
|
-------
|
||||||
|
|
||||||
|
Let's see how the C compiler compiles our code and compare it to the machine code
|
||||||
|
generated with the assembler.
|
||||||
|
|
||||||
|
We will start writing a simple program which contains a function, `function.c`.
|
||||||
|
Open the file and examine it.
|
||||||
|
|
||||||
|
To compile system-independent code, we need the flag `-ffreestanding`, so compile
|
||||||
|
`function.c` in this fashion:
|
||||||
|
|
||||||
|
`i386-elf-gcc -ffreestanding -c function.c -o function.o`
|
||||||
|
|
||||||
|
Let's examine the machine code generated by the compiler:
|
||||||
|
|
||||||
|
`i386-elf-objdump -d function.o`
|
||||||
|
|
||||||
|
Now that is something we recognize, isn't it?
|
||||||
|
|
||||||
|
|
||||||
|
Link
|
||||||
|
----
|
||||||
|
|
||||||
|
Finally, to produce a binary file, we will use the linker. An important part of this
|
||||||
|
step is to learn how high level languages call function labels. Which is the offset
|
||||||
|
where our function will be placed in memory? We don't actually know. For this
|
||||||
|
example, we'll place the offset at `0x0` and use the `binary` format which
|
||||||
|
generates machine code without any labels and/or metadata
|
||||||
|
|
||||||
|
`i386-elf-ld -o function.bin -Ttext 0x0 --oformat binary function.o`
|
||||||
|
|
||||||
|
*Note: a warning may appear when linking, disregard it*
|
||||||
|
|
||||||
|
Now examine both "binary" files, `function.o` and `function.bin` using `xdd`. You
|
||||||
|
will see that the `.bin` file is machine code, while the `.o` file has a lot
|
||||||
|
of debugging information, labels, etc.
|
||||||
|
|
||||||
|
|
||||||
|
Decompile
|
||||||
|
---------
|
||||||
|
|
||||||
|
As a curiosity, we will examine the machine code.
|
||||||
|
|
||||||
|
`ndisasm -b 32 function.bin`
|
||||||
|
|
||||||
|
|
||||||
|
More
|
||||||
|
----
|
||||||
|
|
||||||
|
I encourage you to write more small programs, which feature:
|
||||||
|
|
||||||
|
- Local variables
|
||||||
|
- Function calls
|
||||||
|
- Pointers
|
||||||
|
|
||||||
|
Then compile and disassemble them, and examine the resulting machine code.
|
3
12-kernel-c/function.c
Normal file
3
12-kernel-c/function.c
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
int my_function() {
|
||||||
|
return 0xbaba;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user