x64
読み:エックスろくよん
外語:x64
x86
の命令セットアーキテクチャーを64ビットに拡張したものの俗称。
目次
概要
呼称
由来
現状
特徴
拡張点
追加された命令
使用できない命令
空きオペコード
補足
オペコード
inc/dec命令
概要
16ビットから始まったx86の命令セットアーキテクチャーは、
i386
から命令セットの大枠は維持したまま32ビット化され「
IA-32
」になった。
そこで、従来のIA-32の延長線上にある64ビット命令セットも同様に「IA-64」と呼びたいところだが、
Intel
は64ビット化は非互換の命令セットに移行する計画を立て、これに「
IA-64
」と命名していた。
結果として「IA-64」は失敗に終わるが、しかしこの理由により「IA-64」という名が使えないことになったため、その代替として使われるようになった語の一つが「x64」である。
呼称
由来
AMDやIntel、他にVIAなども、64ビット機能については各メーカーが独自の呼び方をしていた。
従来の
IA-32
の延長線上にある64ビット命令セットは、
AMD
は
AMD64 ISA
(旧称
x86-64
)、
Intel
は
Intel 64
(旧称
EM64T
)と呼んでいる。
現状
その源流がAMD64にあることは自明であるが、これにはAMDという企業名が含まれるため、「中立的な呼称」が求められた。
AMDが当初使っていた「
x86-64
」が使われることもあったが、従来の「x86」と同じ文字数で、かつ似た名称である「x64」がやがて普及するようになった。
Microsoft
や
Oracle
などが使用していることから、半ば業界標準の呼称であるとも言える。
特徴
以下は、AMD64 ISA、Intel 64ともに共通する。
拡張点
ロングモード環境では、次のような特徴を有する。
64ビットのフラット仮想アドレッシング
従来の8個のレジスター(EAX/ECX/EDX/EBX/ESP/EBP/ESI/EDI)の64ビット化
新たな8個のレジスター(R8〜R15)の追加
命令ポインターは32ビットから64ビットに拡張
8個の新たなSSEレジスター(XMM8〜XMM15)を追加
追加された命令
REX.W
は、REXプリフィクスのWフィールドが1となるバイト。他のフィールドが0なら48hだが、他のフィールド次第で、48hから4fhまで変化する。
movsxd r64,r/m32 REX.W 63 /r : ダブルワードをクアッドワードに符号拡張して転送する
cdqe REX.W 98 : EAXを符号拡張してRAXに設定
cqo REX.W 99 : RAXを符号拡張してRDX:RAXに設定
cmpsq REX.W A7 : 文字列オペランド比較
iretd 66 CF
iretq REX.W CF
jrcxz E3 cb : jcxz(CX)、jecxz(ECX)に対し、64ビットのRCXでの比較
lodsq REX.W AD : rax = [rsi++]
movsq REX.W A5
popfq 9D : popfdは66 9D
pushfq 9C : pushfdは66 9C
scasq REX.W AF
stosq REX.W AB
swapgs 0F 01 F8
syscall
0F 05
sysret 0F 07
cmpxchg16b REX.W 0F C7 (CPUID命令のCMPXCHG16Bビットが1の場合のみ)
movzx r64,r/m32 (64ビット) REX.W 0F B7 /r : ダブルワードをクアッドワードにゼロ拡張して転送する
使用できない命令
10進演算命令(daa、das、aaa、aas、aam、aad)
arpl (オペコードはmovsxd命令に使われている)
bound
call farptr/jmp farptr
into
lahf
/
sahf
(cpuid命令のLAHF/SAHFビットが1の場合は使用可)
lds/les
push cs/ds/es/ss、pop ds/es/ss
pusha/pushad/popa/popad
setalcないしはsalc (非ドキュメント命令、正式ニーモニックは不明)
sysenter
/sysexit (longモードで使用不可、但しIntel 64は利用可能)
1バイトオペコードのinc/dec (オペコード4xh、
REXプリフィックス
になるため)
オペコード82h (80hの別名)
空きオペコード
64ビットで無効命令となった1バイトオペコードのうち、割り当てが決まっていないものには以下のものがある。
27h DAA
2Fh DAS
37h AAA
3Fh AAS
D4h AAM ib
D5h AAD ib
将来的に、何らかの拡張に使われると思われる。
補足
オペコード
具体的には、ロングモードでは標準で32ビットレジスター参照となり、従来の32ビット動作と互換性がある。
例えば、次の命令を例とする。
01 C3 ‐ ADD EBX, EAX
16ビットの場合は「66」の
プリフィックス
を付ける。ここまではIA-32と同様である。
66 01 C3 ‐ ADD BX, AX
64ビット演算の場合は、
REXプリフィックス
を付けてビット長を制御する。この点がIA-32との違いである。例えば「48」のプリフィックスを付けると、次のようになる。
48 01 C3 ‐ ADD RBX, RAX
この目的のため、1バイト目が40H〜4FHの範囲は、従来のx86命令と互換性がない。
なお、8ビットの場合はIA-32と同様、1バイト目のWフィールドを0にして表現する。
00 C3 ‐ ADD BL, AL
inc/dec命令
REXプリフィックスのため、0x40〜0x4fから始まる旧来のx86命令(inc reg16、dec reg16)はロングモードでは使用できず、これはロングモードでは別の機械語コードを使用する。
8ビット
FE /0 : inc r/m8
FE /1 : dec r/m8
16ビット
66 FF /0 : inc r/m16
66 FF /1 : dec r/m16
32ビット
FF /0 : inc r/m32
FF /1 : dec r/m32
64ビット
REX.W
FF /0 : inc r/m64
REX.W FF /1 : dec r/m64
例えば、40のinc eaxは、AMD64 ISAではFF C0になる。この2バイトでの表現は従来のx86から存在したが、冗長となるため従来は使われていなかったものである。
プログラム動作中にロングモードかどうかを確認するには、
IA32_EFER
レジスターのビット8を参照し(但し特権命令(RING 0)でないと参照できない)、ここが1ならロングモードと判断する。
再検索