a.我们先来体验一下在Linux下用汇编编程的感觉,见代码

[section .data]	; 数据在此

strHello	db	"Hello, world!", 0Ah
STRLEN equ $ - strHello [section .text] ; 代码在此 global _start ; 我们必须导出 _start 这个入口,以便让链接器识别 _start:
mov edx, STRLEN
mov ecx, strHello
mov ebx, 1
mov eax, 4 ; sys_write
int 0x80 ; 系统调用
mov ebx, 0
mov eax, 1 ; sys_exit
int 0x80 ; 系统调用

编译方法:

nasm -f elf hello.asm -o hello.o

ld -m elf_i386 -s -o hello hello.o

./hello

运行结果是打印出Hello, world!

入口点默认的是_start,我们不但要定义它,而且要通过global这个关键字将它导出,这样链接程序才能找到它。两个系统调用不用深究,因为在我们自己的OS中根本用不到Linux的系统调用。

b.汇编和C同步使用

; 编译链接方法
; (ld 的‘-s’选项意为“strip all”)
;
; $ nasm -f elf foo.asm -o foo.o
; $ gcc -c bar.c -o bar.o
; $ ld -s hello.o bar.o -o foobar
; $ ./foobar
; the 2nd one
; $ extern choose ; int choose(int a, int b); [section .data] ; 数据在此 num1st dd 3
num2nd dd 4 [section .text] ; 代码在此 global _start ; 我们必须导出 _start 这个入口,以便让链接器识别
global myprint ; 导出这个函数为了让 bar.c 使用 _start:
push dword [num2nd] ; `.
push dword [num1st] ; |
call choose ; | choose(num1st, num2nd);
add esp, 8 ; / mov ebx, 0
mov eax, 1 ; sys_exit
int 0x80 ; 系统调用 ; void myprint(char* msg, int len)
myprint:
mov edx, [esp + 8] ; len
mov ecx, [esp + 4] ; msg
mov ebx, 1
mov eax, 4 ; sys_write
int 0x80 ; 系统调用
ret

1.由于在bar.c中用到函数myprint(),所以要用关键字global将其导出。

2.由于用到本文件外定义的函数choose(),所以要用关键字extern声明。

3.不管是myprint()还是choose(),遵循的都是C调用约定,后面的参数先入栈,并由调用者清理堆栈。

void myprint(char* msg, int len);

int choose(int a, int b)
{
if(a >= b){
myprint("the 1st one\n", 13);
}
else{
myprint("the 2nd one\n", 13);
} return 0;
}

编译和执行的过程:

nasm -f elf -o foo.o foo.asm

gcc -m32 -c -o bar.o bar.c

ld -m elf_i386 -s -o foobar foo.o bar.o

./foobar

运行结果:the 2nd one

有了关键字global和extern就可以方便地在汇编和C代码之间自由来去。

源码

操作系统开发系列—10.内核HelloWorld ●的更多相关文章

  1. 封装一个简单好用的打印Log的工具类And快速开发系列 10个常用工具类

    快速开发系列 10个常用工具类 http://blog.csdn.net/lmj623565791/article/details/38965311 ------------------------- ...

  2. 操作系统开发系列—12.f.在内核中添加中断处理 ●

    因为CPU只有一个,同一时刻要么是客户进程在运行,要么是操作系统在运行,如果实现进程,需要一种控制权转换机制,这种机制便是中断. 要做的工作有两项:设置8259A和建立IDT. /*========= ...

  3. 操作系统开发系列—12.d.扩充内核 ●

    现在把esp.GDT等内容放进内核中,我们现在可以用C语言了,只要能用C,我们就避免用汇编. 下面看切换堆栈和GDT的关键代码: ; 导入函数 extern cstart ; 导入全局变量 exter ...

  4. 操作系统开发系列—12.c.从Loader加载ELF内核,顺便解释下函数调用过程 ●

    实际上,我们要做的工作是根据内核的Program header table的信息进行类似下面这个C语言语句的内存复制: memcpy(p_vaddr, BaseOfLoaderPhyAddr+p_of ...

  5. 操作系统开发系列—12.a.从Loader到内核 ●

    Loader要做两项工作,我们先来做第一项,把内核加载到内存: 1.加载内核到内存. 2.跳入保护模式. 首先编译无内核时: nasm boot.asm -o boot.bin nasm loader ...

  6. 操作系统开发系列—1.HelloWorld ●

    org 07c00h ;伪指令,告诉编译器程序会被加载到7c00处 mov ax, cs mov ds, ax mov es, ax call DispStr ;调用显示字符串例程 jmp $ ;无限 ...

  7. 操作系统开发系列—12.g.在内核中设置键盘中断

    8259A虽然已经设置完成,但是我们还没有真正开始使用它呢. 所有的中断都会触发一个函数spurious_irq(),这个函数的定义如下: PUBLIC void spurious_irq(int i ...

  8. 操作系统开发系列—9.Loader

    一个操作系统从开机到开始运行,大致经历“引导—>加载内核入内存—>跳入保护模式—>开始执行内核”这样一个过程.也就是说,在内核开始执行之前不但要加载内核,而且还有准备保护模式等一系列 ...

  9. 操作系统开发系列—4.LDT

    一直以来,我们把所有的段描述符都放在GDT中,而不管它属于内核还是用户程序,为了有效地在任务之间实施隔离,处理器建议每个任务都应当具有自己的描述符表,称为局部描述符表LDT,并且把专属于自己的那些段放 ...

随机推荐

  1. [Java 基础]数组

    数组初始化 定义数组语法格式 定义数组有两种方式,如下两种格式是等价的: int[] a1; int a1[];  注:在C/C++中,不支持第一种格式.但是,推荐使用这种方式,因为这样似乎更合理,声 ...

  2. [锋利JQ]-图片提示效果

    新知识点: 在HTML-Dom中 "style" 属性,是所有HTML标签共有的一个对象属性,这个对象属性可以为元素设置内嵌样式. style是元素的属性,但是它自身则是一个对象, ...

  3. canvas画简单电路图

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. [DBW]js获取当前时间(昨天、今天、明天)

    开发过程中某些前台页面的时间控件我们需要给默认当前时间,jquery可以轻松的帮我们实现,代码如下 1 //昨天的时间 2 var day1 = new Date(); 3 day1.setTime( ...

  5. GCC、ARM-LINUX-GCC、ARM-ELF-GCC浅析

    一.GCC简介: The GNU Compiler Collection,通常简称GCC,是一套由GNU开发的编译器集,为什么是编辑器集而不是编译器呢?那是因为它不仅支持C语言编译,还支持C++, A ...

  6. input框中的size和maxlength的区别

  7. Android使用SAX解析XML(6)

    应用截图: (1)开始运行时 (2)选择学院 (3)选择专业 (4)选择班级 (5)选择班级的详细信息 本文参考了<Android平台开发之旅>.

  8. Java 经典实例: Unicode字符和String之间的转换

    在Java诞生之际,Unicode码是一个16位的字符集,因此char值似乎顺其自然为16位宽,多年来一个char变量几乎可以表示任何Unicode字符. /** * Created by Frank ...

  9. Struts2框架的自定义类型转换器

    前言:对于java的基本数据类型及一些系统类(如Date类.集合类),Struts2提供了内置类型转换功能,但是也有一定的限制.所以就演示出自定义类型转换器 一.应用于局部类型转换器 eg.用户登录出 ...

  10. 【转】UTF-8汉字正则表达式

    原文链接:http://blog.csdn.net/wide288/article/details/30066639 $str = "编程";// if(!preg_match(& ...