GNU アセンブラ用の x64 アセンブリを書いています。.seh_ * ディレクティブについて調べてみましたが、それらに関する情報があまり見つかりません。ドキュメントはそれらgas
についてまったく言及していません。
しかし、私が理解しているように、SEH アンワインド操作中にコードがスタックにある可能性がある場合は、これらを使用することが期待されています。また、私のコードは操作をスタックし、他の関数を呼び出すため、SEH の可能性があるため、これらを使用する必要があります。
ほとんどの場合、私はそれが正しいと思います:
.seh_proc FCT
FCT:
push %rbp
.seh_pushreg %rbp
mov %rsp, %rbp
.seh_setframe %rbp, 0
push %r14
.seh_pushreg %r14
lea -(iOffset + iBytes)(%rsp), %rsp
.seh_stackalloc iOffset + iBytes
andq $-16, %rsp <---- But what about this?
.seh_endprologue
etc...
しかし、はっきりしない点が 1 つあります。私はこの指示を持っています:
andq $-16, %rsp
スタックアライメントを実行していることをSEHに伝えるにはどうすればよいですか?これにより、スタックが 15 バイト (ほとんどありません) から 8 バイト (非常に可能性が高い)、0 バイト (確かに可能) に調整される可能性があります。実際の金額は実行時まで決定されない可能性があるため、行き詰まっています。
.seh 命令をスキップできると思いますが、そこで 8 バイトのスタックが予約された場合、アンワインドを破棄した可能性がありますね。それはここでの目的全体を無効にしませんか?
または、アライメントを省略できます。しかし、他の関数 (memcpy など) を呼び出した場合、スタックを整列する必要はありませんか? MSによると:
スタックは、プロローグ内を除いて、常に 16 バイトでアラインされた状態に維持されます。
たぶん、これで自分のやり方を「推論」できますか?私を呼んだ人が正しいことをした場合 (もし...)、彼がしたときにスタックが整列していたcall
ので、今では 8 バイト (戻りアドレス) とプロローグで行ったことは何でもずれています。私はこれに頼ることができますか?壊れやすいようです。
私は他のコードを調べてみましたが、私が見ているものを信頼できるかどうかはわかりません. .seh_ gas
* の誤用によるエラーを報告しているとは思えません。おそらく、実際の例外が発生しているときに問題が発生するだけです (常にそうであるとは限りません)。
これをやるなら、ちゃんとやりたい。スタックの配置は一般的なことのように思われるので、誰かがここで解決策を持っている必要があります. 私はそれを見ていません。