首页
社区
课程
招聘
新手必看好书 <<自己动手写操作系统>>
发表于: 2007-4-17 22:32 22433

新手必看好书 <<自己动手写操作系统>>

2007-4-17 22:32
22433
收藏
免费 0
支持
分享
最新回复 (35)
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
第1章

             马上动手写一个最小的“操作系统”

                             勿以善小而不为.

                                          ——刘备

    虽说万事开头难,但有时也未必.比如说,写一个有实用价值的操作系统是一项艰
巨的工作,但一个最小的操作系统或许很容易就实现了.现在我们就来实现一个小得无
法再小的“操作系统”,建议你跟随书中的介绍一起动手来做,你会发现不但很容易,而
且很有趣.

1.1 准备工作

对于写程序,准备工作无非就是硬件和软件两方面,我们来看一下:

1.硬件
~ 一台计算机(Windows 操作系统)
~ 一张空白软盘

2.软件
~ 汇编编译器NASM.最新版本可以在此链接处获得:
  http://sourceforge.net/projects/nasm.
  (此刻你可能会有疑问:为什么是NASM,而不是MASM 或者
  TASM?对于这一点本书后面会有解释.)
~ 软盘绝对扇区读写工具.比如本书附赠光盘中的
  FloppyWriter.exe.

1.2 10 分钟完成的操作系统

  你相不相信,一个“操作系统”可以只有20 行代码?请看:

代码1-1 \chapter1\a\boot.asm
-------------------------------------------------------------
   org 07c00h        ; 告诉编译器程序加载到7c00 处
   mov ax, cs
   mov ds, ax
   mov es, ax
   call DispStr      ; 调用显示字符串例程
   jmp $             ; 无限循环
DispStr:
   mov ax, BootMessage
   mov bp, ax        ; es:bp = 串地址
   mov cx, 16        ; cx = 串长度
   mov ax, 01301h    ; ah = 13, al = 01h
   mov bx, 000ch     ; 页号为0(bh = 0) 黑底红字(bl = 0Ch,高亮)
   mov dl, 0
   int 10h           ; 10h 号中断
   ret
   BootMessage: db "Hello, OS world!"
   times 510-($-$$) db 0      ; 填充剩下的空间,使生成的二进制代码恰好为
                              ; 512 字节
   dw 0xaa55                  ; 结束标志
-------------------------------------------------------------
   把这段代码用NASM 编译一下:
    nasm boot.asm –o boot.bin
   我们就得到了一个512B 的boot.bin,使用软盘绝对扇区读写工具将这个文件写到一
张空白软盘的第一个扇区.好了,你的第一个“操作系统”就已经完成了.这张软盘已
经是一张引导盘了.

    把它放到你的软驱中重新启动计算机,从软盘引导,你看到了什么?
    计算机显示出你的字符串了!红色的“Hello, OS world!”,多么奇妙啊,你的“操作
系统”在运行了!
    如果使用Virtual PC 的话(下文中将会有关于Virtual PC 的详细介绍),你应该能看
到图1-1 所示的画面.
    这真的是太棒了,虽然你知道它有多么简陋,但是,毕竟你已经制作了一个可以引
导的软盘了,而且所有工作都是你亲手独立完成的!

            

                        图1-1 最小的 "操作系统"

1.3 Boot Sector

   你可能还没有从刚刚的兴奋中走出来,可是我不得不告诉你,实际上,你刚刚所完
成的并不是一个完整的OS,而仅仅是一个最最简单的引导扇区(Boot Sector).然而不
管我们完成的是什么,至少,它是直接在裸机上运行的,不依赖于任何其他软件,所以,
这和我们平时所编写的应用软件有本质的区别.它不是操作系统,但已经具备了操作系
统的一个特性.

   我们知道,当计算机电源被打开时,它会先进行加电自检(POST),然后寻找启动
盘,如果是选择从软盘启动,计算机就会检查软盘的0 面0 磁道1 扇区,如果发现它以
0xAA55(假如我们把此扇区看做一个字符数组sector[]的话,那么此结束标志相当于
sector[510]=0x55,且sector[511]=0xAA)结束,则BIOS 认为它是一个引导扇区,也就是
我们说的Boot Sector.当然,一个正确的Boot Sector 除了以0xAA55 结束之外,还应该
包含一段少于512B 的执行码.

   好了,一旦BIOS 发现了Boot Sector,就会将这512B 的内容装载到内存的0000:7c00
处,然后跳转到0000:7c00 处将控制权彻底交给这段引导代码.到此为止,计算机不再由
BIOS 中固有的程序来控制,而变成由操作系统的一部分来控制.

  现在,你可能明白了为什么在那段代码的第一行会出现org 07c00 这样的代码.没错,
这行代码就是告诉编译器,将来我们的这段程序要被加载到内存偏移地址7c00 处.好了,
下面将对代码的其他部分进行详细解释.

1.4 代码解释

   其实程序的主体框架只有5 行(从第2 行到第6 行),其中调用了一个显示字符串的
子程序.程序的第2、3、4 行是3 个mov 指令,使ds 和es 两个段寄存器指向与cs 相同
的段,以便在以后进行数据操作的时候能定位到正确的位置.第5 行调用子程序显示字
符串,然后jmp $让程序无限循环下去.

  可能大部分人开始学汇编时用的都是MASM,其实NASM 的格式跟MASM 总体上
是差不多的,在这段程序中,值得说明的地方有以下几点:

   (1)在NASM 中,任何不被方括号[]括起来的标签或变量名都被认为是地址,访问
标签中的内容必须使用[].所以,

    mov ax, BootMessage

将会把“Hello, OS world!”这个字符串的首地址传给寄存器ax.又比如,如果有:

   foo dw 1

则mov ax, foo 将把foo 的地址传给ax,而mov bx, [foo]将把bx 的值赋为1.
   实际上,在NASM 中,变量和标签是一样的,也就是说:

   foo dw 1 ≡ foo: dw 1

   而且你会发现,Offset 这个关键字在NASM 也是不需要的.因为不加方括号时表示
的就是Offset.

   笔者认为这是NASM的一大优点,要地址就不加方括号,也不必额外地用什么Offset,
想要访问地址中的内容就必须加上方括号.代码规则非常鲜明,一目了然.

   (2)关于$和$$.$表示当前行被汇编后的地址.这好像不太好理解,不要紧,我们
把刚刚生成的二进制代码文件反汇编来看看:

   ndisasmw -o 0x7c00 boot.bin >> disboot.asm

   打开disboot.asm,你会发现这样一行:

   00007C09 EBFE jmp short 0x7c09

   明白了吧,$在这里的意思原来就是0x7c09.

   那么$$表示什么呢?它表示一个节(section)的开始处被汇编后的地址.在这里,
我们的程序只有1 个节,所以,$$实际上就表示程序被编译后的开始地址,也就是0x7c00.

注意:这里的section 属于NASM 规范的一部分,表示一段代码,关于它和
$$更详细的注解请参考NASM 联机技术文档.


   在写程序的过程中,$-$$可能会被经常用到,它表示本行距离程序开始处的相对距
离.现在,你应该明白510-($-$$)表示什么意思了吧?times 510-($-$$) db 0 表示将0 这个
字节重复510-($-$$)遍,也就是在剩下的空间中不停地填充0,直到程序有510B 为止.
这样,加上结束标志0xAA55 占用的2B,恰好是512B.

1.5 水面下的冰山

    即便是非常袖珍的程序,也有可能遇到不能正确运行的情况,对此你一定并不惊讶,
谁都可能少写一个标点,或者在一个小小的逻辑问题上犯迷糊.好在我们可以调试,通
过调试,可以发现错误,让程序日臻完美.但是对于操作系统这样的特殊程序,我们没
有办法用普通的调试工具来调试.可是,哪怕一个小小的Boot Sector,我们也没有十足
的把握一次就写好,那么,遇到不能正确运行的时候该怎么办呢?在屏幕上没有看到我
们所要的东西,甚至于机器一下子重启了,你该如何是好呢?

    每一个问题都是一把锁,你要相信,世界上一定存在一把钥匙可以打开这把锁.你
也一定能找到这把钥匙.

    一个引导扇区代码可能只有20 行,如果Copy&Paste 的话,10 秒钟就搞定了,即便
自己敲键盘抄一遍下来,也用不了10 分钟.可是,在遇到一个问题时,如果不小心犯了
小错,自己到运行时才发现,你可能不得不花费10 个10 分钟甚至更长时间来解决它.
笔者把这20 行的程序称做水面以上的冰山,而把你花了数小时的时间做的工作称做水面
下的冰山.

    古人云:“授之以鱼,不如授之以渔.”本书将努力将冰山下的部分展示给读者.这
些都是笔者经历了痛苦的摸索后的一些心得,这些方法可能不是最好的,但至少可以给
你提供一个参考.

    好了,以Boot Sector 为例,你可以想像得到,将来我们一定会对这20 行进行扩充,
最后得到200 行甚至更多的代码,我们总得想一个办法,让它调试起来容易一些.其实
很容易,我们只要把“org 07c00h”这一行改成“org 0100h”就可以编译成一个.COM
文件让它在DOS 下运行了.我们来试一试,首先把07c00h 改成0100h,编译:

    nasm boot.asm –o boot.com

    好了,一个易于执行和调试的Boot Sector 就制作完毕了.调试.COM 文件可能让你
仿佛一下子回到了20 世纪,没关系,怀旧一下感觉还是蛮不错的.
Turbo Debugger 是一个不错的调试工具,“图形化”界面,全屏操作,用起来感觉和
一个“严重”精简后的Windows 差不多☺.
    调试完之后要放到软盘上进行试验,我们需要再把0100h 改成07c00h,这样改来改
去比较麻烦,好在强大的NASM 给我们提供了预编译宏,把原来的“org 07c00h”一行
变成许多行即可:

代码1-2 节自\chapter1\b\boot.asm
-------------------------------------------------------------------
;%define _BOOT_DEBUG_ ; 做 Boot Sector 时一定将此行注释掉!
; 将此行打开后用 nasm Boot.asm -o Boot.com
; 做成一个.COM 文件易于调试
%ifdef _BOOT_DEBUG_
org 0100h ; 调试状态,做成 .COM 文件,可调试
%else
org 07c00h ; Boot 状态,BIOS 将把 Boot Sector 加载到 0:7C00
; 处并开始执行
%endif
-------------------------------------------------------------------

    这样一来,如果我们想要调试,就让第一行有效,想要做Boot Sector 时,将它注释
掉就可以了.
    这里的预编译命令跟C 差不多,就不用多解释了.
至此,你不但已经学会了如何写一个简单的引导扇区,更具备了扩充它的条件——
知道如何排错,如何调试.这就好比从石器时代走到了铁器时代,宽阔的道路展现在眼
前,运用工具,你无所不能.

    如果说开始我们还是在黑暗中摸索,到现在为止,我们至少已经看到了光亮,我们
有信心将Boot Sector 进行不断扩充,让它变成一个真正的操作系统的一部分.

1.6 回顾

    让我们再回过头看看刚才那段代码吧,大部分代码你一定已经读懂了.如果你还是
一个NASM 新手,可能并不是对所有的细节都那么清晰.但是,毕竟你已经发现,原来
可以如此容易地迈出写操作系统的第一步.

    是啊,这是个并不十分困难的开头,如果你也这样认为,就请带上百倍的信心,以
及一直以来想要探索OS 奥秘的热情,随我一起出发吧!
上传的附件:
2007-4-17 22:33
0
雪    币: 200
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢分享,有时间我也试试!
2007-4-18 08:05
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
看不懂啊.大哥们.!有人愿意收徒弟的吗?
2007-4-18 09:08
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
5
这书好象挺有趣的。。。不过面向的似乎不是新手。。。用的MASM。。
2007-4-18 10:07
0
雪    币: 188
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zyn
6
这个有电子书吗?放出来吧。。。。期待中。。。。
2007-4-18 10:23
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
电子版有,但是很不清楚,下了之后就一直没看了
2007-4-18 10:39
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
这本书我在书店里看见过,,当时没有没有仔细看内容,,
2007-4-18 11:01
0
雪    币: 1334
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
这本书如果出版於50年前,到不失为一部好书.但是在今天有啥意义?
2007-4-18 11:06
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
谢谢分享!太感谢了!刚入这个行业!还请高手多多指点!~~~下载下来试一下!
2007-4-18 11:10
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
11
呵呵
与我现在看的卢军的一本<<Linux0.01内核分析与操作系统设计>>第二章是差不多的
不错不错
对于技术爱好者来说
值得一看
2007-4-18 15:26
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
电子书太大 PDF图片版  看不清楚 传不上 还是慢慢的粘好了
2007-4-18 15:54
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
50年前出了更没法看了 虚拟机也没 NASM也没 ....作者也没出生..........作者的妈妈还在背99乘法表.....
2007-4-18 15:58
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
谢谢分享!!
2007-4-18 17:15
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
这上面写的好象不是给我们一般的菜鸟学的哦,有点难啊
2007-4-18 17:31
0
雪    币: 164
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
16
作为了解编程机制,对于破解都有帮助,应该看看!
2007-4-18 17:49
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
第2章这里有 http://www.dearbook.com.cn/WebResource.aspx?id=13123

我就从第3章开始写了

                                  为了追求速度  可能会偶尔有几个错别字.....

                         第3章

                 保护模式 (Protect Mode)

        学而不思则X(这字不会打 以后不会打的字用X代替),思而不学则怠.

                                                           -----啊孔

    或许你从来没有接触过保护模式这个概念,如果真的是在合阳,请不要害怕,这个

概念不容易用定义解释清楚,胆囊市如果读者怀着对它的好奇和疑问读下面的章节,在获得了一定

感性的知认识之后,回看到眼前的迷雾渐渐散去,并最终很好地理解他。而且,本书也会不断和读

者一起来体会这个概念中“保护”一次的内在含义,在“学”和“思”中不断前行。

3.1 认识保护模式

    很多时候,我觉得自己是懒惰和急功近利的,在学习新东西的时候不肯花时间阅读大段概念性的叙述。我认为那是给已经明白了的人看的,当我也懂了的时候,可能能弄清楚作者在说些申明,可当我初学的时候,我真的不太喜欢泛泛的介绍 我想尽快看到些吸引研究的东西。

说不定,你也有这样的想法。
  那好,在你不知道什么叫保护模式之前,让我们先来看一段代码,如果你没有接触过这些内容,

可能会觉得一头雾水,不知所云,不要紧,这正是我们想要的效果---在好奇心的驱使下,人总是很

勤劳

代码是这样的:

               代码3-1

; ==========================================
; pmtest1.asm
; 编译方法:nasm pmtest1.asm -o pmtest1.com
; ==========================================

%include	"pm.inc"	; 常量, 宏, 以及一些说明

org	0100h
	jmp	LABEL_BEGIN

[SECTION .gdt]
; GDT
;                                         段基址,      段界限     , 属性
LABEL_GDT:		Descriptor	       0,                0, 0     		; 空描述符
LABEL_DESC_CODE32:	Descriptor	       0, SegCode32Len - 1, DA_C + DA_32	; 非一致代码段, 32
LABEL_DESC_VIDEO:	Descriptor	 0B8000h,           0ffffh, DA_DRW		; 显存首地址
; GDT 结束

GdtLen		equ	$ - LABEL_GDT	; GDT长度
GdtPtr		dw	GdtLen - 1	; GDT界限
		dd	0		; GDT基地址

; GDT 选择子
SelectorCode32		equ	LABEL_DESC_CODE32	- LABEL_GDT
SelectorVideo		equ	LABEL_DESC_VIDEO	- LABEL_GDT
; END of [SECTION .gdt]

[SECTION .s16]
[BITS	16]
LABEL_BEGIN:
	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	mov	ss, ax
	mov	sp, 0100h

	; 初始化 32 位代码段描述符
	xor	eax, eax
	mov	ax, cs
	shl	eax, 4
	add	eax, LABEL_SEG_CODE32
	mov	word [LABEL_DESC_CODE32 + 2], ax
	shr	eax, 16
	mov	byte [LABEL_DESC_CODE32 + 4], al
	mov	byte [LABEL_DESC_CODE32 + 7], ah

	; 为加载 GDTR 作准备
	xor	eax, eax
	mov	ax, ds
	shl	eax, 4
	add	eax, LABEL_GDT		; eax <- gdt 基地址
	mov	dword [GdtPtr + 2], eax	; [GdtPtr + 2] <- gdt 基地址

	; 加载 GDTR
	lgdt	[GdtPtr]

	; 关中断
	cli

	; 打开地址线A20
	in	al, 92h
	or	al, 00000010b
	out	92h, al

	; 准备切换到保护模式
	mov	eax, cr0
	or	eax, 1
	mov	cr0, eax

	; 真正进入保护模式
	jmp	dword SelectorCode32:0	; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0  处
; END of [SECTION .s16]


[SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS	32]

LABEL_SEG_CODE32:
	mov	ax, SelectorVideo
	mov	gs, ax			; 视频段选择子(目的)

	mov	edi, (80 * 10 + 0) * 2	; 屏幕第 10 行, 第 0 列。
	mov	ah, 0Ch			; 0000: 黑底    1100: 红字
	mov	al, 'P'
	mov	[gs:edi], ax

	; 到此停止
	jmp	$

SegCode32Len	equ	$ - LABEL_SEG_CODE32
; END of [SECTION .s32]


如果你是第一次读到这里,不晓得你对这段代码有怎样的感觉,肯呢感对开头几巷的耐心到
了第2页就消失得差不多了,然后很快的翻业,很段的时间后,你已经到达代码的末尾,恩,
可能他显得的确有点灰色。首先说明的是,这段代码将实现由实模式到保护模式的转换。至于保护
模式和X模式的概念以及区别,我们之后再做详细解释,现在,先让我们把这段过一变,分别看一下它的三过部分。

你肯呢感主义到了,在开头处的注视中,这个程序被变异成了。COM文件,最简单的二进制文件。这以为着,程序执行时
的内存XX和二进制文件XX是一样的。所以,在上面的程序中定义的secion并没有什么实质上的作用,但即便不定义他们,从执行结果来可那也是一样的(变异出来的2进制会有微笑差别0)。定义他们只是使代码结构上比较清晰,而且,后面我们对这个程序渐渐扩展的时候,他还有一点小小的妙用

好了,首先说说[SECTION.GDT]这个段 其中的Descriptor是在pm.inc中定义的红

pm.inc  代码 3-2
;
; 描述符
; usage: Descriptor Base, Limit, Attr
;        Base:  dd
;        Limit: dd (low 20 bits available)
;        Attr:  dw (lower 4 bits of higher byte are always 0)
%macro Descriptor 3
	dw	%2 & 0FFFFh				; 段界限 1				(2 字节)
	dw	%1 & 0FFFFh				; 段基址 1				(2 字节)
	db	(%1 >> 16) & 0FFh			; 段基址 2				(1 字节)
	dw	((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)	; 属性 1 + 段界限 2 + 属性 2		(2 字节)
	db	(%1 >> 24) & 0FFh			; 段基址 3				(1 字节)
%endmacro ; 共 8 字节


先不要管具体的意义是什么,看字面我们可以知道,这个红表示的不是一段代码,而是一个数据结构,他的大小是8字节

在段[SECTION.gdt]中并列有3个Des什么什么tor,看上去是个结构数组,你一定猜到了这个数组的名字叫GDT

GDTLEN是GDT的长度 GDTPTR也是个小的数据结构,他有6字接 前2字接是GDT的界限 后4字接是GDT的基地质

另外 还定义了两个形如SELECXXXXXXXXXXXXXXXXXXXXXXXXXXXXX的常量 ,至于是做事业很么用的,,我们暂且不管它。
再往下到了一个代码段,BTS 16 明确地指明了他是一个16位代码段。你会发现 这短程序修改了一些GDT中的值

然后执行了一些不常见的指令,最后通过jmp指令实现一个跳转

      jmp Seletxxxxcode32:0

正如代码注视中所说的,这一句将“真正进入保护模式”。实际上,他将跳转到第3个SECTION,及{XXXXX.s32}中,这个段是32位的

执行最后一小段代码,。这段代码看上去是往某个地质处写如了2字节 然后进入无限循环

   瑞染我门还位能了解更多细节,但我猜 你一定在想这段程序的执行结果会是怎样的 让我们先来看一下

                             暂时没有图片!!!!!!!!!

可以看到 程序打印了一个红色的自负P 然后再什么也不动了不难猜到 程序的最后一部分代码中写入的亮字节是写进了现存中

  现在 大致感性认识已经有了 但你一定有一些疑惑 什么是GDT 那些看是行去怪怪的指令到底在做什么  现在我们先来总结一下

在这个程序中我们哦了解什么有哪些疑问

我们了解到的内容如下:

·程序定义了一个叫做GDT的数据结构
·后面的16位代码进行了一些与GDT有关的操作
·程序最后跳到32位代码中做了一点操作显存的工作。
我们不明就里的内容如下
·GDT是啥破玩意  干啥用的
·程序对GDT干了啥
·那个jmp S什么什么code32:0 跟我们从前用的jmp有杀不同

好的 现在就让我们出发 一起走进保护模式

---------------------节 3.1  完-------------------------------------
2007-4-18 20:00
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
看不懂啊.大哥们.!谢谢分享!
2007-4-18 21:33
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
你的说法不对,如果明天你也可能做出自己的系统不好吗!不用看别人脸色。
2007-4-20 21:20
0
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
20
我开始学习~
2007-4-20 21:31
0
雪    币: 235
活跃值: (29)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
21
邪恶八进制有 以前看了些
2007-4-20 22:24
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
偶像,我都不敢想象把一本书全部手工贴出来
2007-4-21 13:27
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
看不懂啊,刚入这个行业,还请高手多多指点.
2007-4-21 17:23
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
不敢想象把一本书全部手工贴出来
2007-4-21 17:29
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
25
认真看一遍intel手册应该就能写吧。。。
2007-4-21 21:29
0
游客
登录 | 注册 方可回帖
返回
//