アセンブリ言語のプログラムは、実行速度に関して処理系の影響を受けにくく、実行環境からの影響は直接的でわかりやすい。そのため、実行時間の予測がしやすく、時間のかかる部分を容易に発見して修正することができる。また、ソースコードを表示できるような高級なデバッガが使えないときでも、デバッグが簡単である。
アセンブリ言語でプログラム全体を記述するなら、そこには高級言語で見えたのとは別の世界が広がっている。
この文章では、AMD64がx86から拡張された部分の概要を説明した後、AMD64を実装するプロセッサの特性を紹介する。
longモードでは、割り込みハンドラは64ビットモードで呼び出され、ページテーブルやTSSの構造もlegacyモードとは異なるため、longモード用のシステムソフトウェアを用意する必要がある。システムソフトウェアで適切にサポートするなら、compatibilityモードで4GBを超える物理メモリを使用したり、x86のプロテクトモード用のアプリケーションプログラムと64ビットモード用のアプリケーションプログラムを並行して実行させたりすることができる。
各モードの特徴をまとめると次のようになる。
モード | アドレスサイズ | オペランドサイズ | 汎用レジスタ数 | 物理アドレス空間 | 使用可能なリニアアドレス空間 | セグメントベースアドレス | セグメントリミット | ||
---|---|---|---|---|---|---|---|---|---|
longモード | 64ビットモード | 64/32 | 32/16/64,8 | 16 | 2^52 #1 | 2^48 #1 | 0 #2 | 2^64-1 | |
compatibilityモード | 32 | 32/16 | 32/16,8 | 8 | 2^32 | セグメントディスクリプタによる | |||
16 | 16/32 | 16/32,8 | |||||||
legacyモード | プロテクトモード | 32 | 32/16 | 32/16,8 | 2^32/2^40/2^52 #3 | ||||
16 | 16/32 | 16/32,8 | |||||||
仮想86モード | 2^20+HMA | セグメント値×16 | 2^16-1 | ||||||
リアルモード | 2^20+HMA #4 |
各モードの区別は次のビットで行う。
以下の各節では、主に64ビットモードで追加・拡張された機能について解説する。
64ビットの汎用レジスタはRAX,RCX,…で、下位半分が従来のEAX,ECX,…に相当する。追加された8本の汎用レジスタは、R8,R9,…,R15で、下位32ビットがR8D,R9D,…、下位16ビットがR8W,R9W,…、下位8ビットがR8B,R9B,…である。なお、SP,BP,SI,DIの下位8ビットは、SPL,BPL,SIL,DILとして使うことができる(後述のREXプリフィックスを使用したとき)。逆に、R8,R9,R10,R11のビット8-15を8ビットレジスタとして使うことはできない。
この文章で扱うレジスタをまとめると、次のようになる。
オペランドサイズあるいはアドレスサイズによって、RAX,RCX,…またはEAX,ECX,…が使われる場合、rAX,rCX,…と表記する。R8,R9,…またはR8D,R9D…が使われる場合(さらにR8W,R9W,…とR8B,R9B,…を含むこともある)、r8,r9,…と表記する。
汎用レジスタの下位32ビットに書き込むと、上位32ビットは0になる。例えば、 MOV EAX,EAX は、RAXの上位32ビットをクリアする。16,8ビットの書き込みでは、残りの部分は変更されない。
以上をまとめると次のようになる。
REX - 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F r/m,baseにr8-r15 × × ○ × ○ × ○ × ○ × ○ × ○ × ○ × ○ r/mにSPL,BPLなど × ○ -- ○ -- ○ -- ○ -- ○ -- ○ -- ○ -- ○ -- indexにr8-r15 × × × ○ ○ × × ○ ○ × × ○ ○ × × ○ ○ regにr8-r15 × × × × × ○ ○ ○ ○ × × × × ○ ○ ○ ○ regにSPL,BPLなど × ○ ○ ○ ○ -- -- -- -- ○ ○ ○ ○ -- -- -- -- 64ビットオペランド × × × × × × × × × ○ ○ ○ ○ ○ ○ ○ ○
この章では今後、必要なビットだけが1になっているREXプリフィックスを代表として「REX=44」のように示す。複数の機能を組み合わせるときには、ORをとって一つのREXプリフィックスにする。
命令中の即値や変位は、いくつかの例外を除いて最大32ビットである。例外とは、A0h-A3hとB8h-BFhの各命令である。
ModR/Mバイトのregフィールドは、オペランドサイズに応じて、次のように解釈される。
size reg 00 08 10 18 20 28 30 38 8 - AL CL DL BL AH CH DH BH REX=40 AL CL DL BL SPL BPL SIL DIL REX=44 R8B R9B R10B R11B R12B R13B R14B R15B 16 - AX CX DX BX SP BP SI DI REX=44 R8W R9W R10W R11W R12W R13W R14W R15W 32 - EAX ECX EDX EBX ESP EBP ESI EDI REX=44 R8D R9D R10D R11D R12D R13D R14D R15D 64 - RAX RCX RDX RBX RSP RBP RSI RDI REX=44 R8 R9 R10 R11 R12 R13 R14 R15表には示さないが、XMM8、CR8、DR8なども同様である。
ModR/Mバイトのmodフィールドとr/mフィールドは、オペランドサイズに応じて、次のように解釈される。SIBについては後述する。
r/m - REX=41 r/m - REX=41 r/m - REX=41 r/m - REX=41 00 [rAX] [r8] 40 [rAX+disp8] [r8+disp8] 80 [rAX+disp32] [r8+disp32] C0 AL/AX/EAX/RAX r8 01 [rCX] [r9] 41 [rCX+disp8] [r9+disp8] 81 [rCX+disp32] [r9+disp32] C1 CL/CX/ECX/RCX r9 02 [rDX] [r10] 42 [rDX+disp8] [r10+disp8] 82 [rDX+disp32] [r10+disp32] C2 DL/DX/EDX/RDX r10 03 [rBX] [r11] 43 [rBX+disp8] [r11+disp8] 83 [rBX+disp32] [r11+disp32] C3 BL/BX/EBX/RBX r11 04 [SIB] [SIB] 44 [SIB+disp8] [SIB+disp8] 84 [SIB+disp32] [SIB+disp32] C4 AH#b/SP/ESP/RSP r12 05 [RIP+disp32]#a 45 [rBP+disp8] [r13+disp8] 85 [rBP+disp32] [r13+disp32] C5 CH#b/BP/EBP/RBP r13 06 [rSI] [r14] 46 [rSI+disp8] [r14+disp8] 86 [rSI+disp32] [r14+disp32] C6 DH#b/SI/ESI/RSI r14 07 [rDI] [r15] 47 [rDI+disp8] [r15+disp8] 87 [rDI+disp32] {r15+disp32] C7 BH#b/DI/EDI/RDI r15 #a REX.Bに関係なくRIP相対 #b REX.Bが0のREXプリフィックスを使用すると、順にSPL,BPL,SIL,DILModR/Mバイトのr/mフィールドが、SIBを使用することを示してしているとき、SIBバイトのbase,index,scaleの各フィールドはそれぞれ次のように解釈される。
[SIB] [SIB+disp8] [SIB+disp32] base - REX=41 - REX=41 - REX=41 00 rAX r8 rAX r8 rAX r8 01 rCX r9 rCX r9 rCX r9 02 rDX r10 rDX r10 rDX r10 03 rBX r11 rBX r11 rBX r11 04 rSP r12 rSP r12 rSP r12 05 disp32#c rBP r13 rBP r13 06 rSI r14 rSI r14 rSI r14 07 rDI r15 rDI r15 rDI r15 #c REX.Bに関係なく直接アドレス index 00 08 10 18 20 28 30 38 - rAX rCX rDX rBX -#d rBP rSI rDI REX=42 r8 r9 r10 r11 r12 r13 r14 r15 #d [rSP]、[r12]、および[disp32]のために使う scale 00 40 80 C0 *1 *2 *3 *4
結局、メモリオペランドについては次のようなアドレシングモードがあることになる。
[base] baseはrBP,r13以外 [RIP+disp32] [disp32] [base+disp] [base+index*scale] baseはrBP,r13以外 [index*scale+disp32] [base+index*scale+disp] baseはベースレジスタ(全汎用レジスタ) indexはインデックスレジスタ(rSP以外) scaleはスケール(1,2,4,8) disp32は32ビットの変位(符号つき定数) dispは8または32ビットの変位(符号つき定数)注意するべき点は次の通りである。
64ビットオペランドであっても、即値のエンコーディングは32ビットであり、符号拡張されて使用される。
64ビットオペランドに対するシフトカウントは、下位6ビットが有効になる。
BSWAP命令
JMP,CALL,Jcc
CMOVで32ビットオペランドサイズのとき、条件が偽であっても転送先レジスタの上位32ビットはクリアされる。
CMPXCHG8B命令は追加された命令のCMPXCHG16B命令を参照。
CPUID命令のオペランドサイズは32ビット固定で、64ビットを指定しても無視される。
ENTER,LEAVE命令のオペランドサイズは64ビット固定である(32ビットはエンコードできない)。
INのオペランドは8,16,32ビットまで? OUTも? INS,INSW,INSD,OUTS,OUTSW,OUTSD
LFS,LGS,LSS命令のオペランドサイズは32ビット固定?
MMX命令のMOVD命令は、64ビットとしても使える。
PUSH,POPはデフォルト64ビットだが、16ビットにもできる(RSPも2ずつ増減)。
RET nearは64ビット固定
RET farはデフォルト32ビットだが、64ビットにもできる
VERR,VERW命令は16ビット固定
NOP(90h)は、 XCHG EAX,EAX とは異なる動作になる。後者は上位32ビットをクリアする。
MOVSXD CDQE CMPSQ IRETD,IRETQ JRCXZ LODSQ MOVSQ POPFQ PUSHFQ SCASQ STOSQ SWAPGS SYSCALL SYSRET
CMPXCHG16B命令は、CMPXCHG8B命令にREXプリフィックスをつけて64ビットにしたものである。CPUID命令のCMPXCHG16Bビットが1の場合に利用でき、そうでない場合は無効命令例外が発生する。
AAA,AAS,AAM,AAD命令
BOUND命令
CALL,JMP命令のうちfar絶対
DAA,DAS命令
INTO命令
LAHF,SAHF命令(CPUID命令のLahfSahfビットが1の場合は使用できる。Errata 110の影響で、使用できるのにこのビットが0の場合があるが、通常はファームフェアで修正されている)
LDS,LES命令
PUSH ES/CS/SS/DS、POP ES/SS/DS
PUSHA,PUSHAD,POPA,POPAD命令
オペコード82h(80hの別名)
SALC(ドキュメント化されていない命令)
ARPL命令(MOVSXD命令になる)
命令長1バイトのINC,DEC命令(REXプリフィックスになる)
SYSENTER,SYSEXIT命令はlongモードで使用できない
同じFamilyの中でも製品によって、コア数、キャッシュサイズなどが異なる。特にFamily 0Fhでは、Revisionによって拡張命令などのサポート状況が異なる。
以下はAMD64を搭載する主なプロセッサの仕様である。 (準備中)
コア数 L2キャッシュ メモリの種類 製品名 コードネーム L3キャッシュ チャンネル数 Family/Revision Opteron SledgeHammer 1 1MB DDR 2 0Fh/C Opteron 8xx Athenes Opteron 2xx Troy Opteron 1xx Venus Athlon 64 FX SledgeHammer 1 1MB DDR 2 0Fh/C Athlon 64 ClawHammer 1 1MB/512KB DDR 1 0Fh/C Athlon 64 Newcastle 1 512KB DDR 2 0Fh/C Athlon 64 Winchester 1 512KB DDR 2 0Fh/D Athlon 64 FX San Diego 1 1MB DDR 2 0Fh/E Athlon 64 Venice 1 1MB/512KB DDR 2 0Fh/E Athlon 64 FX/X2 Toledo 2 1MBx2 DDR 2 0Fh/E Athlon 64 X2 Manchester 2 512KBx2 DDR 2 0Fh/E Athlon 64 FX/X2 Windsor 2 1MBx2/512KBx2 DDR2 2 0Fh/F Athlon 64 Orleans 1 1MB/512KB DDR2 2 0Fh/F Athlon (64) X2 Brisbane 2 512KBx2 DDR2 2 0Fh/G Athlon (64) Lima 1 512KB DDR2 2 0Fh/G Phenom X4 Agena 4 512KBx4 2MB DDR2 2 10h Phenom X3 Toliman 3 512KBx3 2MB DDR2 2 10h Athlon X2 Kuma 2 512KBx2 2MB DDR2 2 10h Phenom II X4 Deneb 4 512KBx4 6MB DDR2/3 2 10h Phenom II X3 Heka 3 512KBx3 6MB DDR3 2 10h Phenom II X2 Callisto 2 512KBx2 6MB DDR3 2 10h Athlon II X4 Propus 4 512KBx4 DDR3 2 10h Athlon II X3 Rena 3 512KBx3 DDR3 2 10h Athlon II X2 Regor 2 1MBx2 DDR3 2 10h Phenom II X6 Thuban 6 512KBx6 6MB DDR3 2 10h AMD A-Series Llano 4 1MBx4 DDR3 2 12h AMD C-Series Ontario 2 512KBx2 DDR3 1 14h AMD E-Series Zacate 1/2 512KBx1/2 DDR3 1 14h AMD FX-Series Zambezi 8 2MBx4 DDR3 2 15h 低電圧版モバイルAthlon 64 Oakville Turion 64 Lancaster 1 1MB/512KB DDR 1 0Fh/E Turion 64 X2 Taylor 2 0Fh/F Turion 64 X2 2 0Fh/G Turion X2 Ultra Griffin 2 11h Turion II 2 10h
この文章の各章に対する参照箇所は次のとおりである。