星期一, 一月 09, 2006

使用at&t汇编写x86启动扇区

At&t的汇编语言语法在类unix操作系统中使用很多,linux内核新的源代码全部都是使用at&t汇编完成的,at&t汇编使用编译器是gas,但是,使用at&t汇编与使用nasm或masm编写启动扇区略有不同。新版本的gas不支持直接生成可执行的二进制代码文件,所以还需使用ld进行连接或使用objcopy将其生成的目标文件进行转换才可以使用,下面给出一个例子:
Boot sector的源代码:

START_SEG = 0x07c0
.code16
.text
.global _start
_start:

ljmp $START_SEG, $_start2

_start2:
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw $0x7c00, %sp
sti
cld

movw $hellomsg, %si

msg_loop:
lodsb
andb %al, %al
jz die
movb $0xe, %ah
int $0x10
jmp msg_loop

die:
jmp die

hellomsg:
.ascii "Hello, World!\r\n"
.byte 0

.org 510
boot_flag: .word 0xaa55

这个代码仿照linux内核的bootsect.s写成。编译连接步骤如下:
1. as –o boot1.o boot1s
这句不用解释了
2. 这里有两种方法可以实现
a. ld –o boot1.bin –Ttext 0x0 --oformat binary boot1.o
其中的-Ttext 0x0指定代码中的text段偏移量从0开始
--oformat binary指定输出文件是纯二进制形式
b. objcopy -O binary boot1.o boot1.bin
objcopy的作用是转换文件格式,上面的命令将as生成的目标文件直接转换成对应的二
进制文件,因为此文件是一个自包含即不依赖于任何外界库的文件,所以可以直接转换。
以上两句的结果是等价的,都生成了一个512字节的boot1.bin,在vmware中直接指定floppy image开机就可以看到效果了。在使用cygwin的系统中a方法似乎会失败。
这里主要介绍使用at&t编写boot sector的编译和连接工作,具体的boot sector的内容可以在网上找到。