选择显示字体大小

freebsd启动扇区代码分析(ver5.2.1)

freebsd完整的内核代码在freebsd的“/sys”目录下。其中,freebsd 的 boot manager代码是 sys\boot\i386\boot0\boot0.s,它是freebsd自带的boot manager,其功能虽然不如linux的lilo和grub功能强大,但它只需按一个键就可以引导,界面直观。 小小的512字节,可以给你一个简单明了的启动选择界面,还能记住你上次的选择。以下,就对此代码进行详细分析:

当我们打开计算机电源时,计算机叽叽嘎嘎进行设备和内存检测过后就读取硬盘或者软盘的引导扇区,这个扇区只有512字节,显然这512字节不能够有多大作用,这512字节的代码被bios放在地址从0x0000:0x7c00开始处。然后直接跳转到0x0000:0x7c00处去执行。以上工作是bios 干的,你什么也不用作。操作系统需要通过这个引导扇区代码再装载操作系统的其他部分。 在还没有跳转到这段代码之前,也就是bios把磁盘的引导扇区读入到内存之后,其dl和es、si寄存器的内容如下: dl:表示启动设备,例如,如果计算机是从软盘启动的则dl=0,若是从ide的c、d盘(严格来说是物理磁盘一和物理磁盘二,而不是逻辑磁盘分区)启动的则dl分别为0x80和0x81。如果是从硬盘启动的话,es:si是指向bios中的硬盘分区表存放的地址。

好了,我们现在已经知道,计算机的bios已经把引导扇区的512字节的内容读入到了0:0x7c00处,然后就跳转到0:0x7c00处去执行,也就是执行引导扇区代码,引导扇区代码boot0执行代码dump如下(它很有用,以后我们还不时回头来看):



上图中的4x16个字节是保留的4个分区信息

下面,我们对freebsd启动扇区代码boot0.s进行逐步分析。boot0.s代码如下:

