Vlad Krasnov が質問に対するコメントで述べているように、問題は、コンパイラ (および/またはアセンブラ) が のようなコードの引数のサイズを認識していないことに起因しますadd [esp], 7
。この問題は、たとえばadd [esp], eax
.
If you were the compiler, how would you interpret this instruction? You are asked to add 7 to the memory location ESP is pointing to. But neither 7, nor [esp]
specify how large the arguments for the addition are. A byte? Two bytes? Four bytes? Even 8 bytes would have been a possibility if this wasn't inline assembly (isn't allowed in 64-bit code.)
Note that while ESP is 4 bytes, the memory location it points to can be of any size. The same goes for the immediate value 7, which can fit in any number of bytes.
解決策は、Vlad Krasnov がコメントで再度述べているように、オペランドのサイズを明示的に指定することです。お好みのアセンブラのドキュメントを確認してみてください。この場合、32 ビットの追加が必要な場合は、次のように記述しadd DWORD PTR [esp], 7
ます。これは明らかに[esp]
、メモリ内の DWORD (MASM では 32 ビット) を指していることを示しています。
また、x86 のすべての命令が、即値とメモリ アドレスを含む形式をサポートしているわけではないことに注意してください。各命令について、使用しようとしている命令が実際に存在することを確認するために、" Intel Architectures Software Developer Manual ", volume 2 (命令セットのリファレンス) を確認できます。
また、(インライン アセンブリを使用しているため) コンパイラのアセンブリ出力を常に調べて、コンパイラが生成したコードが実際に意図したものであることを確認する必要があります。アセンブラ コードを生成するようにコンパイラに指示するのは非常に簡単で、非常に読みやすいです。