C与汇编合作编程+Makefile

2017-12-12  本文已影响52人  十月石榴2013

这周主要学习了保护模式下操作系统的加载与运行,但还没有完全学完。其中有个知识点是汇编语言与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:一个操作系统的实现》

上一篇下一篇

猜你喜欢

热点阅读