首页

为什么在安腾平台上的页面大小是8KB

在x86架构的机器上,Windows选择将4KB作为页面的大小,因为当时设计操作系统时,处理器架构只能支持4KB的页面。(后来,CPU添加了对4MB的页面的支持,我记得好像是奔腾处理器吧,但是对于大多数人来说,这个4MB就显得太大了些) 在安腾平台(IA64)上,Windows选择了使用8KB作为页面的大小,而不是4KB。这是为啥? 这样设计主要是在两个竞争性目标之间做出某种平衡。大页面相对小页面...

如何将一个字节数组转换为System.String

因为某些原因,这个问题被问的特别频繁:我如何将一个字节数组(byte [])转换为一个System.String? (是的,你冒看错,我说的是和CLR相关的东西。如果你觉得有些意外了,抱歉了啊) 简而言之,请使用下面这个技法,直接传入一个字节数组,它会给你转换为一个string。 System.Text.UnicodeEncoding.GetString() 这个方法会将指定字节数组中的所有字节解...

注意:Shift按键会覆盖NumLock

也许这个事实有很多人还不知道,但是在那个箭头和数字共用同一个按键的那个年代,确实会发生如标题所描述的事情:Shift按键会覆盖NumLock按键。 如果NumLock按键打开(通常它就是处于打开的状态),然后按下一个数字按键的同时,按住Shift按键,这个时候NumLock虽然是打开的但是实际上它会被覆盖,也即:这个时候键盘输入的是一个箭头(或者其他方向导航按键),而不是你想要输出的数字。 同理,...

即使在计算机的世界,同时性也只是相对的

爱因斯坦告诉我们:同时性是相对的。也即:在不同的地点发生的两个事件,在一个惯性系里是同时的,但在另一个惯性系里看来却不是同时的。而在计算机的世界里,同时性也是相对的。容我慢慢道来。 有些开发者会问:”是否可以同时在一个线程里执行操作A而在另一个线程中执行操作B?”,下面是一些具体的例子: > X操作:关闭某个句柄,Y操作:使用这个句柄。 > X操作:在一个句柄上...

为什么BIOS里的时间是本地时间

尽管Windows NT内部使用的是UTC时间,但是BIOS里的时间还是本地时间,这是为啥? 原因有那么一些,其中一个原因就是为了保持向后兼容性。 在早期,人们经常在Windows NT和MS-DOS/Windows 3.1之间进行双启动。MS-DOS和Windows 3.1 在本地时间运行,因此 Windows NT也效仿,这样你就不必在每次启动不同的操作系统时,不断更改系统时间了。 当人们从W...

如何寻找IE浏览器的执行路径  

基于某些原因,有些开发者希望能获取到IE浏览器(Internet Explorer)的全路径,这样就可以在二进制执行文件上加上一些选项了。 其实,并不需要这样。 只需要向ShellExecute函数传递”IEXPLORE.EXE”这个参数,它就会有方法找到IE的执行文件并想办法执行它,如下图所示: 这个ShellExecute函数会负责为我们干”脏活̶...

关于x86平台上内存对齐的重要性,第二部分

各种 Interlocked 函数(InterlockedIncrement 等)要求被更新的变量正确对齐,即使在 x86 平台上,CPU 以静默方式修复未对齐的内存访问。 如果将未对齐的指针传递给 Interlocked 函数之一,操作仍然会成功,但结果将不是原子的。 另一个处理器可能会看到部分完成的更新。 这是一个特别隐蔽的错误,因为它只发生在非常严格的时序条件下的多处理器机器上。 您将很难在...

关于x86平台上内存对齐的重要性

有时候,未对齐的内存访问,可能会导致系统挂起。 有一些显卡不允许驱动程序一次性就访问所有的显卡内存。取而代之的做法是:它给你一个访问窗口,你可以从中选择一个显存的子集来进行访问。举个例子,EGA显卡有256K的字节空间,它们被划分到4个64K的存储单元中。如果你希望访问第一个64K,则你需要将这个64K空间(bank 0)选择到访问窗口中,同样的道理,如果你需要访问第二个64K,则你需要将它(ba...

为什么有些结构体中会定义一个字节的数组  

有一些Windows结构体是可变长度的,它们通常会有一个固定长度的头部,然后接下来是一个可变长度的数组。当这些结构体被声明的时候,它们通常会被声明为一个只有一个字节元素的数组,如下图所示: 如果我们观察一下头文件中的定义,就会发现,这里的ANYSIZE_ARRAY被定义成了1,也就是说,这个结构体的结尾是一个只包含1个字节的数组。 通过这样的声明,我们可以分配一个可变长度的结构体,如下图所示: ...

为什么不能将FILETIME看做__int64  

我们先来看看FILETIME这个结构体,它通过组合两个DWORD来表示了一个64位的整数值。 你可能想将这个FILETIME结构体看做一个整体,然后将它们看做一个__int64结构来进行访问。 毕竟,这两个类型的内存布局都是一样的,下面是一些开发者写的代码,我们来看看: 上面的代码有什么错呢? 你答对啦:对齐。 因为这个FILETIME结构体包含两个DWORD部分,所以它只需要4个字节的对齐,...