zoukankan      html  css  js  c++  java
  • 操作系统开发系列—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代码之间自由来去。

    一个码农的日常 

    源码

  • 相关阅读:
    【AHOI2009】 维护序列
    Codeforces Hello 2019 F. Alex and a TV Show[bitset+莫比乌斯反演]
    Codeforces Hello 2019 D. Makoto and a Blackboard[DP+数论+概率期望]
    Codeforces Hello 2019 ABCDF题解
    [BZOJ1042][HAOI2008]硬币购物[容斥原理+背包]
    Codeforces Round #529 (Div. 3)题解
    [BZOJ4311]向量[线段树分治+计算几何+二分/三分]
    [BZOJ1076][SCOI2008]奖励关[状压DP+概率期望]
    [POJ3368][UVA11235] Frequent values[ST表]
    [USACO5.5]矩形周长Picture[扫描线+线段树]
  • 原文地址:https://www.cnblogs.com/joey-hua/p/5396258.html
Copyright © 2011-2022 走看看