そこで、現在のCPUが64bitロングモードで動作しているかどうかをチェックする簡単なPerlスクリプトを書いてみました。
...#!/usr/bin/perl use DynaLoader; sub x86_sub { my ($func, $x86) = @_; if ($^O eq "linux") { require 'syscall.ph'; syscall(&SYS_mprotect,(unpack"L",pack"P",$x86)&~4095,4096*2,7); } DynaLoader::dl_install_xsub(caller(0)."::$func",unpack"L",pack"P",$x86); } x86_sub check64bit => do { our $LM64bit = "?"; "\xb8\x31\x00\x00\x00". # mov eax, 0x31 "\x48". # dec eax // 64bit REX PREFIX "\xa2".pack("P",$LM64bit). # mov [$LM64bit], al "\xc3"; # ret }; &check64bit(); warn $LM64bit; # "0" => 32bit, "1" => 64bitこれは、DynaLoader::dl_install_xsubでx86の機械語を直接実行させるサブルーチンを定義して、64bitロングモード特有のREX PREFIXを解釈するかどうかで判別している方法になります。32bitのx86互換モードでは dec eax が実行され $LM64bit='0' となりますが、64bitロングモードではこのような1byte decは解釈されず、直後のmov命令のREX PREFIXを指定することになるので、$LM64bit='1' となります。
したがって、x86_64対応の「Intel(R) Xeon(R) CPU E5430 @ 2.66GHz」が搭載されているマシンでもCentOS 5.2(i386)のような64bitに対応していないOSで動かしてしまっている場合は、32bitと判定されます。
[Debug Hacks] #66.手元のx86マシンが64bitモード対応かどうかを調べる | TAKESAKO @ Yet another Cybozu Labs
...
Mac OS X Leopard on MacBook Air で実行してみると、
% perl check_x86_64.pl
0 at check_x86_64.pl line 27.
当然、32 bit。
明日は Shibuya.pm#11 だ。