次のようなコードが表示されます。
mov ax, cs
mov ds, ax
mov es, ax
これを次のように圧縮できないのはなぜですか。
mov ds, cs
mov es, cs
アキュムレータレジスタを使用してから最初の方法は高速ですか?しかし、csとdsはセグメントレジスタであるため、これは直感的には思えません。それとも私が気付いていない制限がありますか?
ちなみに私はnasmを使用しています。
次のようなコードが表示されます。
mov ax, cs
mov ds, ax
mov es, ax
これを次のように圧縮できないのはなぜですか。
mov ds, cs
mov es, cs
アキュムレータレジスタを使用してから最初の方法は高速ですか?しかし、csとdsはセグメントレジスタであるため、これは直感的には思えません。それとも私が気付いていない制限がありますか?
ちなみに私はnasmを使用しています。
セグメントレジスタをセグメントレジスタに移動することはできません。そのための指示はありません。
プロセッサには、すべての命令のためのマイクロコードのための余地があまりありません。そのため、まれにしか使用されない操作、レイク変更セグメントレジスタでは、1つの一般的な命令がいくつかの特別な目的の命令よりも好まれることがよくあります。また、一部のプロセッサでは、命令の数がアーキテクチャによって完全に制限されています。たとえば、元の8080プロセッサはすべて1バイトでオペコードをエンコードする必要があるため、256命令に制限されていました。
Intel ManualVolume2命令セットリファレンス-325383-056US2015年9月「MOVMove」列「Instruction」を参照してください。
レジスタへの唯一の16ビットmovは、次のようにエンコードされます。
mov r/m16, Sreg
また、「オペコード要約表の3.1.1.3命令列」では、次のように説明しています。
したがってmov ds, cs
、バージョンがないため、エンコードできませんmov Sreg, Sreg
。
これらの操作を妨げるのは、実際にはアセンブリ言語ではなく、基盤となる機械語です。
アセンブリは読みやすい単語やニーモニックで構成されていますが、実際にはマシンコードの1と0を直接表しています。x86 CPUでは、各命令は通常、個々のバイトまたは意味を持つバイト内のビットを含む一連のバイトで構成されます。特定のビットは命令を表し、他のビットはアドレッシングモードを表します。mov
例のようなレジスタアドレッシングモードでは、いくつかのビットは、命令のソースおよびデスティネーションとして使用される特定のレジスタを表します。
現在、x86ファミリのプロセッサは、CPUアーキテクチャが単純だった1970年代にまでさかのぼります。当時、アキュムレータの概念は非常に重要でしax
た-16ビットx86アキュムレータです。すべての計算はこのレジスタに蓄積または「蓄積」されているため、すべての命令で使用できます。他の汎用レジスターは、より制限された使用範囲を持っていました。
命令はバイトに基づいているため、命令のデコードを高速に保つために、命令を表すバイトをできるだけ少なくする必要があります。できるだけ多くの命令を短くするために、アキュムレータの使用が中心になります。
Motorola 680x0などの最新のCPUでは、より汎用的なレジスタに、以前はアキュムレータのドメインであったより多くの機能があります。RISC CPUでは、すべてのレジスタがアキュムレータと同じくらい柔軟です。64ビットモードでは、現在のx86/amd64命令セットの制限が大幅に緩和されていると聞きました。