NSIS脚本源码分析: 如何判断CPU平台类型

来源:互联网 发布:数字域名最贵的是哪些 编辑:程序博客网 时间:2024/06/03 07:59

做安装程序时,有时需要支持多个CPU平台。Windows下支持的CPU平台一般有三大类:x86, x64和ia64。

其中,x86就是我们最常用的32位平台,x64则是64位的x86平台,ia64比较特殊,它只存在于Intel Itanium系列芯片中。

好了,下面上源码了:



看到上面的代码是否有点云里雾里的感觉?反正第一眼看过去,我的感觉就是这样。不过,不要急,慢慢地一句一句地分析,自然会将它搞明白的。

首先看前两句:



System是NSIS的一个标准插件,可以在NSIS安装目录的Plugins子目录下可以找到,System.dll是也。System是NSIS中的一个很重要的插件,安装中的很多高级功能都是通过它来实现的。System::Alloc也就是调用System插件的Alloc接口函数。

System插件的文档可以参考:中文文档,英文文档

其实这两句的意思很简单,就是分配32字节的地址空间并将空间地址保存到寄存器r0。可以想象得到,System::Alloc的返回值是压入到堆栈中的,所以要用Pop指令去将它取出来。至于为什么要分配32个字节呢,下面将会说明。

再看下一句:

System::Call "Kernel32::GetNativeSystemInfo(i) v (r0)"

System::Call是System插件中的一个函数调用接口,看到Kernel32::GetNativeSystemInfo,我们就知道它要调的是Windows API GetNativeSystemInfo。那么就将这个API的声明调出来看看:

void GetNativeSystemInfo( LPSYSTEM_INFO lpSystemInfo );

原来,这个API只有一个参数 -- 指向一个名为SYSTEM_INFO结构的指针。这个结构又是怎么样的呢,再看:



这个结构中我们感兴趣的是字段wProcessorArchitecture,这个字段可能有如下几种取值情况:



好,看看这个调用的后面参数部分:“(i) v (r0)”,这究竟是什么意思呢?

原来,(i)指的是参数类型,v 表示返回值是void类型,r0 表示指针地址。从上面就可以看出 r0 实际上指的是这个结构的地址,这个地址的空间大小是32。

再继续看:

System::Call "*$0(&i2 .r1)"

说NSIS脚本难以理解,主要就是因为它的插件调用参数字符串太难懂了。象这一句,参数就象天书一样。还好,NSIS参考文档网络上有很多,再不济还是有源代码参考的,这就是开源的好处了。

*$0 表示以寄存器0地址空间的结构,&i2 表示是2字节整数,.r1 表示这个2字节整数的值要存放到寄存器1去。

下一句:

System::Free $0

这应该很好理解,就是将寄存器0的地址空间释放掉。

详细解释前面的语句了,后面的应该不难理解。StrCmp $1 9 0 +2的意思就是看寄存器1的值是否等于PROCESSOR_ARCHITECTURE_AMD64(9),若相等则执行下一句,若不等则执行下下句。这里需要注意的是,StrCmp不光是指字符串比较,数字比较它也兼任了。