ablog

不器用で落着きのない技術者のメモ

TAKESAKOさん作のCPUが64bitロングモードで動作しているかどうかをチェックするPerlスクリプト

面白いPerlスクリプトを見つけたのでメモ。

そこで、現在の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 だ。