C语言结合汇编开发系统内核

汇编与C的交合调用

在这个例子中,源代码包含两个文件:foo.asm, 和 bar.c.程序入口在foo.asm 中,程序先从foo.asm中的_start处开始执行,在_start中,调用一个函数叫bar_func, 而bar_func 函数由bar.c模块来实现,而bar.c实现的bar_func函数中,又调用一个来自foo.asm实现的函数,叫foo_print, 两个模块的相互交互如下:

Paste_Image.png

接下来我们看看两个模块的实现,先看看foo.asm:

extern bar_func;

[section .data]
arg1  dd 3
arg2  dd 4

[section .text]
global _start
global foo_print

_start:
mov   eax, dword[arg1]
push  eax
mov   eax, dword [arg2]
push  eax
call  bar_func
add   esp, 8

mov   ebx,0
mov   eax, 1
int   0x80

foo_print:
mov   edx, [esp + 8]
mov   ecx, [esp + 4]
mov   ebx, 1
mov   eax, 4
int   0x80
ret

由于需要调用另一个模块的函数,所以开始先要使用extern 声明,要不然编译时,编译器会报错。由于_start要导出作为整个可执行程序的入口,因此要用global关键字声明,同时,该模块中的foo_print要导出给其他接口使用,所以需要用global声明。

在_start中,在调用bar_func函数前,需要传入参数,C语言的参数传递是通过堆栈实现的,函数如果有多个参数的话,那么最右边的参数先压入堆栈,由于代码中,我们先压入arg1, 然后再压入arg2,所以就相当于以如下方式调用来自C语言模块的接口:

bar_func(arg2, arg1);

根据C语言的函数调用规则,堆栈的回收由调用者负责,所以在_start中,bar_func调用结束后,需要调整堆栈指针esp, add esp ,8 将堆栈指针往下移动8字节,这就将开头压入堆栈的两个4字节参数,arg1,arg2从堆栈上删除了。

在理解foo_print前,我们需要看看bar.c的实现:


void foo_print(char* a, int len);

int  bar_func(int a, int b) {
    if (a > b) {
       foo_print("the 1st one\n", 13);
    } else {
       foo_print("the 2nd one\n", 13);
    }

    return 0;
}

根据bar.c中,对foo_print的调用方式来看,最右边的参数是13,表示的是第一个输入参数,也就是字符串的长度。这么看来在foo.asm的foo_print中,[esp+8] 对应于第二个参数,也就是上面的13,[esp+4]对应第一个参数,也就是输入的字符串。

mov ebx, 1
mov eax, 4
int 0x80

上面三句实现Linux的一个系统调用,该调用的作用是将ecx寄存器中指向的内存地址中的字符信息打印到屏幕上。

上面两个文件的编译,需要在Linux系统上进行,我用的是ubuntu,先编译foo.asm:
nasm -f elf32 -o foo.o foo.asm

然后编译bar.c
gcc -m32 -c -o bar.o bar.c

接下来就可以将两个模块连接在一起了:
ld -m elf_i386 -o foobar foo.o bar.o

于是在目录下便会生成一个可执行文件 foobar, 通过下面指令可将生成的可执行文件加载执行:

./foobar

运行后结果如下:


这里写图片描述

上面代码可通过地址下载:
http://pan.baidu.com/s/1kVlmQGn

虽然,我们基本实现了将汇编和C语言模块结合的目的,但这种做法有一个问题,就是最终编译成的可执行文件是elf格式,但我们要开发的是系统内核,如果将内核编译成elf格式,那么就不能直接将内核加载到内存直接执行。所以需要想新的办法。

我的做法是,将C语言编译或的.o模块反汇编,将反汇编的代码贴到foo.asm里面,从而形成单个asm文件,最后编译这个整合在一起的汇编文件,直接生成二进制可执行代码。

用反汇编结合C语言和汇编语言

新的做法是这样的:

  1. 先写好汇编代码和对应的C代码。
  2. 用以下命令编译C代码模块,以便后面反汇编:gcc -m32 -fno-asynchronous-unwind-tables -s -c -o bar.o bar.c
  3. 下载一个好用的反汇编工具objconv,通过如下命令下载:git clone https://github.com/vertis/objconv.git
  4. 下载后进入objconv目录,编译该工具,运行下面的命令:g++ -o objconv -O2 src/*cpp , -O2中的圆圈是大写字母O.
  5. 用objconv 反汇编C语言生成的目标文件bar.o,命令如下:objconv -fnasm bar.o -o bar.asm,于是目录下便有一个反汇编文件bar.asm
  6. 打开foo.asm, 将里面的_start, 修改成main, 这一步在后面我们编译系统内核时可以不用,现在这么做,主要是想编译成linux可执行文件
  7. 在foo.asm末尾,通过语句:%include "bar.asm" 将第五步反汇编的C模块代码引入foo.asm。
  8. 运行命令编译foo.asm: nasm -f elf32 foo.asm, 执行这一步后,目录上会出现foo.o二进制文件
  9. 执行命令:gcc -m32 foo.o -o foo. 这一步将foo.o与系统模块连接成可执行文件,编译系统内核时,这一步就不需要。
  10. 运行结果:./foo, 就可以看到运行结果了。

在后面的章节中,我们将主要依赖C语言进行内核的开发,只有当C语言力不能逮,特别是需要操作硬件时,才会使用汇编语言,下一节,我们看看如何使用C语言绘制操作系统GUI.

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

推荐阅读更多精彩内容