1

インライン アセンブリにいくつかのセクションがある Windows 32 ビット プログラムを作成しています。このプログラムは、32 ビットおよび 64 ビット システムで実行することを想定しています。両方のシステム用に 32 ビット バージョンをコンパイルしています。

私の質問は、スタック幅が 4 バイト幅であると想定していることです。32 ビット プログラムを 64 Windows システムで実行すると、スタック幅は 4 バイトのままですか?

私のプログラムでは(これは簡略化されたバージョンです)スタックにいくつかの値をプッシュしています:

for (i=0;i<4;i++)   
    {
    _asm 
        {
        mov ebx,i   ; push 0,1,2,3 on the stack
        push ebx
        }
    }

後で、次のようなコードを使用して値を照会しています。

ii=0;
for (i=0;i<5;i++)   
    {
    _asm 
        {
        mov ebx,ii   ; ii has 0, then 4, then 8 ...
        mov eax,dword ptr [esp+ebx]     ; peek values on the stack from the top
        mov num1,eax
        }
   ii+=4;   // here I am assuming stack width is 4 bytes  
   // -- do something with num1 --//
    }
4

2 に答える 2

1

64 ビット システムが 32 ビット バイナリと下位互換性を持つメカニズムを提供すると仮定すると、スタックは依然として 32 ビット幅です。

Windows x64 システムはその 1 つです。

于 2012-10-23T18:20:26.750 に答える
1

とにかく、スタックには実際には「幅」がありません。ただのバイトです。スタック ポインターは位置合わせされていることが期待される場合がありますが、スタック自体は単なるバイトです。そのスペースを好きなように使うことができます。手動で操作rSPして、必要に応じて位置をずらすことができます (これは問題を引き起こす可能性がありますが、それでも可能です)。任意のオフセットで、またはスタック ポインターを超えて、スタックから直接読み取り/書き込みを行うことができます。

基本的に、ルールはなく、システムの残りの部分による仮定のみがあります。コードがこれらの仮定を満たさない場合、問題が発生する可能性がありますが、スタック ポインターから 3 を減算し、作成したばかりのスペースに 5 バイトを書き込むことを止めるものは何もありません (明らかに、すべてが収まるわけではありません)。

しかし、あなたが実際に求めているように見えるのは、互換モードでdwordをプッシュしますか?push r32

はい、そうです。実際、すべての状況で常にそうであるか、またはアセンブルに失敗します。書き込んpush r32で「誤って」qwordpush r32をプッシュすることはできません-64ビットモードではエンコードできません。

その動作はオペレーティング システムに依存しません。

また、通常の 32 ビット モード、互換モード、および 64 ビット モードでも、単語をプッシュおよびポップできます。そして、前に言ったように、先に進んで、スタック ポインターを使って何でもすることができます。

于 2012-10-23T18:38:19.407 に答える