## copyright (c) 1998 robert nordier# all rights reserved.## redistribution and use in source and binary forms are freely# permitted provided that the above copyright notice and this# paragraph and the following disclaimer are duplicated in all# such forms.## this software is provided "as is" and without any express or# implied warranties, including, without limitation, the implied# warranties of merchantability and fitness for a particular# purpose.#以上的coyright就不用翻译了。# &#36;freebsd: src/sys/boot/i386/boot0/boot0.s,v 1.27 2003/11/20 20:28:18 jhb exp &#36;以上供版本管理软件使用 # a 512-byte boot manager.        .set nhrdrv,0x475     # number of hard drives        .set origin,0x600     # execution address        .set fake,0x800       # partition entry        .set load,0x7c00      # load address        .set prt_off,0x1be     # partition table        .set tbl0sz,0x3     # table 0 size        .set tbl1sz,0xb     # table 1 size        .set magic,0xaa55     # magic: bootable        .set b0magic,0xbb66     # identification        .set key_enter,0x1c     # enter key scan code        .set key_f1,0x3b         # f1 key scan code        .set key_1,0x02         # #1 key scan code## addresses in the sector of embedded data values.# accessed with negative offsets from the end of the relocated sector (&#37;ebp).#        .set _nxtdrv,-0x48         # next drive        .set _opt,-0x47             # default option        .set _setdrv,-0x46         # drive to force        .set _flags,-0x45         # flags        .set _ticks,-0x44         # timeout ticks        .set _fake,0x0             # fake partition entry        .set _mnuopt,0xc # menu options 以上是定义相关的参数值,例如“.set nhrdrv,0x475”类似于c语言中的“#define nhrdrv 0x475”        .globl start     # entry point        .code16          # this runs in real mode## initialise segments and registers to known values.# segments start at 0.# the stack is immediately below the address we were loaded to.#start:        cld             # string ops inc        xorw &#37;ax,&#37;ax     # zero        movw &#37;ax,&#37;es     # address        movw &#37;ax,&#37;ds     #  data        movw &#37;ax,&#37;ss     # set up        movw &#36;load,&#37;sp     #  stack 以上代码:1)首先使用“cld”指令清除方向标志,使得以下的进行“rep”操作时si和di的值递增。2)使ax清零,并使除代码段cs外的另外两个数据段寄存器es、ds和堆栈段ss清零。当然,此时cs   由于reset或初始上电已经为零了。3)bios已经把引导扇区的512字节的内容读入到了0:0x7c00处,movw &#36;load,&#37;sp 使得堆栈指针指向扇区   代码(或曰本段代码 0:0x7c00)的顶部。虽然堆栈向下生长可能会影响代码的内容,但下面我   们马上就把位于0:7c00处代码移到其他地方去执行。 ## copy this code to the address it was linked for#        movw &#37;sp,&#37;si         # source        movw &#36;start,&#37;di     # destination        movw &#36;0x100,&#37;cx     # word count        rep                 # relocate        movsw                 #  code把位于0:7c00处的代码搬移到0:0x600处。注意,此时由于代码连接的重定向,&#36;start=0x600。## set address for variable space beyond code, and clear it.# notice that this is also used to point to the values embedded in the block,# by using negative offsets.        movw &#37;di,&#37;bp     # address variables        movb &#36;0x8,&#37;cl     # words to clear        rep             # zero        stosw             #  them通过以上一段代码的执行,本代码已被搬移到0:0x600处,此时si=di=0x600+0x100,以上代码把di的值保存到bp,bp此时指向本程序搬移后的未用的空间的首部,且把此bp所指的16字节空间清零。以上过程如下图所示:                        ┏>0:0x600 ┏━━━━━┓                        ┃         ┃          ┃                        ┃         ┃    搬    ┃                        ┃         ┃    移    ┃                        ┃         ┃    之    ┃                        ┃         ┃    后    ┃                        ┃         ┃    的    ┃                        ┃         ┃    代    ┃                        ┃         ┃    码    ┃                        ┃         ┃          ┃                        ┃ 0:0x7ff ┣━━━━━┫                        ┃         ┃    0     ┃<-bp指向这里(0:0x800),以此开始的16字节被清零。                        ┃         ┣━━━━━┫以下所称的fake partition entry就是指这里。                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┣━━━━━┫                        ┃         ┃    0     ┃                        ┃         ┗━━━━━┛0:0x7c00 ┏━━━━━┓ ┛         ┃          ┃         ┃    搬    ┃         ┃    移    ┃         ┃    之    ┃         ┃    前    ┃         ┃    的    ┃         ┃    代    ┃         ┃    码    ┃         ┃          ┃0:0x7dff ┗━━━━━┛                      图(二)## relocate to the new copy of the code.#        incb -0xe(&#37;di) # sector number        jmp main-load+origin # to relocated code把以上清零的16字节的第二个字节置为1,表示我们已经读取了一个分区。然后跳转到搬移之后的新代码的main处执行。## check what flags were loaded with us, specifically, use a predefined drive.# if what the bios gives us is bad, use the '0' in the block instead, as well.#main:        testb &#36;0x20,_flags(&#37;bp)       # set number drive?        jnz main.1                     # yes        testb &#37;dl,&#37;dl                 # drive number valid?        js main.2                     # possibly (0x80 set)main.1:        movb _setdrv(&#37;bp),&#37;dl # drive number to use上面说过,bios把磁盘的引导扇区读入到内存之后,其dl的内容表示启动设备,但我们安装好freebsd之后,我们可以改变此引导扇区的内容,其中的一个改变就是可以使我们可以“手动指定”我们实际安装freebsd的分区,如果我们希望指定freebsd所在的boot分区,那么我们在bp-0x45处的位置(即_flags(&#37;bp)处)的bit 0x20置1,那么上面的“movb _setdrv(&#37;bp),&#37;dl”一句中movb_setdrv(&#37;bp),&#37;dl(即bp-0x46)即指向我们“手动指定”freebsd所在分区代码,例如,ide的c、d盘(严格来说是第一个物理磁盘的第一个和第二个分区)的代码分别为 0x80和0x81。如果没有“手动指定”启动分区,那么,我们缺省使用机器当前启动的分区,上面说过,机器当前启动的分区代码放在dl中。因为freebsd boot manager 不可能安装到软盘(如果从软盘启动则dl为0),所以,使用testb &#37;dl,&#37;dl来判断驱动器代码是否合法(volid)。有关_flags(&#37;bp)中其他bit位表示的意义,在随后的代码分析中慢慢给你道来。## whatever we decided to use, now store it into the fake# partition entry that lives in the data space above us.#main.2:        movb &#37;dl,_fake(&#37;bp) # save drive number        callw putn # to new line        pushw &#37;dx # save drive number以上第一句把freebsd启动分区的代码保存到_fake(&#37;bp)(bp-0)处,也就是说,上图(二)的bp处保存的是freebsd启动分区的代码(_fake=0)。“callw putn”一句在屏幕上打印“回车”和“换行”,“pushw &#37;dx”一句把启动分区的值压入堆栈。## start out with a pointer to the 4th byte of the first table entry# so that after 4 iterations it's beyond the end of the sector.# and beyond a 256 byte boundary and has overflowed 8 bits (see next comment).# (remember that the table starts 2 bytes earlier than you would expect# as the bootable flag is after it in the block)#        movw &#36;(partbl+0x4),&#37;bx # partition table (+4)        xorw &#37;dx,&#37;dx # item number以上代码首先把&#37;bx指向分区表partbl的的第四个字节,这里存放的是分区类型,如82表示linux native分区83表示linux swap 分区,有关分区表的细节请详见本文的尾部。然后dx清零,此后,dx将作为遍历磁盘分区的列举代号使用。启动分区代码dl的原来的值在上面已经压入了堆栈保存。## loop around on the partition table, printing values until we# pass a 256 byte boundary. the end of loop test is at main.5.#main.3:        movb &#37;ch,-0x4(&#37;bx)     # zero active flag (ch == 0)        btw &#37;dx,_flags(&#37;bp)     # entry enabled?        jnc main.5             # no上面首先使得第一个分区的活动标志为0,标志它不为活动标志,因为ch的值为0。至于第二句“btw &#37;dx,_flags(&#37;bp)”中的_flags(&#37;bp)是上面我们说到的“手动指定我们实际安装freebsd的分区代码”。其中的bit 0x20我们在上面已经提到过。_flags(&#37;bp)中的其他位表示是否我们需要检查相应的磁盘分区。缺省情况下,我们需要检查所有的磁盘分区。检查磁盘分区看是否有可以启动的磁盘分区,例如,可能磁盘上的某个分区为windowsxp或者是linux等。如果我们没有改变在磁盘上该处的值,则相应的bit位的值为0,表示所有的分区都要检查(因为此时_flags(&#37;bp)中的值为0),否则,只针对flags(&#37;bp)中相应的bit位未被设置为1的分区进行检查。大家知道,freebsd manager启动时可能出现以下的提示:f1    freebsdf2    ??f3    bsdf4    ??default    f1其中,上面的提示中出现了令人讨厌的“??”,为了避免出现“??”的提示,我们可以设置相应的第一分区和第四分区不检查,就需要正确设置_flags(&#37;bp)中的bit位。设置好后,屏幕可能出现以下的提示:f1    freebsdf2    bsddefault    f1## if any of the entries in the table are# the same as the 'type' in the slice table entry,# then this is an empty or non bootable partition. skip it.#        movb (&#37;bx),&#37;al         # load type        movw &#36;tables,&#37;di     # lookup tables        movb &#36;tbl0sz,&#37;cl     # number of entries        repne                 # exclude        scasb                 #  partition?        je main.5             # yes我们从上面已经知道起始(&#37;bx)指向的是mbr中分区信息1(16字节)的位置(见图(三)),以上代码在“忽略的分区类型&#36;tables”中查找看是否本分区是不可启动的或者不合法的分区。不可启动的或者不合法的分区类型有3(&#36;tbl0sz=3)个,它们是“0x0, 0x5, 0xf”,见下面的&#36;tables处。如果是不可启动的或者不合法的分区类型则跳转到main.5,进行下一轮循环。## now scan the table of known types#        movb &#36;tbl1sz,&#37;cl         # number of entries        repne                     # known        scasb                     #  type?        jne main.4                 # no## if it matches get the matching element in the# next array. if it doesn't, we are already# pointing at its first element which points to a "?".#        addw &#36;tbl1sz,&#37;di     # adjustmain.4:        movb (&#37;di),&#37;cl # partition        addw &#37;cx,&#37;di #  description        callw putx # display it上面检查看所检查的分区类型是否为我们知道的分区类型,知道的分区类型有11(&#36;tbl1sz=0xb)个,它们是:“0x1, 0x4, 0x6, 0xb, 0xc, 0xe, 0x83,0x9f, 0xa5, 0xa6, 0xa9”,见下面的&#36;tables处。如果不是以上的类型,则跳转到main.4。那么,(&#37;di)所指的字串是“??”,如果分区类型是“0x1, 0x4, 0x6, 0xb, 0xc, 0xe, 0x83,0x9f, 0xa5, 0xa6, 0xa9”之一,则(&#37;di)所指的字串是“dos”、“linux”、“freebsd”或“bsd”等。见下面的“os_misc”、“os_dos”、“os_linux”、“os_freebsd”、“os_bsd”等标记。callw putx调用putx函数,在屏幕上打印:“fx   xxx”。其中xxx为dos”、“linux”、“freebsd”或“bsd”等。main.5:        incw &#37;dx # next item        addb &#36;0x10,&#37;bl # next entry        jnc main.3 # till done遍历磁盘分区的举代号dx加1,重复下一轮循环查找。bl加上0x10(0x10=16)表示寻址到下一个分区信息(加16字节)入口。循环直到255字节边界。## passed a 256 byte boundary..# table is finished.# add one to the drive number and check it is valid,#        popw &#37;ax                 # drive number        subb &#36;0x80-0x1,&#37;al     # does next        cmpb nhrdrv,&#37;al         #  drive exist? (from bios?)        jb main.6                 # yes“popw &#37;ax”把上面压入堆栈的bx(当前的启动扇区)值弹出到ax中。例如,如果计算机是从软盘启动的则dl=0,若是从ide的c、d盘启动的则dl分别为 0x80和0x81。然而,freebsd的boot manerger不能够安装到软盘上,所以,dl只能为0x80、0x81,0x82...等。在计算机的bios地址0:0x475处存放的是计算机的硬盘的数目,“subb &#36;0x80-0x1,&#37;al”一句等于“sub&#36;0x79,&#37;al”,例如,即当前驱动器如果是c盘,则al的值是ox80-0x79=1,然后再与计算机的硬盘的数目比较,如果当前所在硬盘不是最后一个硬盘,则直接跳转到main.6。如果当前所在硬盘是最后一个硬盘,则继续执行。# if not then if there is only one drive,# don't display drive as an option.#        decw &#37;ax         # already drive 0?        jz main.7         # yes如果只有一个硬盘,则直接跳转到main.7,这样,本计算机只有一个硬盘,所以不用显示其他磁盘相关的提示。# if it was illegal or we cycled through them,# then go back to drive 0.#        xorb &#37;al,&#37;al # drive 0下面的内容表示多于一个磁盘的情况。此时“al”清0,与磁盘列举相关。## whatever drive we selected, make it an ascii digit and save it back# to the "next drive" location in the loaded block in case we# want to save it for next time.# this also is part of the printed drive string so add 0x80 to indicate# end of string.#main.6:        addb &#36;'0'0x80,&#37;al         # save next        movb &#37;al,_nxtdrv(&#37;bp)         #  drive number        movw &#36;drive,&#37;di             # display        callw putx             #  item首先,在_nxtdr(&#37;bp)处置入“0字符高位置1”的字符,以代表第二个驱动器,然后在屏幕上显示“fx drive”,表示更换另外的磁盘启动。注意,在调用putx之前,di中保存的是下面字串“drive ”的首地址。dl中存放的是当前遍历的到的可启动的或者合法的分区类型递增序数,al与dl是不同的,al是ascii码,dl是“fx”中的x值。## now that we've printed the drive (if we needed to), display a prompt.# get ready for the input byt noting the time.#main.7:        movw &#36;prompt,&#37;si     # display        callw putstr         #  prompt        movb _opt(&#37;bp),&#37;dl     # display        decw &#37;si             #  default        callw putkey         #  key        xorb &#37;ah,&#37;ah         # bios: get        int &#36;0x1a             #  system time        movw &#37;dx,&#37;di             # ticks when        addw _ticks(&#37;bp),&#37;di   #  timeout上面的代码首先在屏幕上打印出字符串“default: ”,缺省启动的磁盘号放在“_opt(&#37;bp)”中,这里有个小小的技巧,在执行“decw &#37;si”和“callw putkey”两句后屏幕会显示“fx”,x是_opt(&#37;bp)的ascii。然后取得当前的tickes放到&#37;di中,等待用户按键超时的时间从_ticks(&#37;bp)中取出,加到当前的tickes即是最后超时时间到的tickes。## busy loop, looking for keystrokes but# keeping one eye on the time.#main.8:        movb &#36;0x1,&#37;ah     # bios: check        int &#36;0x16         #  for keypress        jnz main.11         # have one        xorb &#37;ah,&#37;ah         # bios: get        int &#36;0x1a         #  system time        cmpw &#37;di,&#37;dx         # timeout?        jb main.8         # no等待用户按下“fx”键,同时检查当前等待是否超时,如果有用户按键则跳转到main.11,如果超时时间不到则继续等待。## if timed out or defaulting, come here.#main.9:        movb _opt(&#37;bp),&#37;al # load default        jmp main.12 # join common code超时时间到,此时表示用户使用缺省分区启动,把缺省的启动分区号置入al中,然后跳转到main.12。## user's last try was bad, beep in displeasure.# since nothing was printed, just continue on as if the user# hadn't done anything. this gives the effect of the user getting a beep# for all bad keystrokes but no action until either the timeout# occurs or the user hits a good key.#main.10:        movb &#36;0x7,&#37;al # signal        callw putchr #  error用户输入错误,只是响铃提示,其他什么也不发生。## get the keystroke.#main.11:        xorb &#37;ah,&#37;ah         # bios: get        int &#36;0x16             # keypress        movb &#37;ah,&#37;al         # scan code用户按下了一个键,把键值扫描码放到al中。## if it's cr act as if timed out.#        cmpb &#36;key_enter,&#37;al         # enter pressed?        je main.9                 # yes如果用户按下“enter”键,和超时等同处理,这样,就启动缺省的boot分区。## otherwise check if legal# if not ask again.#        subb &#36;key_f1,&#37;al         # less f1 scan code        cmpb &#36;0x4,&#37;al             # f1..f5?        jna main.12                 # yes        subb &#36;(key_1 - key_f1),&#37;al         # less #1 scan code        cmpb &#36;0x4,&#37;al                 # #1..#5?        ja main.10                     # no如果是除“enter”键外其他的键,则检查是不是f1...f5键,如果不是,表示输入不合法,跳回到main.10处理。## we have a selection.# but if it's a bad selection go back to complain.# the bits in mnuopt were set when the options were printed.# anything not printed is not an option.#main.12:        cbtw                     # option        btw &#37;ax,_mnuopt(&#37;bp)   #  enabled?        jnc main.10             # no如果是f1...f5键,则检查是否在我们提示的范围内,其中,_mnuopt(&#37;bp)的相应bit位为1,表示是一个合法的选项,如果不是,跳回到 main.10处理。## save the info in the original tables# for rewriting to the disk.#        movb &#37;al,_opt(&#37;bp)         # save option把我们按下的f1...f5键保存到_opt(&#37;bp)位置。        movw &#36;fake,&#37;si             # partition for write        movb (&#37;si),&#37;dl             # drive number把原来的启动分区代码取回到dl中。        movw &#37;si,&#37;bx                 # partition for read        cmpb &#36;0x4,&#37;al                 # f5 pressed?        pushf                     # save        je main.13             # yes如果我们按下的是f5键则直接跳转到main.13处理。        shlb &#36;0x4,&#37;al             # point to        addw &#36;partbl,&#37;ax             #  selected        xchgw &#37;bx,&#37;ax               #  partition        movb &#36;0x80,(&#37;bx)             # flag active上面,我们从按键fx选择中得到图(三)中的我们选择的四个分区信息中的某一分区信息,上面计算出的bx为我们选择的分区信息的首地址,我们把此选择到的分区信息的第一个个字节置为0x80表示它是当前的活动分区。## if not asked to do a write-back (flags 0x40) don't do one.#main.13:        pushw &#37;bx                     # save        testb &#36;0x40,_flags(&#37;bp)         # no updates?        jnz main.14                 # yes        movw &#36;start,&#37;bx         # data to write        movb &#36;0x3,&#37;ah             # write sector        callw intx13             #  to disk检查回写标志_flags(&#37;bp)的bit位0x40为,如果设置的是可回写,则把当前选择到的boot分区作为下次缺省的启动分区。main.14:        popw &#37;si             # restore        popf                 # restore## if going to next drive, replace drive with selected one.# remember to un-ascii it. hey 0x80 is already set, cool!#        jne main.15                 # if not f5恢复上面保存的si和标志寄存器的内容。如果不是按键f5,则直接跳转到main.15去执行。        movb _nxtdrv(&#37;bp),&#37;dl         # next drive        subb &#36;'0',&#37;dl                 #  number否则的话,我们选择下一个驱动器作为启动盘。## load  selected bootsector to the load location in ram.# if it fails to read or isn't marked bootable, treat it# as a bad selection.# xxx what does &#37;si carry?#main.15:        movw &#36;load,&#37;bx         # address for read        movb &#36;0x2,&#37;ah             # read sector        callw intx13         #  from disk        jc main.10             # if error把我们上面选择到的分区读到0x7c00处,就象我们刚刚才加电启动一样,只是活动分区改变了而已。如果发生读错误则直接跳转到main.10。使用户重新选择启动分区。        cmpw &#36;magic,0x1fe(&#37;bx)         # bootable?        jne main.10             # no判断引导扇区的最后两个字节是否是“0x55aa”,如果不是,则表示此扇区是不可引导的,或不合法的引导扇区则直接跳转到main.10。使用户重新选择启动分区。        pushw &#37;si             # save        movw &#36;crlf,&#37;si         # leave some        callw puts             #  space        popw &#37;si             # restore打印“回车”和“换行”。        jmp *&#37;bx             # invoke bootstrap跳转到我们选择的引导扇区去执行。整个boot manager代码到此执行完毕。## display routines#putkey:        movb &#36;'f',&#37;al         # display        callw putchr         #  'f'        movb &#36;'1',&#37;al         # prepare        addb &#37;dl,&#37;al         #  digit        jmp putstr.1         # display the rest“putkey”函数在屏幕上打印“f1”、“f2”或“f3”等。如果dl为0则打印“f1”,如果dl为1则打印“f2”,如果dl为3则打印“f3”。和调用“putstr”在屏幕上打印es:si指向的以最高位置1为结束字符的字符串。## display the option and note that it is a valid option.# that last point is a bit tricky..#putx: #首先,把_mnuopt(&#37;bp)的第dx位(bit)置1,表示此菜单选项被显示。然后在屏幕上打印空格和es:di指向的以最高位置1为结束字符的字符串。        btsw &#37;dx,_mnuopt(&#37;bp)         # enable menu option        movw &#36;item,&#37;si                 # display        callw putkey                 #  key        movw &#37;di,&#37;si                 # display the restputs: #调用“putstr”在屏幕上打印es:si指向的以最高位置1为结束字符的字符串。        callw putstr                 # display stringputn: #“putn”打印“回车/换行”后在屏幕上打印es:si指向的以最高位置1为结束字符的字符串。        movw &#36;crlf,&#37;si                 # to next lineputstr: #“putstr”在屏幕上打印es:si指向的以最高位置1为结束字符的字符串。        lodsb                     # get byte        testb &#36;0x80,&#37;al         # end of string?        jnz putstr.2             # yesputstr.1:        callw putchr             # display char        jmp putstr                 # continueputstr.2:        andb &#36;~0x80,&#37;al             # clear msbputchr:        pushw &#37;bx                 # save        movw &#36;0x7,&#37;bx           # page:attribute        movb &#36;0xe,&#37;ah             # bios: display        int &#36;0x10                 #  character        popw &#37;bx                 # restore        retw                     # to caller“putchr”在屏幕上显示“al”中的字符。# one-sector disk i/o routineintx13:        movb 0x1(&#37;si),&#37;dh             # load head        movw 0x2(&#37;si),&#37;cx             # load cylinder:sector        movb &#36;0x1,&#37;al                 # sector count        pushw &#37;si                     # save        movw &#37;sp,&#37;di                 # save        testb &#36;0x80,_flags(&#37;bp)         # use packet interface?        jz intx13.1                 # no        pushl &#36;0x0                 # set the        pushl 0x8(&#37;si)             # lba address        pushw &#37;es                 # set the transfer        pushw &#37;bx                 #  buffer address        push  &#36;0x1                 # block count        push  &#36;0x10                 # packet size        movw &#37;sp,&#37;si             # packet pointer        decw &#37;ax                 # verify off        orb &#36;0x40,&#37;ah             # use disk packetintx13.1:        int &#36;0x13                 # bios: disk i/o        movw &#37;di,&#37;sp             # restore        popw &#37;si                 # restore        retw                     # to caller# menu stringsitem:        .ascii "  ";      .byte ' '0x80prompt:        .ascii "\ndefault:"; .byte ' '0x80crlf:        .ascii "\r";      .byte '\n'0x80# partition type tablestables:## these entries identify invalid or non boot types and partitions.#        .byte 0x0, 0x5, 0xf## these values indicate bootable types we know the names of#        .byte 0x1, 0x4, 0x6, 0xb, 0xc, 0xe, 0x83        .byte 0x9f, 0xa5, 0xa6, 0xa9## these are offsets that match the known names above and point to the strings# that will be printed.#        .byte os_misc-.         # unknown        .byte os_dos-.         # dos        .byte os_dos-.         # dos        .byte os_dos-.         # dos        .byte os_dos-.         # windows        .byte os_dos-.         # windows        .byte os_dos-.         # windows        .byte os_linux-.         # linux        .byte os_bsd-.         # bsd/os        .byte os_freebsd-.         # freebsd        .byte o (完)


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons