Board logo

标题: 【Billunique】个人网志-滴水汇海 [打印本页]

作者: Billunique     时间: 2007-4-6 03:12    标题: 【Billunique】个人网志-滴水汇海

受Redtek网志的熏陶和蛊惑~

心痒痒、恶狠狠也来开辟我的学习网志!

希望把自己的学习足迹记录下来,当回头看的时候,可以感受自己一点一滴的进步!

[ Last edited by Billunique on 2007-4-9 at 08:00 AM ]
作者: Billunique     时间: 2007-4-6 03:23
先把这篇链接过来,作为开篇~:)

http://www.cn-dos.net/forum/view ... light=%2BBillunique

[ Last edited by Billunique on 2007-4-6 at 03:28 AM ]
作者: Billunique     时间: 2007-4-6 04:06
★《Windows98/2000/XP/2003 DOS命令实用大全》-希望图书工作室

☆CON这个文件名指的是控制台(CONsole),所谓控制台就是用户与计算机交谈联系的终端,在PC上就是指屏幕与键盘。CON这个文件若作“输入”用指的就是“键盘”,若作“输出”用就是指“屏幕”。

 由于CON被当成文件看待(有点类似Unix啊呵),因此可以用Copy将CON所输入的数据与文件连接起来(适用于想向文件作简单内容添加的时候):
A:\>copy con 1.txt
line1
^Z
1 files(s) copied

A:\>copy 1.txt+con temp
1.txt
con
line2
^Z
1 file(s) copied

A:\>tpye temp
line1
line2
☆用Copy连接多个文件时,拷贝的目标文件只取各源文件中Ctrl+Z键之前的代码。(在Notepad中,这一代码是隐含的,文本末尾的光标在什么地方,Ctrl+Z标记就在什么地方)

 Copy+的机制:先用源文件队列中的第一个文件覆盖目标文件(没有则创建),然后依次将队列里其他成员的内容往这个目标文件里添加。于是乎,如果源列表里有含有与目标文件重名的文件,则这一文件的内容将不被拷入------因为之前它的内容已经被源列表里的第一个文件“挤”出去了,挤完之后再去读,伊人已非她也。(也就是通常说的Copy会忽略这一文件的原因)

[ Last edited by Billunique on 2007-4-7 at 11:41 PM ]
作者: Billunique     时间: 2007-4-6 05:55
利用环境变量可以在两个批处理程序间传递%变量所无法传递的数据。例如下面的Test.bat程序,它会先在当前工作目录下寻找所指定的文件,若找得到,就Type其目录数据;若找不到则调用Test2.bat,由Test2往Usr子目录去寻找并Type其内容。
C:\>type test.bat
@echo off
if not exist %1 goto find
type %1
goto end
:find
set file=usr\%1
call test2
:end
echo OK!

C:\>type test2.bat
@echo off
echo Type out now....
type %file%

C:\>type \usr\doc
This is a test file in C:\usr

----------------------
C:\>test doc
Type out now....
This is a test file in C:\usr
OK!
[ Last edited by Billunique on 2007-4-7 at 11:42 PM ]
作者: Billunique     时间: 2007-4-6 07:49
MS-DOS配置了ANSI驱动程序有什么好处呢?

  ANSI.SYS是一个以ANSI标准为规范的终端(Terminal)驱动程序。因为早期的终端控制码规则不一,在甲端使用的程序在乙端却无法使用(会使屏幕、键盘异常),这种状况在网络系统上尤为常见,因为一个网络上可能接数种厂商的终端,如果所有的终端都遵守同一标准的控制码,则程序就可以在各终端之间通用而没有差异了。

  这就是ANSI.SYS的由来,它是由美国国家标准协会提供的。当指定DOS把ANSI.SYS装入,和DOS形成一体后,MS-DOS就会遵守ANSI的控制码了。ANSI的控制码都是由一个以上的字符构成的,所以又称为控制序列。

  由于ANSI.SYS是终端控制程序,所以只要把ANSI控制码往DOS的标准输出,ANSI.SYS便可接收到该控制码,而根据控制码的指示来执行动作。那么要如何把ANSI控制序列送往输出呢?因为控制码会立即产生控制效果,所以无法在DOS的状态下直接键入控制码。

  通常是使用DOS的prompt命令来传送控制码的。因为prompt命令本身也有一些控制输出的能力,再配合ANSI.SYS的功能,就可以完成许多很有用的事情。

[ Last edited by Billunique on 2007-4-7 at 11:42 PM ]
作者: Billunique     时间: 2007-4-6 11:43
Comspec和Shell有何不同呢?
 
  Shell存放在Config.sys文件里,在启动时提供DOS命令处理器的路径名。
  而Comsepc则是启动后,存于内存中的环境变量。

  这个变量有什么作用呢?因为某些程序会把Command.com的非驻留部分破坏,所以程序结束后返回DOS时,DOS必须把命令处理器的非驻留部分重行装入,但到底命令是在哪里?叫什么名字呢?DOS并不知道,那么可以由Config.sys的命令得到。可是当前在驱动器内的软盘可能已不是启动盘(没有Config.sys这个文件)了。所以MS-DOS才设计了一个叫Comspec的环境变量,用以记住命令处理器的路径名。当DOS要重新驻入非驻留部分时,便根据Comspec的指示去找命令解释程序。

  当然,应用程序需要装入DOS命令时处理器时,也都可以根据Comspec的记载去磁盘里寻找。

[ Last edited by Billunique on 2007-4-7 at 11:43 PM ]
作者: Billunique     时间: 2007-4-6 23:21
☆ DOS提供了多重弹性的执行Config.sys文件命令的做法,让用户自己能轻易掌握更符合当前状况的Config文件,控制哪些程序不运行、哪些程序要安装,因此不但能因需求不同而迅速调整系统设置,甚至可回到最原始的配置,而且也使内存不做无谓的浪费。

  DOS6.22提供了3种方式供用户控制Config.sys文件及Autoexec.bat文件的运行:

  1.征询用户是否运行某一条Config命令----在Device前加?:Device?=C:\DOS\ANSI.SYS

  2.所有Config命令和Autoexec.bat命令均需征询用户确认----在启动时(当出现Starting MS-DOS……时马上)按F8键。(6.0版只能确认Config的运行,6.2版起则亦能控制Autoexec)在这期间,如果决定接下去的命令都不运行,可按F5键;反之也可以按Esc键以运行接下去的所有命令。

  3.完全跳过Config.sys和Autoexec.bat文件的运行,以最原始的设置启动----在启动时按F5键。由于跳过了Config.sys这个文件,所以Shell=这个命令不会被运行到。这时DOS会自动到要目录下装入Command.com文件,作为命令处理器。万一Command.com不在根目录,则DOS也会到C:\DOS这个目录下去找。万一在这个目录下还找不到,则DOS会显示以下信息:
  Bad or Missing Command Interpreter
  Enter correct name of Command Interpreter(eg, C:\COMMAN.COM)

  另外,因为Autoexec.bat也被跳过了,所以其Path命令并未被运行到。不过DOS会自行默认设置PATH=C:\DOS,至于其他目录下的程序就得另用Path命令手动指定了。
  

[ Last edited by Billunique on 2007-4-7 at 11:44 PM ]
作者: Billunique     时间: 2007-4-7 00:55
☆ 上面说的设置能在一定程序上满足用户的多重需求,但在有些时候显得比较麻烦。有没有专门为某用户或某场合定制的配置环境,可以供其在需要的时候直接加载进入呢?

  答案是有的,DOS赋予Config.sys文件另一个很好用的功能:多重的系统配置!

1.多重配置文件的结构

  多重配置文件可分为选项区(menu block)、配置区(configuration block)和公用区(common block)3大部分,其格式如下:
[Menu]
menuitem=Bill
menuitem=Gates
[Bill]
Files=40
Device=C:\Device1.sys
[Gates]
Files=10
Device=C:\Device2.sys
[Common]
Buffers=30
Install=C:\Dos\Doskey.com
  ●选项区:这是多重配置文件的开端,必须以[Menu]为起头,以Memuitem指定各配置区的名称。启动后,屏幕上会以一个启动菜单列出各配置区的名称:
MS-DOS 6.22 Startup Menu

1.Bil

2.Gates

Enter a choice:1


F5=Bypass startup files F8=Confirm each line of CONFIG...
  启动菜单中的每一项代表着一套配置,供用户选择。请注意,选项区中只能有Menuitem语句,其他的命令DOS均不会接受。
  
  ●配置区:这是真正存放Config命令的环境设置区。启动菜单中每一选项均对应到一个配置区。以上例而言,在Enter a choice之后选第1项Bill,就会跳到以[Bill]为首的配置区去运行其环境设置。

  ●公用区:每一选项除了有各自独立的配置区外,多重配置文件还设置了共同运行区,无论选择了哪一套环境设置,都要到本区来运行共用的命令。公用区以[Common]为首。

  各配置区和公用区不分前后次序可任意排列,若选项区所列的选项没有对应的配置区,则DOS会显示该行有错。

[ Last edited by Billunique on 2007-4-7 at 11:45 PM ]
作者: Billunique     时间: 2007-4-7 02:31
2.Menuitem命令

  Menuitem命令使用于选项区,此命令用来设置启动菜单所对应的配置区名称,必要时可以加上说明文字,其格式为:
  
Menuitem=BlockName[,Menu Text]
  ●BlockName:除了空格 \ / , ; = [ ]字符外,可以是任何字符,最多可达70个字符。

  ●Menuitem:此参数是可选的,主要用来说明BlockName的含义。加了这个参数后,在启动菜单上所显示的项将是Menu Text,而不是BlockName。(但选择了它仍然会跳转到其BlockName相对应的配置区,它只是更替了BlockName的显示而已)同样的,Menu Text也可达70个字符。

3.MenuDefault命令

  此命令用来设置启动菜单的预选项,必要时可加上超时(Timeout)参数。其格式如下:
  
MenuDefault=BlockName[Timeout]
  ●Timeout:等待时间。一般介于0~90s之间。当用户未做选择时,DOS会在Timeout所设的时间之后,自动运行默认的项。若未指定Timeout时间,DOS会等到用户按键做选择之后才会运行下一步骤。
  
  若在多重配置内未加入MenuDefault命令,则以第一项为预选项。

[ Last edited by Billunique on 2007-4-7 at 04:24 AM ]
作者: Billunique     时间: 2007-4-7 03:27
4.MenuColor命令

  在选项区还可以使用MenuColor命令来设置文字和背景颜色,其格式如下:
  
MenuColor=X[,Y]
  X表示文字的颜色,Y表示背景的颜色。Y与逗号之间不能有空格。X、Y为0~15之间的数值,其代表的颜色如下所示---

  0:黑色  4:红色  8:灰色   12:鲜红
  1:蓝色  5:紫红  9:鲜蓝   13:鲜紫
  2:绿色  6:棕色    10:鲜绿   14:黄色
  3:浅绿  7:白色    11:草绿       15:亮白

  如果背景色取用8~15,将造成闪烁效果,(真的会这样吗?)所以建议尽量采用0~7号颜色。使用这些颜色的设置会因ANSI.SYS的装入而还原成最原始的颜色状态。

[ Last edited by Billunique on 2007-4-7 at 03:30 AM ]
作者: Billunique     时间: 2007-4-7 04:20
好了,下面我们来看一个比较综合的例子:
[Menu]
Menuitem=first_config,First Level Configuration Only
Menuitem=second_config,Second Level Configuration
Menuitem=net_config,Normal Configuration With Network
Menudefault=fir_config,30
Menucolor=15,1

[first_config]
Buffers=10
Device=C:\DOS\Ramdrive.sys

[second_config]
Buffers=20
Device=C:\CMouse.sys

[net_config]
Buffers=30
Device=C:\DOS\Himen.sys

[Common]
Files=15
Device=C:\DOS\ANSI.sys
  运行后,屏幕会显示:
MS-DOS 6.22 Startup Menu

1.First Level Configuration only

2.Second Level Configuration

3.Normal Configuration with Network

Enter a choice:1 Time remaining:28


F5=Bypass startup files F8=Confirm each line of CONFIG...
  过30s后,自动运行1。

[ Last edited by Billunique on 2007-4-7 at 04:23 AM ]
作者: Billunique     时间: 2007-4-7 09:00
5.Submenu命令

  在选项区中,还可以使用Submenu命令将启动菜单上的项再分出子项,所以当选用该项时,屏幕上会接着显示另一串子菜单,使得选项的结构呈现树形组织。其格式是:
Submenu=BlockName[,Menu Text]
  
  参数BlockName与MenuText和Memuitem命令的参数含义完全相同。
[Menu]
Menuitem=Ordinary
Menuitem=Special
Submenu=Combination

[Combination]
Menuitem=Text_Proc
Menuitem=Image_Proc
  
[Ordinary]
……
[Special]
……
[Text_Proc]
……
[Image_Proc]
……
  运行后,屏幕上显示:
MS-DOS 6.22 Startup Menu

1.Ordinary

2.Special

3.Combination

Enter a choice:3

F5=Bypass startup files F8=Confirm each line of CONFIG...
  如果选择第3项Combination,则会出现以下屏幕:
MS-DOS 6.22 Startup Menu

1.Text_Proc

2.Image_Proc

Enter a choice:1

F5=Bypass startup files F8=Confirm each line of CONFIG...
[ Last edited by Billunique on 2007-4-7 at 09:04 AM ]
作者: Billunique     时间: 2007-4-7 12:18
6.Include命令

  Include命令适用于配置区,当配置区欲使用到和其他配置相同的设置时,可以用此命令将其他配置区的内容包括进来(Include)进来,以避免重复编写。其格式如下:
Include=BlockName
  ●BlockName:并不限定在之前或之后,只要在文件内即可。

  现在再来一个相对完整的例子:
[Menu]
Menuitem=Old_Proc,Old version Operation
Menuitem=Reg_Proc,Regular Operation
Menuitem=Dbase_Proc,Data Base Operation

[Common]
device=c:\dos\himen.sys
device=c:\dos\emm386.exe noems(?)
dos=high,umb(?)
shell=c:\dos\command.com c:\dos /p(?)

[Old_Proc]
device=c:\dos\setver.exe
include=Reg_Proc

[Reg_Proc]
buffers=30
files=30

[Dbase_Proc]
device=c:\dos\ramdrive.sys 384,128,16/E(?)
lastdrive=E
buffers=30
files=20
  ●MS-DOS Config文件内的运行顺序是:

  1)DOS=High与DOS=UMB先运行,这二者按排列顺序先后来运行。若此时Himen.sys或Emm386.exe尚未运行,则DOS会先保留,等Himen.sys或Emm386.exe装入后,便立即运行DOS=High和DOS=UMB。
  2)接下来运行的是Device、Files、Buffers…DeviceHigh、Shell等Config命令,各命令根据排列次序运行。
  3)最后运行的是Install命令。

  上列命令分散于多个配置区,则DOS会等用户做完配置区选择之后,将所选的配置区和Command区内的Config命令集中起来,再根据上列1、2、3的顺序运行。

[ Last edited by Billunique on 2007-4-7 at 12:26 PM ]
作者: Billunique     时间: 2007-4-7 23:37
多重配置的Autoexec.bat

  使用多重配置时,DOS会建立一个专用的环境变量Config,以记载当前运行的是哪一个配置区。可以根据这个环境变量,来制作多重的Autoexec.bat文件,使得每一套配置,均能对应到分别的批处理文件。如此将使每一套系统的配置更加个性化,不会和其他系统配置相互干涉。

  如何制作多重的Autoexec.bat文件呢?可以使用Goto命令,再配合环境变量Config来运行其对应的部分。

  下面是专为呼应前例多重配置文件而编写的的Autoexec.bat文件:
@echo off
path c:\dos; c:\windows; c:\pctools8; c:\et31
prompt $p $g

goto %config%          rem 记载当前运行的配置区名称(BlockName)

:Old_Proc
msav
goto End

:Reg_Proc
doskey
smartdrv
goto End

:Dbase_Proc
call et31
append c:\dbf
goto End

:End
[ Last edited by Billunique on 2007-4-7 at 11:46 PM ]
作者: Billunique     时间: 2007-4-8 07:12
CPU的寻址能力

  寻址能力就是CPU能存取到的地址空间,也就是CPU地址线所能组合出来的地址数。CPU利用地址线来选定内存的地址。因为每一条地址线有0和1两种状态。所以n条地址线可以选到2的n次方个地址。

  以下是80x86系列CPU的寻址能力:


以下引用自Redtek:)

  Quote:
  5、8080、8088、80286、80386地址总线宽度分别为16、20、24、32根,它们寻址能力为_KB、_MB、_MB、_GB。

    答:8080  为:64KB
      8088    为:1MB
      80286  为:16MB
      80386  为:4GB

  6、8080 8088 8086 80286 80386的数据总线宽度为8 8 16 16 32根,则它们一次可以传送的数据分别为多少B?

    答:8080  为:256B
      8088  为:256B
      8086  为:65536B
      80286 为:65536B
      80386 为:4294967296B



[ Last edited by Billunique on 2007-4-8 at 07:14 AM ]
作者: Billunique     时间: 2007-4-8 07:51
PC机上的内存(RAM)可分为4类:

1.传统内存

  传统内存的地址空间是位于0KB~640KB之间。不论使用哪一种类型的CPU,从8086到486,传统内存都是必需的。它是MS-DOS运行程序最重要的舞台。

2.保留内存

  由于MS-DOS最初是为8086/8088 CPU设计的操作系统,最多只能使用1MB的内存。这1MB内存最前面的640KB就是前述的传统内存;至于后面剩下的384KB,则保留给BIOS ROM、硬件接口卡(如VGA卡、硬盘控制卡)上的ROM与VidelBuffer使用。

  保留内存(Reserved Memory)的地址空间位于640KB~1024KB之间,是保留给外部使用的地址空间。保留内存其实不应该称为内存,应该称为保留内存空间,因为在此空间内并未安装实体的RAM。

  在保留内存的384KB地址空间内,除了由视频缓冲区、BIOS ROM和其他硬件扩充卡所使用之外,仍有许多空隙。可运用386/486的分页(paging)能力,将扩展内存映射过来填补这些空隙,因为这些空隙还在DOS的1MB范围之内。(以往是因为没有安插内存,所以才无法使用,现在以分页技术配置好内存之后,便成为可供DOS使用的内存了---这句其实不太明白)我们称这些在640KB以上地址的内存为“上位内存(Upper Memory)”,上位内存可能因外部卡的安装而被分成几个块,所以又称为上位内存块(Upper Memory Blocks)简称UMB。

3.扩展内存

  扩展内存(Extended Memory)是指位于1024KB以后的内存。对于我们的内存RAM,扣除640KB的传统内存,其余全部都是扩展内存。

  虽然从计算机主机板上看,所有的RAM都排列在一起,但事实上,超过640KB传统内存以外的RAM,其安插的位置是跳过384KB的保留内存而往1MB以后的空间再延续下去。(在640KB~1024KB的区间是没有RAM存在的)[?这两段合着是说,假如我有2M的RAM,事实上是占有(2M+384KB)的空间呢,还是说号称2M其实真实容量是(2M-384KB)----因为有384KB的空间位置是虚的?]

  由于MS-DOS本来只能管理1MB以内内存,而保留内存内又没有实体RAM,所以只有传统内存才是MS-DOS的“管辖区”。必须通过286/386/486的保护模式,才可以使用高于1024KB地址的内存。

  (1)HMA
  
  在1MB以后的第一个64KB(1024~1088KB)的扩展内存,我们称为HMA(High Memory Area)。

  80286以上的CPU,由于地址线超过20条,可以很巧妙地使DOS获得额外的64KB使用空间。其关键在于CPU是否将A20地址线打开(设为ON)。所以在286以上的计算机上,将A20地址一律设为ON,就可以获得这额外的64KB内存,这也就是HMA的所在。

  (2)XMM  
  
  如前所述,MS-DOS的管不到扩展内存的,为了有效地利用扩展内存,程序应该通过“管理程序”来统一运用扩展内存。此种管理程序就称为扩展内存管理程序(XMM,extended Memory Manager)。

  (3)XMS(extended Memory Specification)

  为了能有共同的“管理规则”,Lotus/Intel/Microsoft/AST4家公司提出了所谓的XMS规则。MS-DOS提供的Himen.sys程序,就是一个符合这一规则的扩展内存管理程序。

