操作系统开发系列—10.内核HelloWorld ●
2016-04-15 17:38
337 查看
a.我们先来体验一下在Linux下用汇编编程的感觉,见代码
编译方法:
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同步使用
1.由于在bar.c中用到函数myprint(),所以要用关键字global将其导出。
2.由于用到本文件外定义的函数choose(),所以要用关键字extern声明。
3.不管是myprint()还是choose(),遵循的都是C调用约定,后面的参数先入栈,并由调用者清理堆栈。
编译和执行的过程:
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代码之间自由来去。
【源码】
[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代码之间自由来去。
【源码】
相关文章推荐
- 九种乱码解决办法(非原创)
- CentOS7上GitHub/GitLab多帐号管理SSH Key
- 重要!!!model原带update和cerate进行逻辑更新和存值(代码复用)
- OpenCV中寻找轮廓函数cvFindContours的使用说明以及序列cvSeq的用法说明
- CentOS安装ReviewBoard记录
- 一个优秀的程序员应该如何提高工作效率?
- 朴素贝叶斯
- MTK Nucleus平台软件log抓取方法
- 王高利:Kvm虚拟化(1)__基础搭建
- Python 练习实例15
- 报道贴
- 三、命令模式Commond(行为型模式)
- iOS APP上架详细流程
- HBase -ROOT-和.META.表结构(region定位原理)
- git工作流
- 一小时搞定DIV+CSS布局-固定页面开度布局
- C++作业2-2
- 2. 快速入门-跟着例子走
- Project facet Java version 1.8 is not supported.错误提示解决方法
- DecimalFormat类——Java中字符串类型的数字加减报错和精度缺失的解决办法