NASMは「命令は64ビットモードではサポートされていません」のようなエラーを返し、何をすべきか理解できませんでした。
対象の命令はpop ecx
およびPush ecx
手順。それらの代わりに何を使用できますか、この問題を修正する他の方法はありますか?
一般的な考え方は、通常、フルレジスタ、つまり64ビットモードの64ビットレジスタをプッシュおよびポップすることです。 Push
のデフォルトのオペランドサイズは64ビットであり、32ビットのオペランドサイズは使用できません。 各プッシュ命令はx64で8バイトの倍数をプッシュしますか? (はい、特に16ビットプッシュを使用する場合を除きますが、32ビットは使用できません)。
64ビットモードでは32ビットレジスタをプッシュできません。代わりに、必要な32ビット値を含む64ビットレジスタ全体をプッシュしてポップできるため、Push rax
ではなくPush eax
になります。メモリ参照についても同様です。Push qword ptr[rax]
はできますが、Push dword ptr[rax]
はできません。
しかし:64ビットモードでもプッシュできます:
8または32ビットの即値符号が64に拡張されました。これは通常、最適化としてアセンブラーによって自動的に処理されます(Push 1
を実行すると、最もコンパクトなエンコードでエンコードされます。これは6A01
になります。つまり、imm8オペランド)。これは アセンブラが選択する幅の幅に関係なく、Push Word 1
を明示的に指定しない限り、常に64ビットのプッシュです。
fs
およびgs
セグメントレジスターレジスターcs
、ds
、es
、ss
レジスター(64ビットモードでは重要ではなく、 mov
ではなく Push
で読み取られ、将来の使用のためにこれらのプッシュ/ポップオペコードが解放されます)。
例外として、セグメントレジスタはzeroで拡張されるか、16ビットの移動でスタックにプッシュされます(つまり、スタックの他の48ビットは未変更のまま); pop fs
およびpop gs
はこれらの余分なビットを破棄するだけなので、これはそれほど問題ではありません。
Push imm64
はPush low32
/mov dword [rsp+4], high32
でエミュレートできます。またはmov r64, imm64
/Push r64
; (メモリではなく)mov
は、64ビットの即値を取得できる唯一のx86-64命令です。
16ビットのオペランドサイズ(66h
接頭辞)を使用すると、RSPを8ではなく2に調整する16ビットのプッシュを実行できますが、通常は、これを行わないでください。 16ビットポップまたはその他の方法で修正します。
Push ax
)およびメモリ参照(Push Word ptr[rax]
);8ビットレジスタはどのモードでもプッシュできません(より広いレジスタの一部を除く)。64ビットモードでは32ビットは使用できません プレフィックスREX.W=0
を付けても 。