4.扩充内存

  以扩充内存槽加插内存而扩充出来的内存称为“扩充内存”(Expanded Memory)。它不像扩展内存线性地排列在1MB之后,而是独立于一旁。Lotus/Intel/Mircosoft3家公司共同提出了所谓的LIM/EMS(~Specification)规范。依据LIMEMS的规定,程序必须通过页帧(Page Frame)的映射,才能对扩充内存进行数据的存取。不像其他的内存可以直接根据地址来存取数据,所以速度较慢。(这块完全没有概念,难道现在第二个插槽的内存都属于扩充内存?#_#)
  
  

[ Last edited by Billunique on 2007-4-9 at 08:01 AM ]
作者: Billunique     时间: 2007-4-9 08:33
关于Format(其实基础的东西需要了解的还很多):

  Format命令的用途主要是将磁盘格式化,以建立磁道、扇区的构造,并且会在磁盘上建立启动扇区(Boot Sector)、根目录(Root)以及FAT表(File Allocation Table),用以管理磁盘的文件。

  早期版本的Format做格式化时,会把扇区里的数据完全清除。但从DOS5.0版起的Format,默认采用了“非破坏性”的方式。

  它并不会将磁盘上原有的数据完全消除。事实上,做完非破坏性格式化后,原有数据还是存在磁盘上,只有启动扇区、根目录和FAT更新而已。由于启动扇区、根目录和FAT记载的是硬盘的使用状态,所以更新之后,表面看起来像是全新的空磁盘,DIR时什么也看不到,但事实上硬盘的原数据还是存在的。这就是我们能将磁盘数据救回来的真正原因!

  非破坏性的格式化会在磁盘里建立“隐藏性”的文件,叫“Mirror映像文件”,以保存原来的启动扇区、FAT和根目录等“与磁盘系统有关的”数据,以备Unformat时使用。

  建好隐藏性的映像文件后,Format便开始建立新的启动扇区、空白的FAT与根目录,至于其他扇区,则只做检查(Verify)而不改变扇区的内容。由于原来的启动扇区、FAT、根目录都被保存起来了,而所有的文件、子目录则未予更动,所以非破坏格式化之后,若立即运行Unformat命令,便可将数据完整地恢复出来。所以“非破坏性”的格式化也就是“可恢复的”格式化。

  当Format发现原磁盘所剩空间不足以建立Mirror映像文件,即存放启动扇区、FAT和根目录数据的时候(基本上针对软盘了,^_^),就会询问用户是否要运行破坏性的格式化。

  Format默认是非破坏性的,如果用户自己需要破坏性格式化,则可以给Format指定/U参数。

  如果使用了/S参数,则Format完成非破坏性格式化后要将系统文件写入软盘时,会避开该软盘里原来的数据,而若原来的数据太多,使得系统文件写入后势必盖掉一些原来的数据扇区,这时候就会显示信息询问用户是否仍要将系统文件写入。(WARNING:This disk cannot be unformatted if system files are transferred.Proceed with system transfer anyway(Y/N)?)

  注:如果连续做两次非破坏性格式化,就不能用Unformat恢复原状了,因为在做第二次的时候,Mirror里保存的数据会是“当时”的,也就是硬盘状态为未使用时的记录。这样的话,恢复后就会得到一个空的FAT和根目录。

  如果使用/Q参数,会略过“检查扇区”的步骤。换言之,就是“简化”的非破坏性格式化,所以运行速度很快。(如果确信硬盘没问题,完全可以加上这一参数,加快格式化速度)

  如果使用/Q/U组合,则原来的启动扇区、FAT和根目录不会被保存,而会直接重建,至于其他扇区则既不被破坏,也不被检查。换言之,就是“简化”的破坏性格式化。

[ Last edited by Billunique on 2007-4-10 at 03:07 AM ]
作者: Billunique     时间: 2007-4-10 06:27
80x86的地址表示法:

  当一个程序运行时,其内存空间的分布可以分为:程序区、数据区以及堆栈区。其中,程序区存放程序码以供CPU来读取、运行,数据区存放被处理的数据,而堆栈区则作为程序中断或调用子程序时的数据及返回地址的缓冲区。

  早期8088CPU的内部寄存器只有16位。这些寄存器是AX、BX、CX、DX、BP、IP、SP、SI、DI、CS、DS、ES、SS及FLAG,共14个。后来的80x86系列虽然已有更多的改良,但仍保持8088的基本模式。

  前列的14个寄存器组中,有一个寄存器叫指令寄存器(Instruction Pointer,简称IP)当程序运行时,IP会指向程序的起始地址,然后CPU便往IP所指的地址上读取指令。接着IP自动指向下一指令的地址,以便继续运行下一指令。
  
  IP只有16位,只能定义出2的16次方即65536个字节,又如何能定出1M字节的内存地址呢?IP岂不是还差4个位才能定出1MB的内存地址?80x86是如何来补足这4个位的呢?为了解决这个问题,80x86是以两个16位的寄存器来组合出一个20位的地址的。80x86有4个16位寄存器叫段寄存器(Segment Pointer):CS、DS、ES、SS,将其中的CS指示器与IP相配合,就可以构成20个位来定出1MB的空间。

  也就是说,80x86将段指示器的值看到20个定址位的后16位,即b4~b19(由b0算起),而将IP的值看成是20位地址的前16位,即b0~b15,将这两个寄存器错开4个位相加后就建立一个20位的位数组,CPU将此20位送往地址线就可以定出1M的地址了。

  以986895这个地址而言,其16进制表示为F0F0F,可以将段指示器设为F0F0,而IP设为000F,二者错开4个位(即1个16进制位)相加后就是F0F0F了。
  
  一个地址是由5位的16进制表示的,但为了要指出其段指示器与IP的组成内容,可以直接列出此二寄存器的值,而以冒号来分隔。Debug程序就是以这种方式来表示地址的。称段指示器CS的值为段地址,而程序指示器IP的值为段内地址。

  虽然F0F0:0000F组合成的地址是F0F0F,但F0F0F不一定是由F0F0:000F组合成的,它可能由F000:0F0F或F001:0EFF等非常多的方式组成,除非查出寄存器真正的内含值,否则无法断言一个地址是由什么样的两个值组成的。

[ Last edited by Billunique on 2007-4-26 at 03:44 AM ]
作者: Billunique     时间: 2007-4-10 07:05
Debug浅尝(等有好书后再研究):

A(汇编)

  直接将8086/8088记忆码合并到内存。
  该命令从汇编语言语句创建可执行的机器码。所以数值都是十六进制格式,必须按一到四个字符输入这些数值。在引用的操作码前指定前缀记忆码。

C(比较)

  比较内存的两个部分。

D(转储)
  
  显示一定范围内存地址的内容。

E(键入)

  将数据输入到内存中指定的地址。
  可以按十六进制或ASCII格式键入数据。任何以前存储在指定位置的数据全部丢失。

F(填充)

  使用指定的值填充指定内存区域中的地址。
  可以指定十六进制或ASCII格式表示的数据。任何以前存储在指定位置的数据将会丢失。

G(转向)

  运行当前在内存中的程序。

H(十六进制)

  对指定的两个参数执行十六进制运算。

I(输入)

  从指定的端口读取并显示一个字节值。

L(加载)

  将某个文件或特定磁盘扇区的内容加载到内存。

M(移动)

  将一个内存块中的内容复制到另一个内存块中。

N(名称)

  指定Debug I或W命令的可执行文件的名称,或者指定正在调试的可执行文件的参数。

O(输出)

  将字节值发送到指定端口。

P(执行)

  执行循环、重复的字符串指令、软件中断或子例程;或通过任何其他指令跟踪。

Q(退出)

  停止Debug会话,不保存当前测试的文件。

R(寄存器)

  显示或改变一个或多个CPU寄存器的内容。

S(搜索)

  在某个地址范围搜索一个或多个字节值的模式。

T(跟踪)

  执行一条指令,并显示所有注册的内容、所有标志的状态和所执行指令的解码形式。

U(反汇编)

  反汇编字节并显示相应的原语句,其中包括地址和字节值。反汇编代码看起来像已汇编文件的列表。

W(写入)

  将文件或特定分区写入磁盘。

XA(分配扩展内存)

  分配扩展内存的指定页面数。
  要使用扩展内存,必须安装符合4.0版的Lotus/Intel/Microsoft扩展内存规范的扩展内存设备驱动程序。

XD(释放扩展内存)

  释放指向扩展内存的句柄。

XM(映射扩展内存页)

  将属于指定句柄的扩展内存逻辑页映射到扩展内存的物理页。

XS(显示扩展内存状态)

  显示有关扩展内存状态的信息。

  (云里雾里的,忍了

[ Last edited by Billunique on 2007-4-10 at 07:29 AM ]
附件 1: Debugh.jpg (2007-4-10 07:05, 32.25 K,下载次数: 4)



作者: Billunique     时间: 2007-4-10 10:10
网络管理命令(Some):

远程登录--Telnet

  远程登录就是将本地计算机作为远程主机上的一个终端使用。目前使用最多的BBS系统。简单地讲,远程登录就是在本地计算机上键入的所有命令,并不是在本地机上执行,而是在远程主机上执行。就好像本地计算机的键盘与显示器直接连到了远程主机上。这样,从远程终端就可以直接管理服务器,给网络管理与测试带来很大的方便。

  要想使用Telnet远程登录,远程主机必须先启动Telnet服务,并设置好相应的参数与环境变量;另外,Telnet是一个基于TCP/IP协议的程序,所以本地计算机首先要配置好TCP/IP协议。

显示和修改本地ARP列表--ARP

  ARP(Address Resolution Protocol)是负责将IP地址解析成MAC地址的协议,对于网络中的高层应用程序,网络主机之间的通信是靠IP地址来完成的,但在TCP/IP协议的最底层,主机之间的交换则是通过MAC地址来定位的。每台装网卡的主机中都有一个ARP表,保存着同一网络中IP到MAC之间的映射记录。ARP表并不是一成不变的,大约每两分钟更新一次,这种记录称为动态式(Dynamic)记录。还有一种称为静态记录,也就是表中的记录不变,直到TCP/IP协议重启后才会消失。

  -a 通过询问TCP/IP显示当前ARP项。可指定特定IP。
  -d 删除由特定IP指定的项。
  -s 在ARP缓存中添加项,将IP地址和物理地址相关联。在“租期”到了之后,项自动从缓存中删除。

  ARP在添加静态记录之前,必须有一个MAC寻址的过程。当一个TCP/IP的包要发出时,会先查看本机ARP表中的记录是否有该IP的记录。如果有,则直接转换成该IP对应的MAC;如果没有,则将发一个ARP Request广播封包向对方查询MAC地址。这个广播包会被同一子网内的所有主机收到。但只有与该IP相同的主机接收,并回答一个ARP APPLY封包,该包有相应IP与MAC的信息,这样就可以找到相应主机的MAC地址了。

  在ARP表中的记录一般是动态的,大约每两分钟刷新一次。如果本地有频繁的IP要访问时,比如网关、伺服器、路由器等,为了减少发送ARP Request广播包,可以在ARP表中创建静态记录。

显示和修改本地路由表命令--Route

  大多数主机都驻留在只连接一台路由器的网段上,因此不存在使用哪一台路由器将数据包发送到远程计算机的问题。该路由器的IP地址即是该网段上所有计算机的缺省网关。但是,当网络上拥有两个或多个路由器时,就不一定只依赖默认网关了。可以让某些远程IP地址通过某个特定的路由器来传递,而其他的远程IP通过另一个路由器来传递。这时,需要相应的路由信息,这些信息存储在路由表中,每个主机和每个路由器都配有自己独一无二的路由表。大多数路由器使用专门的路由协议来交换和动态更新路由器之间的路由表。但在有些情况下,必须手动将项目添加到路由器和主机上的路由表中。这时就要用到Route命令,它用于显示、人工添加和修改路由表项目。(具体先不管了,以后再说,毕竟现在主要学习DOS,而非NT改进命令。

[ Last edited by Billunique on 2007-4-10 at 10:47 AM ]
作者: Billunique     时间: 2007-4-11 04:57
网络测试命令(some):

显示NetBIOS协议的统计资料命令--Nbtstat

  Nbtstat命令用于显示本地计算机和远程计算机的基于TCP/IP协议的NetBIOS统计资料、NetBIOS名称表和NetBIOS名称缓存。Nbtstat可以刷新NetBIOS名称缓存和注册的Windows Internet名称服务(WINS)名称。

  NetBIOS(Network Basic Input Output System,网络基本输入输出系统)是局域网(LAN)上的程序可以使用的API,几乎所有的局域网计算机都是在NetBIOS基础上工作的。NetBIOS为程序提供了请求低级服务的统一的命令集,这些服务是管理名称、执行会话和在网络节点之间发送数据包所要求的。

显示网络连接信息--Netstat

  在服务器与网络的管理中,需要经常查看服务器所开放的端口、当前的所有连接,以便随时了解网络状态。这时就要使用Netstat命令。该命令可以让管理员轻松查看计算机系统服务是否正常,是否被“黑客”留下后门、木马等。Netstat同时也是一个实时的入侵检测工具,可以随时查看是否有不正常的连接。

  Netstat命令用于显示活动的TCP连接、计算机侦听端口、以太网统计信息、IP路由表、IPv4统计信息(对于IP、ICMP、TCP和UDP协议)以及IPv6统计信息(对于IPv6、ICMPv6通过IPv6的TCP及通过IPv6的UDP协议)。

数据包跟踪诊断--Tracert

  当数据包从本地计算机经过多个网关传送到目的地时,它寻找一条具体路径来传送,每次传送数据包,不能保证或认为总遵循唯一的一条路径。那么如何知道发送的数据包所经过的路径呢?这时就要用到Tracert命令。它同样是内置于TCP/IP的应用程序之一,可以对IP地址或URL进行相应的域名转换。Tracert一般用于检测故障的区段,从而便于查找和排除故障。

  Tracert诊断实用程序将包含不同生存时间(TTL)值的Internet消息控制协议(ICMP)回显数据包发送到目标,以决定到达目标使用的路由。要在转发数据包上的TTL之前至少递减1,必须经过路径上的每个路由器,所以TTL是有效的跃点计数。数据包上的TTL达到0时,路由器应该将“ICMP已超时”的消息发送回源系统。Tracert先发送TTL为1的回显数据包,并在随后的每次发送过程将TTL递增1,直到目标响应或TTL达到最大值,从而确定路由。路由通过检查中级路由器返回的“ICMP已超时”的消息来确定路由。不过,有些路由器下传包含过期TTL值的数据包,而Tracert看不到。(看不懂,再说

  
作者: Billunique     时间: 2007-4-11 08:35
Boot.ini文件解释(基础的东西里面都是有文章的):

  Boot.ini文件的内容可分为[boot loader]和[operating systems]两部分。[boot loader]就不说了,我们来看看[operation systems]。比如有这样一个----
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /fastdetect
multi(0)disk(0)rdist(0)partition(2)WINNT="Microsoft Windows 2000 Server" /fastdetect
  英文引号内的文字,就是引导菜单里显示出来的,选择操作系统的提示文字。至于前面那段涉及ARC命名,它是x86或RISC计算机中用于标识设备的动态方法。ARC命名的第一部分用于标识硬件适配卡/磁盘控制器,它有两个选项SCSI和Multi。Multi表示一个非SCSI硬盘或一个由SCSI BIOS访问的SCSI硬盘,而SCSI则表示一个SCSI BIOS禁止的SCSI硬盘,(x)是硬件适配卡序号;Disk(x)表示SCSI总线号,如果硬件适配卡为Multi,其正确表示方法就为disk(0),rdisk(x)则表示硬盘的序号,如果硬件适配卡为SCSI则忽略此值;partition(x)表示硬盘的分区序号。

开关符的含义:

  /fastdetect:使系统不检查串行口和并行口。
  /safeboot:安全启动,系统只启动HKLM\System\Current ControlSet。
  /basevideo:使用标准VGA方式启动。这种方式主要用于显示驱动失效时。
  /BurnMemory=:使NT在已知的内存上少使用指定的数量,如果/burnmemory=64,则有64M的内存不使用。
  /Bootlog:将日志写入%System%\NTbtlog.txt。 
  /MaxMem:n:指定NT可以使用的最大内存数,如果一个内存片坏了,这个开关就会有些用。
  /Numproc=n:只允许前n个系统处理器工作。
  /OneCPU:在多处理器中只使用一个处理器。
  /NoGUIBoot:不加载VGA程序,也就不会显示启动过程和失败时的蓝屏信息。
  /SOS:在调入驱动程序名时显示它的名字,在因驱动问题而无法启动时使用比较好。 
  /Win95DOS:在装有3个系统DOS、Win9x和NT的系统上,让NTLDR直接调用DOS的启动文件bootsect.dos。
  /Win95:在上述情况下,让NTLDR直接调用Win9x启动文件bootsect.w40。(

※--------------------------------------------------------------------------------------------------个人觉得上面这部分开关的作用要大些。

  /baudrate:指出用于调度的波特率,如果用户不设置,则使用默认的9600,而对于线缆Modem则使用19200。=_=
  /debug:在启动NT时调入调度器,它可以在任何时间激活,在错误时可以再次出现时使用它比较合适。
  /CrashDebug:调度器在NT启动时启动,只有在内核错误时才有用,如果系统经常会无故出错,这个选项就很有用了。
  /debugport=comx:指定用于调度的端口,x就是指端口号。
  /Nodebug:不使用调度信息。
  /HAL=<hal>:允许用户不使用默认的HAL。
  /NoserialMice=[COMx|COmx,y,z...]:在特定的COM中禁止对串行鼠标的检测。如果用户有一个非鼠标设备接在COM口上,这个选项有些用。
  /Year=:使用指定的年份。
  /PCLlock:不让NT为多PCI设置分配IO/IRQ资源,而启用BIOS设置。
  

[ Last edited by Billunique on 2007-4-12 at 03:24 AM ]
作者: Billunique     时间: 2007-4-12 03:47
Msdos.sys文件解释:
[Paths]
WinDir=C:\Windows       --系统所在目录
WinBootDir=C:\Windows     --系统启动目录
HostWinBootDrv=C        --系统所在分区
  Win98的Msdos.sys文件中的[Option]块中的一些设置(各选项中默认值写在前面)。
[Options]
Autoscan=1/0          --异常关机后下次启动是否运行Scandisk
BootDelay=2/?         --开机时热键按下前的等待时间(秒)
BootGUI=1/0           --启动时是否进入Windows界面(否则为DOS界面)
BootKeys=1/0          --启动时热键是否有效         
BootMenu=0/1         --启动时是否显示启动菜单(否则要按下热键才显示)
BootMenuDefault=1/?       --显示启动菜单时的默认项(即光标所在项)
BootMulti=0/1          --是否支持与旧版DOS的多启动(有旧版DOS启动文件,且此盘必须为FAT16)
BootWarn=1/0         --在启动过程失败后,下次启动是否提示进入安全模式
BootWin=1/0         --启动时是否自动装入旧版DOS(?)
DblSpace=0/1        --启动时是否装入DblSpace.bin
DoubleBuffer=0/1       --是否启动双缓冲区支持
DrvSpace=0/1        --启动时是否装入DrvSpace.bin
LoadTop=1/0        --启动时是否将系统核心的一部分装入高端内存
Logo=1/0          --启动时是否显示“蓝天白云”
Winver=4.10.1998      --Windows版本
[ Last edited by Billunique on 2007-4-12 at 04:20 AM ]
作者: Billunique     时间: 2007-4-12 04:19
  这本书大致就到这里了,明天就去还了去。

  下一本是什么呢,现在还没有概念,感觉学得挺乱的,没有一个循序渐进的过程。
作者: Billunique     时间: 2007-4-14 06:38
★《计算机系统结构精髓》(《Essentials of Computer Architecture》By Douglas E.Commer----清华大学出版社)乱弹

  *●*遵循冯·诺依曼体系结构的计算机,将程序和数据两者都存放在存储器中。这样的话,对每条指令,处理器至少必须进行一次存储器访问。如果一个或多个操作指定的数据项在存储器中,那么处理器就得多次访问存储器来读取或存放数值。系统结构设计师用冯·诺依曼瓶颈(Von Neumann bottleneck)这个术语来描绘这种状况。为了避免这种瓶颈,要利用一些技术,诸如把大多数操作数限制在寄存器里。

  
  链接:

  1.概括起来,冯·诺依曼结构有3条重要的设计思想:

  (1)计算机应由运算器、控制器、存储器、输入设备和输出设备5大部分组成,每个部分有一定的功能。
  (2)以二进制的形式表示数据和指令,二进制是计算机的基本语言。
  (3)程序预先存入存储器中,使计算机在工作中能自动地从存储器中取出程序指令并加以执行。

  2.指令(Instruction)就是可以为硬件所识别的操作。一个操作就是一条指令,操作的集合我们称为指令集或指令系统(Instruction Set)。每一次重新进入一个读取-执行周期意味着处理器又在执行一条指令。

 *●*读取-执行周期
  
  一个可编程的处理器是怎样来一步步读取和执行程序的呢?虽然具体细节各不相同,但是所有的可编程处理器都遵循同样的基本范式。这一基础机制称为读取-执行周期(fetch-exccute cycle)

  实现读取-执行周期,处理器自动地历经一个程序,一步一步执行。就是说,每个可编程处理器重复地执行两个基本功能。即:

  永远重复{
         读取:从程序存放的地方读取程序的下一步。
         执行:执行程序的这一步。
  }

  处理器在执行程序的最后一步后会发生什么?--处理器硬件不被设计成停止,它不停地继续运行读取-执行周期。当然,一个处理器不可以永久停止(就是你关了电源)--正常的操作中,处理器将一条指令接一条指令地连续执行。

  在某些情况下,程序利用一个循环来进行延迟。例如,微控制器可能需要等待一个传感器的信号来判断是否满足某个外部条件,再继续执行。但是,处理器并非停下来等待这个传感器,而是在程序中包含一个循环,不断地对传感器进行测试。所以,从硬件的观点看,读取-执行周期继续着。

  无穷尽的读取-执行观点,对程序设计造成一个直接的结果:软件必须设计得使处理器一直有下一步执行。对于诸如控制物理设备的微控制器这类专用系统,程序由一个无穷循环构成--当它完成程序的最后一步时,处理器再从第一步开始。对于通用计算机,总是有一个操作系统。操作系统能把一个应用程序装载到存储器,然后指挥处理器运行这个应用程序,为了保持读取-执行周期运转,当应用程序完成时,操作系统必须约定收回控制。在没有应用程序运行时,操作系统进入一个循环,等待输入(例如键盘或鼠标的输入)。

  摘要如下:因为处理器无穷运行读取-执行周期,所以一个系统必须被设计成确保一直有下一步执行。在专用系统中,同一程序反复执行;在通用系统中,在没有应用程序运行时,操作系统一直运行着。

 *●*处理器一旦完成一条指令的执行,就自动转移到存储器中下一单元,再读取下一条指令。为了执行读取-执行周期,处理器使用一个称为程序计数器(program counter)的专用寄存器--有的系统设计师不称为程序计数器,而称指令指针(Instruction Pointer),两个术语完全一致。

  当一个读取-执行周期开始时,程序计数器里有下一条要执行的指令的地址。一条指令读取后,程序计数器就立即更新为下一条指令的地址。每个读取-执行周期期间程序计数器的更新,意味着处理器自动地历经存储器里相继的指令。下面表明了读取-执行周期怎样历经相继指令。

  赋给程序计数器一个程序的起始地址。
  永远重复{
       读取:从程序计数器给定的单元获取程序的下一步。
       把内部地址寄存器A置值为刚读取的指令的后一个地址。
       执行:执行此步程序。
       把地址寄存器A的内容复制到程序计数器。
  }

  这个算法让我们明白转移指令怎样工作。绝对转移(absolute branch)指明要执行的下一条指令的地址。通常绝对转移指令称为跳转(jump)指令。jump指令在执行阶段把由操作数字段给予的地址加载到上述算法所说明的内部寄存器A。在读取-执行周期最后,硬件把这个数值复制到程序计数器,表明了将按这个地址来读取下一条指令。(相对转移暂搁不表)

[ Last edited by Billunique on 2007-6-6 at 11:11 AM ]
作者: Billunique     时间: 2007-4-14 08:22
  *●*CPU复杂性的部分原因:
  
  它必须充当几个重要的角色==运行操作系统、运行应用程序、控制外部I/O设备、启动和停止计算机、管理存储器等。没有一种单一的指令集对于所有这些角色都是最理想的,因此,一个CPU常包含多个指令集。
  
  保护和特权==现代计算机都含有一个保护系统,它可以赋予某些子系统有更高的特权。例如,可以防止一个应用程序直接与I/O设备交互;可以防止操作系统的代码被有意无意地篡改。
  
  硬件优先权==CPU采用优先权方案,赋予某些计算任务比其他计算任务有更高的优先权。例如,I/O设备比应用程序有更高的运行优先权--如果CPU在运行一个程序时,有一个I/O设备需要服务,此刻CPU就会停止应用程序的运行,而去处理这个设备。

 *●*CPU利用执行模式(mode of execution)。在有些CPU中,各模式的特性差别相当大,可以认为CPU是几个分开的、不同的硬件子系统,由模式来决定当前使用的是哪个硬件子系统。

  以下是由CPU执行模式控制的一些典型特性。模式改变时,CPU的特性也明显改变:

  ~指令系统的一个有效子集 ~数据顶的大小
  ~可以访问的存储器范围  ~可用的功能部件  ~特权量

 *●*特权和保护:
  执行模式关系到CPU的那些用于特权和保护的机制。就是说,当前模式部分指定了CPU的特权级。例如,当CPU为一个I/O设备服务时,它允许操作系统中的设备驱动软件与设备交互作用,并执行控制功能。但是必须防止其他随便什么应用程序无意或恶意地向硬件发送命令,或执行控制功能。所以操作系统执行应用程序前,先要改变模式,降低特权。运行更小特权的模式时,CPU不准许直接控制I/O设备(即,CPU把一个特权操作视为一条无效指令)。

 *●*多级保护:

  到底需要多少级特权?每一级应当允许一些什么样的操作?这个课题,硬件系统设计师和操作系统设计师已经讨论了多年。创建了不提供保护的CPU,又创建了提供八级保护的CPU,一个比一个有更多的特权。保护的想法在于,在任何时刻利用必需的最小级别的特权,来帮助防范问题的发生。摘要如下:

  利用保护方案来限制允许的操作,CPU能够检测那些企图执行未经授权的操作。

  下图表示了两级特权的概念。


  虽然没有一种能满足所有CPU的保护方案,不过设计者们一般对运行应用程序的CPU,认同一种最低限度的方案:
  
  一个运行应用程序的CPU至少需要两级保护:操作系统一定以完全的特权运行,而应用程序以有限的特权运行。

[ Last edited by Billunique on 2007-6-6 at 11:11 AM ]
作者: lxmxn     时间: 2007-4-19 09:54
我来学习一下,顺便顶一个。
作者: Billunique     时间: 2007-4-20 03:54
多谢lxmxn莅临指导。这几天有点忙,同时也不知道记些啥好了。不过我会坚持的~将学习进行到底!
作者: Billunique     时间: 2007-4-24 07:54
★《微机原理与接口技术》(电子工业出版社)乱弹

  ☆十进制数转换为R进制数

  (1)整数部分的转换。常用的方法有除R取余法和降幂法。

  [例]用除R取余法将十进制的1223转换成等值的十六进制数。

  具体做法是:除16取余,先得低位,逐次取得较高位,一直进行到商数为0时为止,然后按反序获得对应的十六进制数。
  
  
  [例]用降幂法将十进制83转换成等值的二进制数。
  
  具体做法是:(对于给定的一个十进制数M)

  ¥ 在R的N次幂中寻找N的最大值,使有(R的N次方)<=M,然后在R进制的对应位上置1,否则置0;
  ¥ M=M-(R的N次方)赋给,若M=0,则结束;否则重复第一步。
83-64=19  (64=2的6次方,0|1|0|0|0|0|0|0)
19-16=3   (16=2的4次方,0|1|0|1|0|0|0|0)
3-2=1     (2=2的1次方,0|1|0|1|0|0|1|0)
1-1=0     (1=2的0次方,0|1|0|1|0|0|1|1)

所以,(83)D=(01010011)B
  (2)小数部分的转换

  十进制小数转换成R进制小数的方法是:乘R取整,先得高位,依次获得低位。如果十进制小数不能用有限的R进制小数表示,则可根据需要取若干位作为近似值。对于既有整数部分又有小数部分的十进制数,转换时只需将整数部分和小数部分分别进行转换,然后用小数点连接起来即可。

  [例]把十进制小数0.5625转换成等值的二进制数。
小数部分    整数部分
2×0.5625     1    (高位)
2×0.1250     0
2×0.2500     0
2×0.5000     1    (低位)
  0.0000

所以,(0.5625)D=(0.1001)B
[ Last edited by Billunique on 2007-6-6 at 11:13 AM ]
作者: Billunique     时间: 2007-4-25 08:36
  ☆汉字的编码

  在计算机内部,任何信息都是用二进制代码表示的(包括字母、数字、符号和汉字)。一般情况下,计算机依靠输入设备把要输入的字符或汉字转换成为一定格式的二进制代码,然后才能接收。输出则是相反的过程,计算机首先把要输出的字符或汉字的二进制代码送到输出设备,然后再由输出设备处理输出。总之,无论是输入还是输出,都必须对文字符和汉字进行编码。

  西文是拼音文字,用有限的几个字母(如英文26个,俄文32个)就可以拼写出全部西文信息。因此,西文仅需对有限个数的字母进行编码,就可以将全部西文信息全部输入计算机。而汉字信息则不一样,汉字是象形文字,一个汉字就是一个方块图形。计算机要对汉字信息进行处理,就必须对数目繁多的汉字进行编码,建立一个含成千上万个汉字的字符集。

  所谓的国标码是《国家标准信息交换用汉字编码基本字符集》的简称。这是我国国家标准总局于1981年,为适应计算机对汉字信息交换的处理而颁布的国家标准,编号为GB2312-80。该标准按94×94的二维代码表形式,收集了6763个汉字和682个一般字符、序号、数字、拉丁字母、希腊字母、汉语拼音符号等,共7745个图形字符。该标准最多可包含8836个图形字符,适合于一般汉字处理、汉字通信等系统之间的信息交换。(2000年又颁布了GB18030-2000,扩充了字符集,加入了对少数民族文字的支持)

  汉字编码有内码、外码之分。外码实际上就是汉字的输入编码,比如区位码、国标码、全拼码、双拼码、五笔字形码、郑码等等。内码是计算机系统内部进行汉字信息存储、交换、检索等操作的编码。汉字内码采用两个字节表示,没有重码。

  区位码:用每个汉字在二维码表中的行、列位置的序数来表示的代码,共4位数字,简称为区位码,前二位为行号(也称区号),后二位为列号(也称位号)。如“啊”的区位码为1601,表示“啊”在二维代码表中位于16区01位。

  国标码:国标码为区号和位号各加32后,得到的双七位二进制编码。如“啊”的国标码为4833,国标码用于不同汉字系统之间汉字的传输和交换,也可用做汉字的输入编码。

  内码:汉字国标码是双七位二进制编码,要用它作机内码将会与英文字符的机内码ASCII码相混淆,为此特把两字节国标码的每个字节的最高位置“1”,以与ASCII码最高位为“0”区别开来。这样,便形成了汉字的机内码。简单说,机内码=国标码+8080H(即1000000010000000)
  

  
  

[ Last edited by Billunique on 2007-4-26 at 12:34 AM ]
作者: Billunique     时间: 2007-4-26 01:38
  Who Can Tell Me把图片上传到什么地方,不会每天都变更一个链接地址,以至于引用的时候不会失效?我在雅虎空间、百度空间都试了,老是天天换,搞得我很机械。

[ Last edited by Billunique on 2007-4-26 at 01:40 AM ]
作者: Billunique     时间: 2007-4-26 02:01
%%总线%%

  所谓总线,是计算机中各功能部件间传送信息的公共通道,是微型计算机的重要组成部分。它们可以是带状的扁平电缆线,也可以是印刷电路板上的一层极薄的金属连线。所有的信息都通过总线传送。根据所传送信息的内容与作用不同,总线可分为三类:

  1.地址总线AB(Address Bus):在对存储器或I/O端口进行访问时,传送由CPU提供的要访问存储单元或I/O端口的地址信息,以便选中要访问的存储单元或I/O端口,是单向总线,其宽度决定了CPU寻址空间的大小。如8086的地址线为20根,则其寻址空间为2的20次方=1MB。而P4的地址线为36根,则其寻址空间为2的36次方=1GB*2的6次方=64GB。

  2.数据总线DB(Data Bus):从存储器取指令或读/写操作数、对I/O端口进行读/写操作时,指令码或数据信息通过数据总线送往CPU或由CPU送出,是双向总线。其宽度决定了CPU一次传送的二进制的位数。(通常说的处理器的位数对应的是它)

  3.控制总线CB(Control Bus):各种控制或状态信息通过控制总线由CPU送往有关部件,或者从有关部件送往CPU。CB中每根线的传送方向是一定的。

[ Last edited by Billunique on 2007-4-26 at 03:46 AM ]
作者: Billunique     时间: 2007-5-14 12:04
  我回来了!最近好忙啊~忙得忽略了学习,这样可不好。要知道知识是需要巩固的,要常记常用才能成为自己受用的知识。

  其实对于DOS的学习我只是停于表面,非常肤浅。照理应该深究才有所成。但限于时间和目前的应用环境,我不想再回头重来一遍了。我知道学习应该有重点,在耐性,不能老是蜻蜓点水过一遍,但总又有意无意地犯这个毛病。不管怎样,学习要进行下去,下一步学什么呢?

  偶然间进入electronixtar的帖子“[分享]批处理与其他语言混合编程”(http://www.cn-dos.net/forum/viewthread.php?tid=26819),在WIKI里一段简单代码让我来了点感觉。既然现在无法很清晰地界定学习目标,那先试探吧。弄一个相对简单而且常用的——VBS,好歹Windows横行天下。学习VBS,从下面这段代码开始:

  Quote:
echo msgbox 3^>2 >v.vbs
cscript v.vbs

  执行之后会弹出一个Windows对话框,主体内容显示“True”,再加一个“确定”按钮。这就是同属Microsoft的好处,省却多少代码。
作者: Billunique     时间: 2007-5-14 18:44
  经典教程里的一段代码--把VBS插在HTML页面中的一个示例:
<HTML>
<HEAD>
<TITLE>测试按钮事件</TITLE>
</HEAD>
<BODY>
<FORM NAME="Form1">
   <INPUT TYPE="Button" NAME="Button1" VALUE="单击">
   <SCRIPT FOR="Button1" EVENT="onClick" LANGUAGE="VBScript">
      MsgBox "按钮被单击!"
   </SCRIPT>
</FORM>
</BODY>
</HTML>

作者: Billunique     时间: 2007-5-16 15:52
不管三七二一,先把这么几段话记下再说:(挺有启发性的)

  基于组件开发(Component-Based Development,简写为CBD)是综合多种优秀设计思想和实践的产物,诸如面向对象开发、契约式设计、模型驱动的开发、分离考虑、软件系统架构设计等。CBD的目标是改进软件开发的过程,手段是通过一些预先构建的软件组件来组装成新的软件,而不是从头开发。通过对复用的强调,CBD达到了可观的开发效率和品质。Delphi组件、COM+组件、CORBA组件、JavaBeans和EJB等都是众所周知的一些组件模型。

  组件和控件:

  在.NET框架中,组件是指实现System.ComponentModel.IComponent接口的一个类,或从实现IComponent的类中直接或间接导出的类。在编程中,“组件”这个术语通常用于可重复使用并且可以和其他对象进行交互的对象。.NET框架组件满足这些一般要求,另外还提供诸如控制外部门资源和设计时支持等功能。

  控件是提供(或实现)用户界面(UI)功能的组件。.NET框架为控件提供两个基类:一个用于客户端Windows窗体控件,另一个用于ASP.NET服务器控件。它们是System.Windows.Forms.Control和System.Web.UI.Control。.NET框架类库中的所有控件都是直接或间接从这两个类导出的。System.Windows.Forms.Control从Component导出,它本身提供UI功能。System.Web.UI.Control实现IComponent,它提供结构,在这个结构上可以很方便地添加UI功能。

  一句经典的话:每个控件都是一个组件,但并不是每个组件都是一个控件。

  

[ Last edited by Billunique on 2007-5-16 at 04:39 PM ]
作者: Billunique     时间: 2007-5-16 17:53
☆VB程序的工作机制

  Visual Basic是一种基于对象的程序设计语言。一个Visual Basic程序由众多的对象以及响应各种事件的代码组成。当用户对对象进行某些操作时,就产生特定的事件。对象在某些特定条件下也会自动产生事件。当事件产生时,Visual Basic程序就自动调用相应的代码来处理这些事件。可以说,应用程序在运行的过程当中,始终在等候事件的产生并做出响应,直到用户结束整个程序为止。

●[对象]

  很多人只要一接触到“面向对象”这个词,就感觉特别难以理解。在日常口语中常用到“东西”这个词,可以简单地认为,所说的“东西”同这里的“对象”具有相同的意义。对象是很具体地存在着的一个事物,比如一支铅笔、一个发电机、一只老虎(如果用口语来表达,这些事物都是“东西”)。不难发现,铅笔也好,发电机也好,老虎也好,都是具有完整意义的一个事物:如果铅笔少了笔芯,也就不是铅笔了;如果发电机少了磁芯,它就发不出电来,也就不能称其为发电机了。

  在日常生活中,是怎么区分“东西”的呢?首先,我们将事物分类。显然,我们不会将家用电脑同车床混淆在一起,因为它们分别属于两类事物。而后,对于同一类的物体,可以通过其不同的特征区分不同的个体。比如两支铅笔,它们都是同一类物体,但可能通过颜色来区分:一支是黄色的,另一支是红色的。

  于是,在面向对象理论中,用“类”这个词来表示对象的不同类型,用属性和方法来表示同种对象的不同特征。属性是对象的静态特征。比如颜色(这是静态的)是铅笔的属性,铅笔的颜色可以是黑的,也可以是红的或蓝的。方法是对象的动态特征。比如发电(这是一种动作,是动态的)就是发电机的方法。对象的方法是通过外部的事件来触发的。像发电机的发电方法,只有在操作人员允许发电机运转后,发电机的发电方法才被触发,进入发电状态。

  在Visual Basic中,窗体、控件、菜单等都是对象。在例子程序“欢迎进入VB世界”中使用的对象有:一个窗体、两个命令按钮控件和一个标签控件。(你可以想象出来,这里照书上的行文来)

  以命令按钮控件为例。在例子程序中,使用了两个按钮控件。这两个对象虽然都是命令按钮(即属于同一类),但是它们具有不同的Caption属性:一个是“开始”,一个是“退出”。也具有不同的Name属性:一个是“Command1”,另一个是“Command2”。命令按钮控件有很多方法,比如“移动”方法,当命令按钮控件在窗体上的位置需要改变时,我们就调用命令按钮的“移动”方法来实现。

  显然,在Visual Basic编程中,应用程序的用户界面是由很多与用户界面有关的对象组成的。所以,在编写Visual Basic程序时,要做的第一件事就是准备好程序中所要用到的对象。(准备“米”--|东西|下饭)

●[事件驱动机制]

  Visual Basic程序的主体是众多的对象,也就是窗体、控件、菜单等。当用户在某个对象上进行某行操作,比如在命令按钮上进行鼠标单击,就会在这个命令按钮对象上激发一个鼠标单击事件。一般来说,用户的操作都是有目的的,应用程序应该响应用户的操作,也就是说,程序员应该编写代码处理这些事件。

  实际上,Visual Basic程序的运行过程就是对事件的处理过程。程序运行时,各种不同的对象会产生很多不同的事件。这些事件有一些是由用户的操作引起的,另一些是在某种条件下对象自己产生的(比如“定时器时间到”事件)。程序员分别为各种不同的事件编写处理代码。在没有事件发生时,程序就什么也不做。这就是所说的事件驱动机制。

  Visual Basic的这种基于对象的事件驱动机制,是简化Windows程序设计的法宝。在这种机制下,设计一个Visual Basic程序只需遵循如下步骤:

  1)设计程序的用户界面,也就是放置各种对象。
  2)定义用户界面中各个对象的属性,比如颜色、标题等。
  3)定义各个可能用到的事件。
  4)给事件编写相应的代码。

  其中,前3个步骤是与界面设计有关的步骤。程序员只需使用VB的可视化工具即可完成这些设计,根本无需编写任何代码。(手编当然也可以,VBS就得手编啊)第4个步骤才是实现程序功能的编码工作。这样,程序员就可以将大部分精力放在功能的实现上。至于界面是怎么捕获用户操作,怎么发出事件,怎么调用程序员编写的事件处理代码的,根本无需关心,VB已经为用户设计好了这些事。
  

  

  

[ Last edited by Billunique on 2007-5-16 at 06:08 PM ]
作者: Billunique     时间: 2007-5-17 17:52
过程

  子过程(Sub procedure)是一个用来完成某一特定功能的程序块。如果一个程度中有多处需要使用相同的程度代码完成相同的事情,就可以将这段代码做成一个过程。在需要的时候,可以通过调用这个过程完成相应的任务。

  函数过程(Function procedure)也是个能完成某一特定功能的程序块,它同子过程的区别在于函数能返回一个结果。

  使用过程能使程序结构清晰,从而实现结构化和模块化程度的设计目标。
作者: ccwan     时间: 2007-5-25 10:38
Billunique兄涉猎很多啊,要是我可就不能同时应对了。呵呵
作者: Billunique     时间: 2007-5-29 15:01
惭愧惭愧,让ccwan兄见笑了!非涉猎广,实蒙头乱撞而已。学东西千万不可似我,学无所专,学无所长。就像那幅经典的漫画“挖井”一样,挖几把换一个地方,到头来始终挖不到自己的“井”。
作者: Billunique     时间: 2007-5-29 18:47
这段话挺好的:

  变量就像一个容器,容器里面可以盛放一升液体或两升液体,也可以什么都不放。变量也是如此,它可以放一个数字、一个字符串,什么时候放多少东西,完全由程序的功能来决定。

  (从专业的角度来说,变量是存储在内存中的用来代替所包含信息的地址的名字。变量,是一个代号。)
作者: Billunique     时间: 2007-6-5 10:21
获取输入

  Prompting for information is easy: Just use InputBox. This function pops up a dialog box, and users can happily enter whatever you asked them to.
ask="Hey,what's your name?"
title="Who are you?"

answer=InputBox(ask,title)
If answer=vbEmpty Then
        MsgBox "You want to cancel? Fine!"
        WScript.Quit
ElseIf answer=""Then
        MsgBox "You want to stay incognito,all right with me..."
Else
        MsgBox "Welcome "&answer&"!"
End If
  注:用户按下“Cancel"键时,传递的值为一个”empty"值,我们可以将其等同于常量“VbEmpty”。如果没有加入这层判断,而直接“Cancel”提交时,MsgBox会“尽力”地把“空值”转化为”空字符串”,这样的话“Cancel”键的作用就体现不出来了,表面上看就好像等同于传递了一个空字符串。

  你可以用下面这段代码去体会上面的描述。
ask="Hey,what's your name?"
title="Who are you?"
default="??"

answer=InputBox(ask,title,default)
MsgBox "Welcome "&answer&"!"
[ Last edited by Billunique on 2007-6-14 at 11:01 AM ]
作者: Billunique     时间: 2007-6-5 18:20
检查输入

  Prompting for information doesn’t necessarily mean you’ll get it. You can ask politely, because InputBox accepts anything the user types in. Therefore,after asking for information, you should check the entered information to make sure it is valid.(这里我们用“is~”这个东西,它就相当于询问“请问你是不是~?”)
'asking for a date
ask="What's your birthday?"
title="Let's see how old you are!"

'start a loop:
Do
        birthday=InputBox(ask,title)
        'check whether the user wants to quit:
        If IsEmpty(birthday)Then
                MsgBox "Hey! You could always lie to me to hide " _
                &" your age! But ok, I quit!"
                WScript.Quit
        ElseIf Not IsDate(birthday) Then
                'check whether birthday is really a date!
                'complain and give another chance:
                MsgBox "You didn't enter a valid date! Try again!"
        End If
'loop until a valid date was retrieved
Loop Until IsDate(birthday)

'at this point,we have a valid date,good!
'do some fun calculations:

age_in_days=DateDiff("d",birthday,Date)
age_in_months=DateDiff("m",birthday,Date)
age_in_years=DateDiff("yyyy",birthday,Date)
day_born=WeekdayName(Weekday(birthday))

' DateDiff是比较两个日期间距的函数,第一个参数为比较单位,结果是第一个日期减去第二个日期的值。
' Weekday是返回“星天量”的函数(Sunday~Saturday:1~7)
' WeekdayName是返回“星天名”的函数。

'calculate this year's birthday
date_day=Day(birthday)
date_month=Month(birthday)
'use current year:
date_year=Year(Date)

' Day函数返回“月天量”(1~31)
' Month函数返回“年月量”(1~12)
' Year函数返回具体的“年量”(2007这种格式的)
' DateSerial函数接受三个参数,分别应为年、月、日的有效数值或表达式,
' 然后把它们重新排列成一个规范的含年、月、日的日期格式

this_years_birthday=DateSerial(date_year,date_month,date_day)
'use Abs to convert to positive numbers in case the birthday's already over:
days_to_birthday=Abs(DateDiff("d",Date,this_years_birthday))
day_celebrating=WeekdayName(Weekday(this_years_birthday))

' 因为是前参-后参,可能会出现负值,就是生日还没到,
' 于是用Abs(Absolute)换出其绝对值。

'already over?
If this_years_birthday<Date Then
        message="you celebrated your birthday "& days_to_birthday &" days ago"
ElseIf this_years_birthday=Date Then
        message="Happy birthday!!"
Else
        message=days_to_birthday &" days to go!"
End If

'output information

msg="This is your birthday analysis:" & vbCr
msg=msg+"You are born on "& birthday & vbCr
msg=msg+"You are " & age_in_years &" yrs old. That's" & vbCr
msg=msg &age_in_months &" months or " & age_in_days &" days!" &vbCr
msg=msg+"You were born on a " & day_born &vbCr
msg=msg+"This year's birthday is on " & this_years_birthday &vbCr
msg=msg+"It's a " &day_celebrating &vbCr
msg=msg+message

MsgBox msg

' 利用msg自身叠加的方法达到最后的输入效果,很典型,要掌握。
[ Last edited by Billunique on 2007-6-14 at 11:12 AM ]
作者: Billunique     时间: 2007-6-6 10:45
仅需确认意见

  In many cases, you don’t need text input. You just need a simple Yes-or-No decision. VBScript contains a very versatile tool that allows you to ask all kinds of simple questions. It’s called MsgBox—you’ve already used this function to display plain text information.

  You can call a function using parentheses, and it will return a value. If you calla function as a procedure, without using parentheses, it will not return a value. MsgBox is a function. When you use it as a procedure, it will simply output information. If you want to base decisions on MsgBox dialog boxes, then use it as a function, and check which value MsgBox returned.

  The easiest way to call  MsgBox as a function looks like this:
result = MsgBox(“Do you agree?”)
  MsgBox后面的参数,第一为内容,第二为显示按钮+语气标志+默认选择按钮,三为标题;后面的为帮助,基本不用。

  

  例如我们可以这样用:
result = MsgBox(“Continue?”, vbYesNo+vbQuestion, “What now?”)
  返回值则可以参照下图:
  

[ Last edited by Billunique on 2007-6-6 at 11:21 AM ]
作者: Billunique     时间: 2007-6-6 11:45

'get arguments as collection object
set args = WScript.Arguments
' check whether there are any arguments:
if args.Count = 0 then
'no arguments
MsgBox “You called this script directly, no arguments specified!”
else
for each argument in args
list = list & argument & vbCr
next
MsgBox “Here’s the list of arguments:” & vbCr & list
end if
  用上面这段代码,可以造就一个“参数阅读器”,而且支持参数拖拽。拖进去后参数的信息便会一目了然。

  这里涉及到set的用法,for each...next的用法,Arguments对象的Count方法;而最典型最值得借鉴的是那个list的用法。利用循环和list自身叠加的方法达到了很好的输出效果,要掌握。
作者: Billunique     时间: 2007-6-13 19:24
  用下面的代码可以写就一个很好的小型VBS调试器;细节先不关心了,暂时先记录下来。
'check whether script is run in CScript (DOS-Environment)
host =WScript.FullName
hostexe =LCase(Mid(host,InStrRev(host,"\")+1))
If Not hostexe = "cscript.exe" Then
        'error! We run in wscript. so let's re-launch in cscript!
        Set wshshell = CreateObject("wscript.shell")
        wshshell.Run "cscript.exe"""& WScript.ScriptFullName &""""
        'quit
        WScript.Quit
End If

'get access to input and output stream:
Set input =WScript.StdIn
Set output =WScript.StdOut

output.Write "> "
Do Until input.AtEndOfStream
        'read in lines:
        line =input.ReadLine
        'exit condition:stop loop once someone enter "exit":
        If LCase(line)="exit" Then
                Exit Do
        Else
                'interpret the command:
                'replace? with output command
                line = Replace(line,"?","output.writeline")
                executeit line
                output.Write "> "
        End If
Loop

Sub executeit(command)
        'execute is a separate procedure because it turns off
        'build-in error handling
        'This is necessary to keep the script running even if
        'invalid command are entered:
        On Error Resume Next
        'execute statement:
        ExecuteGlobal command
        'did an error occur?
        If Not Err.Number=0 Then
                'yes,report cause:
                output.WriteLine "error: " & Err.Description
                Err.Clear
        End If
End sub
[ Last edited by Billunique on 2007-6-14 at 10:50 AM ]
作者: Billunique     时间: 2007-6-14 11:44
  今天转悠的时候偶然间发现bjsh版主发的这个Vbs教程,真的相当不错:http://www.cn-dos.net/forum/viewthread.php?tid=30588。以后我就可能会不时地从中摘记一些东西啦。
作者: Billunique     时间: 2007-6-14 12:05
  1.因为Msgbox的第三个参数是标题,像下面这样就可以省些力气:
MsgBox "1",,"2"
  2.凡是将一对象引用赋给变量,就需要使用Set关键字。那么什么是对象引用呢?凡是字符串、数值、布尔值之外的变量都是对象引用。

  3.Run在运行解析时,遇到空格会停止,解决的方法是使用双引号。比如:wscript.shell.run"""D:\Study\VBS\windows 脚本编程核心技术精解"""。
  run函数有三个参数,第一个参数是你要执行的程序的路径,第二个程序是窗口的形式,0是在后台运行;1表示正常运行;2表示激活程序并且显示为最小化;3表示激活程序并且显示为最大化...; 第三个参数是表示这个脚本是等待还是继续执行,如果设为了true,脚本就会等待调用的程序退出后再向后执行。
作者: Billunique     时间: 2007-6-14 15:17
  1.On  Error Resume  Next  
  这行语句可以告诉vbs在运行时跳过发生错误的语句,紧接着执行跟在它后面的语句。

  2.虽然On Error Resume Next语句可以防止vbs脚本在发生错误时停止运行,但是它并不能真正处理错误,要处理错误,你需要在脚本中增加一些语句,用来检查错误条件并在错误发生时处理它。

  vbscript提供了一个对象err对象,他有两个方法clear,raise,5个属性:description,helpcontext,helpfile,number,source。err对象不用引用实例,可以直接使用。
作者: Billunique     时间: 2007-6-14 16:29
关于操作注册表我想说的:

  1.显然要借助(引用)Wscript.Shell。

  2.路径的最后是用"\"结尾的,比如"HKCU\....\Thing\",就表示这是个项;若没有"\",如"HKCU\....\Thing",则表示这是个键值(键值跟数据不是一个概念)

  3.对于写操作,可以在(路径上的)一个项后进行随意的延伸,不用去担心这个项或键值本身是否存在;如果不存在,那就是“一路”新增,如果存在,那就是修改。All Right?!

  4.若想删除一个键值,则Wscript.Shell.Regdelete "HKCU\....\Thing";
  若想把该键值的数据清空,则Wscript.Shell.Regwrite "HKCU\....\Thing",""。

[ Last edited by Billunique on 2007-6-14 at 04:35 PM ]
作者: Billunique     时间: 2007-6-15 12:02
  
作者: Billunique     时间: 2007-6-15 19:29
  用下面这些代码放在VB编辑器里试试大致可以明白关于文件操作的一些东西:
Set fs=CreateObject("scripting.filesystemobject")
'Set ff=fs.GetFile("d:\bak\11.txt")
'MsgBox ff
'i=ff.Attributes
'MsgBox i
Set fo=fs.OpenTextFile("d:\bak\11.txt")
'MsgBox fo
v=fo.Read(5)
MsgBox v
line1=fo.ReadLine
line2=fo.ReadLine
MsgBox line2
con=fo.ReadAll
MsgBox con

'11.txt文件的内容可以是这样:
cndos.1111 aaa
22222
  想说明的是,OpenTextFile之后进行的Read操作,好像是在“切割”文本似的;上面的先读了到下面就只能读到其“切”完的加上自己“能力范围”内的那部分(我也说不清楚,呵呵)。ReadLine的能力范围只是读一行,不能读指定行。

  Write和WriteLine的用法类似,不过Open的时候需要“OpenTextFile(~.txt,2,[true|false]”其中1表只读、2表写、8表追加;true为不存在则创建,默认为false。

  若想既写又读,那么必须在要进行具体操作前把模式(即1、2、8)先定好,一种操作对应一个模式,否则脚本就会报错。

[ Last edited by Billunique on 2007-6-15 at 07:50 PM ]
作者: Billunique     时间: 2007-6-18 11:49
运用数组


  Variable arrays are just groups of variables that can be accessed using an index number. This is especially useful if your script needs to look up information stored in variables.

  Variable arrays always need to be declared so that VBScript knows how much storage space it should reserve. You can declare variable arrays using Dim or ReDim.

  Dim initializes a variable array of fixed size. You need to specify the number of elements the array should hold, and you cannot expand or shrink the array afterwards.

  Using Dim, you need to specify the number of entries as a constant or absolute number. You are not allowed to use a variable to feed the size of Dim. ReDim will also accept variables.

  大致说的就是ReDim比Dim好,可以随时改变数组的大小,那我们就用ReDim好了呗:)下面是一个简单例子:
Dim myarray(5)

myarray(0)="Unknown"
myarray(1)="Removable"
myarray(2)="Fixed"
myarray(3)="Remote"
myarray(4)="CD-ROM"
myarray(5)="RAM-Drive"

'find out the type of drives

Set fs = CreateObject("scripting.filesystemobject")

'get all drives:
Set drives = fs.Drives

' Drives属性:返回一个Drives集合,包含了本机上所有可用的Drive对象

For Each drive In drives
        letter = drive.DriveLetter
        kind = myarray(drive.DriveType)
        list = list & "Drive " & letter & " is of type "& kind & vbCr
Next

' DriveLetter属性:返回盘符
' DriveType属性:返回一个数值,指示驱动器类型,事实上系统的定义和该例上面的定义是一致的。

MsgBox list
[ Last edited by Billunique on 2007-6-18 at 11:56 AM ]
作者: Billunique     时间: 2007-6-18 18:51
Split和Join

  其实用Split可以简化上面的代码。
MyArray="unknown;Removable;Fixed;Remote;CD-ROM;RAM-Drive"
MyArray=Split(MyArray,";")
.......
  Split其实就是用分隔符将一段字符串“弄”成数组。

  而Join就是把数组里的各个元素“弄”成字符串。比如:
Myarray(0)="This "
Myarray(1)="is "
Myarray(2)="Billunique"
MyString=Join(Myarray)

'Then MyString="This is Billunique"

作者: Billunique     时间: 2007-9-17 19:14
三月没来了,实在惭愧啊,又一次被方向迷失了......
作者: gne3     时间: 2008-1-11 20:04
哈哈,你的第二帖对我有启发。谢谢
作者: Billunique     时间: 2008-8-18 11:13
过来打个招呼,我最爱的论坛之一!!好久不见~
作者: a574616737     时间: 2008-8-25 10:07
想楼住学习,等有上大学有时间时,也来这里写写学习笔记
作者: Billunique     时间: 2010-5-12 14:24
呱呱,露个脸,吐个泡泡
作者: zzz19760225     时间: 2016-2-9 21:21
怎么复制的
作者: zzz19760225     时间: 2017-12-4 13:48
看看