美文网首页
C与汇编合作编程+Makefile

C与汇编合作编程+Makefile

作者: 十月石榴2013 | 来源:发表于2017-12-12 11:18 被阅读52次

    这周主要学习了保护模式下操作系统的加载与运行,但还没有完全学完。其中有个知识点是汇编语言与C语言合作实现一段程序。大概流程是这样:

    image.png

    (图来自《Orange'S:一个操作系统的实现》)


    image.png

    在Linux上实现,具体实现大致是:

    ①在写.asm程序的时候使用“extern”表示使用的函数来自外部文件,使用“global”表示函数可以被外部使用。C语言不需要特殊说明,按语法写即可,函数间采用栈传递参数,后面的参数先入栈。

    ②编译(compile),各自生成目标文件.o文件,汇编用nasm,C用gcc,此时的.o文件已经是机器语言文件了。

    ③链接(link),采用nasm,生成.bin文件。本质上是根据函数名将函数相互链接起来,因此一定不要重名!

    ④ld指令可以指定程序在内存中的位置:ld –s –Ttext指定位置–o xxx.bin xxx.o在最后有一步执行。

    但这几步需要执行很多条指令,需要逐条输入这些指令而且修改了其中一个文件名之后,所有指令中相关的文件名都需要修改,非常麻烦,也容易出错。因此,采用Makefile文件,以实现对编译连接流程的控制。

    Makefile文件没有后缀名,就叫“Makefile”,可以用笔记本写。基本元素是这样的:

    (第一行)目标文件:源文件

    (第二行)指令

    即,

    (第一行)target...: prerequisites ...

    (第二行)command

    除此之外,在开头可以定义“常数”,类似C语言的define,汇编语言的EQU。例如:

    OBJS = xxx.o

    使用时,将指令中xxx.o的地方都换成$(OBJS)。

    还有$@和$<,$@是指目标文件,$<指源文件的第一个名字。可以写在指令里面,避免文件改名之后忘记都改。

    例子;

    
    # [root@XXX XXX]# rm -f kernel.bin
    
    # [root@XXX XXX]# nasm -f elf -o kernel.o kernel.asm
    
    # [root@XXX XXX]# nasm -f elf -o string.o string.asm
    
    # [root@XXX XXX]# nasm -f elf -o klib.o klib.asm
    
    # [root@XXX XXX]# gcc -c -o start.o start.c
    
    # [root@XXX XXX]# ld -s -Ttext 0x30400 -o kernel.bin kernel.o string.o start.o klib.o
    
    # [root@XXX XXX]# rm -f kernel.o string.o start.o
    
    # [root@XXX XXX]#
    
    ENTRYPOINT = 0x30400
    
    ENTRYOFFSET =  0x400
    
    # Programs, flags, etc.
    
    MAKE = make
    
    ASM = nasm
    
    DASM = ndisasm
    
    CC = gcc
    
    LD = ld
    
    ASMBFLAGS = -I boot/include
    
    ASMKFLAGS = -I include -f elf
    
    CFLAGS = -I include -c -fno-builtin
    
    LDFLAGS = -s -Ttext $(ENTRYPOINT)
    
    DASMFLAGS = -u -o $(ENTRYPOINT) -e $(ENTRYOFFSET)
    
    OBJS = kernel.o string.o start.o klib.o
    
    # All Phony Targets
    
    .PHONY : everything final image clean realclean disasm all buildimg
    
    # Default starting position
    
    default :
    
    $(MAKE) boot.bin
    
    $(MAKE) loader.bin
    
    $(MAKE) kernel.bin
    
    $(MAKE) buildimg
    
    clean :
    
    rm $(OBJS) kernel.bin
    
    realclean :
    
    rm -f $(OBJS) $(TINIXBOOT) $(TINIXKERNEL)
    
    disasm :
    
    $(DASM) $(DASMFLAGS) $(TINIXKERNEL) > $(DASMOUTPUT)
    
    # Write "boot.bin" & "loader.bin" into floppy image "TINIX.IMG"
    
    # We assume that "TINIX.IMG" exists in current folder
    
    buildimg :
    
    dd if=/dev/zero of=tinix.img bs=512 count=2880
    
    dd if=boot.bin of=tinix.img bs=512 count=1 conv=notrunc
    
    mount -o loop -r -w tinix.img /mnt/floppy/
    
    cp -f loader.bin /mnt/floppy/
    
    cp -f kernel.bin /mnt/floppy
    
    umount  /mnt/floppy
    
    boot.bin : boot.asm
    
    $(ASM) $(ASMBFLAGS) -o $@ $<
    
    loader.bin : loader.asm
    
    $(ASM) $(ASMBFLAGS) -o $@ $<
    
    kernel.bin : $(OBJS)
    
    $(LD) $(LDFLAGS) -o kernel.bin $(OBJS)
    
    kernel.o :kernel.asm
    
    $(ASM) $(ASMKFLAGS) -o $@ $<
    
    string.o :string.asm
    
    $(ASM) $(ASMKFLAGS) -o $@ $<
    
    klib.o: klib.asm
    
    $(ASM) $(ASMKFLAGS) -o $@ $<
    
    start.o: start.c
    
    $(CC) -c -o $@ $<
    
    

    [图片上传失败...(image-157d4e-1513048624585)]

    参考资料:

    http://m.blog.csdn.net/ruglcc/article/details/7814546?from=singlemessage&isappinstalled=0

    《Orange'S:一个操作系统的实现》

    相关文章

      网友评论

          本文标题:C与汇编合作编程+Makefile

          本文链接:https://www.haomeiwen.com/subject/thbgixtx.html