从头写一个操作系统 11 (create an OS from scratch 11)

你应该先google:C,ojbect code, linker, disassemble
目标:用C语言做底层汇编语言做的那些事

Compile

我们得研究研究C编译器如何编译代码,并且比较它与汇编器生成的机器码两者是否有所差别。

写一个只有一个简单函数的程序function.c。打开function.c看一眼。

int my_function() {
    return 0xbaba;
}

编译与系统无关的代码时需要加-ffreestanding:

i386-elf-gcc -ffreestanding -c function.c -o function.o

研究研究编译器生成的机器码:

i386-elf-objdump -d function.o

function.o:     file format elf32-i386

Disassembly of section .text:

00000000 <my_function>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   b8 ba ba 00 00          mov    $0xbaba,%eax
   8:   5d                      pop    %ebp
   9:   c3                      ret    

是不是有点似曾相识?

Link

最后,如果要生成二进制文件,我们需要使用 linker,中文也叫链接器。在这个时候,我们一定要搞明白高级语言是如何调用函数的标签的。其实我们不知道,程序在内存中的偏移地址(offset)是多少。我们将offset定为0x0并且使用binary(二进制)格式生成二进制码,而不包含任何标签或链接器需要的数据。

i386-elf-ld -o function.bin -Ttext 0x0 --oformat binary function.o

注意:会有一个 warning(i386-elf-ld: warning: cannot find entry symbol _start; defaulting to 0000000000000000),淡定的忽略掉它!

使用xxd命令查看两个文件,我们发现.bin文件是机器码,而.o文件包含很多调试信息。

geyu@geyu-All-Series:~/workdir/os-dev/os-tutorial/12-kernel-c$ xxd function.bin 
00000000: 5589 e5b8 baba 0000 5dc3 0000 1400 0000  U.......].......
00000010: 0000 0000 017a 5200 017c 0801 1b0c 0404  .....zR..|......
00000020: 8801 0000 1c00 0000 1c00 0000 d4ff ffff  ................
00000030: 0a00 0000 0041 0e08 8502 420d 0546 c50c  .....A....B..F..
00000040: 0404 0000            
geyu@geyu-All-Series:~/workdir/os-dev/os-tutorial/12-kernel-c$ xxd function.o
00000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
00000010: 0100 0300 0100 0000 0000 0000 0000 0000  ................
00000020: cc00 0000 0000 0000 3400 0000 0000 2800  ........4.....(.
00000030: 0a00 0700 5589 e5b8 baba 0000 5dc3 0047  ....U.......]..G
00000040: 4343 3a20 2847 4e55 2920 342e 392e 3100  CC: (GNU) 4.9.1.
00000050: 1400 0000 0000 0000 017a 5200 017c 0801  .........zR..|..
00000060: 1b0c 0404 8801 0000 1c00 0000 1c00 0000  ................
00000070: 0000 0000 0a00 0000 0041 0e08 8502 420d  .........A....B.
00000080: 0546 c50c 0404 0000 002e 7379 6d74 6162  .F........symtab
00000090: 002e 7374 7274 6162 002e 7368 7374 7274  ..strtab..shstrt
000000a0: 6162 002e 7465 7874 002e 6461 7461 002e  ab..text..data..
000000b0: 6273 7300 2e63 6f6d 6d65 6e74 002e 7265  bss..comment..re
000000c0: 6c2e 6568 5f66 7261 6d65 0000 0000 0000  l.eh_frame......
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000f0: 0000 0000 1b00 0000 0100 0000 0600 0000  ................
00000100: 0000 0000 3400 0000 0a00 0000 0000 0000  ....4...........
00000110: 0000 0000 0100 0000 0000 0000 2100 0000  ............!...
00000120: 0100 0000 0300 0000 0000 0000 3e00 0000  ............>...
00000130: 0000 0000 0000 0000 0000 0000 0100 0000  ................
00000140: 0000 0000 2700 0000 0800 0000 0300 0000  ....'...........
00000150: 0000 0000 3e00 0000 0000 0000 0000 0000  ....>...........
00000160: 0000 0000 0100 0000 0000 0000 2c00 0000  ............,...
00000170: 0100 0000 3000 0000 0000 0000 3e00 0000  ....0.......>...
00000180: 1200 0000 0000 0000 0000 0000 0100 0000  ................
00000190: 0100 0000 3900 0000 0100 0000 0200 0000  ....9...........
000001a0: 0000 0000 5000 0000 3800 0000 0000 0000  ....P...8.......
000001b0: 0000 0000 0400 0000 0000 0000 3500 0000  ............5...
000001c0: 0900 0000 0000 0000 0000 0000 f402 0000  ................
000001d0: 0800 0000 0800 0000 0500 0000 0400 0000  ................
000001e0: 0800 0000 1100 0000 0300 0000 0000 0000  ................
000001f0: 0000 0000 8800 0000 4300 0000 0000 0000  ........C.......
00000200: 0000 0000 0100 0000 0000 0000 0100 0000  ................
00000210: 0200 0000 0000 0000 0000 0000 5c02 0000  ............\...
00000220: 8000 0000 0900 0000 0700 0000 0400 0000  ................
00000230: 1000 0000 0900 0000 0300 0000 0000 0000  ................
00000240: 0000 0000 dc02 0000 1800 0000 0000 0000  ................
00000250: 0000 0000 0100 0000 0000 0000 0000 0000  ................
00000260: 0000 0000 0000 0000 0000 0000 0100 0000  ................
00000270: 0000 0000 0000 0000 0400 f1ff 0000 0000  ................
00000280: 0000 0000 0000 0000 0300 0100 0000 0000  ................
00000290: 0000 0000 0000 0000 0300 0200 0000 0000  ................
000002a0: 0000 0000 0000 0000 0300 0300 0000 0000  ................
000002b0: 0000 0000 0000 0000 0300 0500 0000 0000  ................
000002c0: 0000 0000 0000 0000 0300 0400 0c00 0000  ................
000002d0: 0000 0000 0a00 0000 1200 0100 0066 756e  .............fun
000002e0: 6374 696f 6e2e 6300 6d79 5f66 756e 6374  ction.c.my_funct
000002f0: 696f 6e00 2000 0000 0202 0000            ion. .......

Decompile

好奇不好奇机器码对应着怎样的汇编代码?
ndisasm -b 32 function.bin

More

强烈建议多谢几个小程序,就像以下这样:

  • Local variables localvars.c
  • Function calls functioncalls.c
  • Pointers pointers.c

仔细看一看os-dev.pdf相关的章节,编译并反汇编上面的代码,对比研究它们的机器码。最后回答这个问题,pointers.c编译后为什么与我们预期不一致?"Hello"的ASCII码0x48656c6c6f在哪里?

THE ORIGIN ARTICALE IN GITHUB:[^1]

Concepts you may want to Google beforehand: C, object code, linker, disassemble

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 xxd. 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 localvars.c
  • Function calls functioncalls.c
  • Pointers pointers.c

Then compile and disassemble them, and examine the resulting machine code. Follow the os-guide.pdf for explanations. Try to answer this question: why does the disassemblement of pointers.c not resemble what you would expect? Where is the ASCII 0x48656c6c6f for "Hello"?

参考资料:
[1]:https://github.com/cfenollosa/os-tutorial/blob/master/12-kernel-c

版权注明:本文所有涉及到:https://github.com/cfenollosa/os-tutorial/ git仓库的内容,全部对应以下开源协议声明:
BSD 3-Clause License
Copyright (c) 2018,
Carlos Fenollosa

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容