• 操作系统开发系列—10.内核HelloWorld ●


    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
    ", 13);
    	}
    	else{
    		myprint("the 2nd one
    ", 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代码之间自由来去。

    一个码农的日常 

    源码

  • 相关阅读:
    windows利用net use删除smb连接
    用jquery的ajax功能获取网站alexa的方法
    11对于Web开发人员和设计师非常有用的在线工具
    Php获取Alexa排行统计
    php获取alexa世界排名值的函数
    26个免费矢量图片免费下载
    对makefile中双冒号规则的学习
    对makefile中 $*的理解
    GNU make manual 翻译(七十三)
    对makefile 中的 静态模式规则的理解
  • 原文地址:https://www.cnblogs.com/joey-hua/p/5396258.html
Copyright © 2020-2023  润新知