アセンブラ命令

もくじ
https://tera1707.com/entry/2022/02/06/144447

ダンプ関連記事

https://tera1707.com/entry/2022/02/06/144447#WindowsDump

やりたいこと

以前の記事で、WinDBGで.NETアプリのクラッシュダンプを解析したが、 そのときにアセンブラを見ないといけなかった。

その際に調べたことをメモしておく。 (まだ経験値が低いので、正確ではない可能性あり)

使用したアセンブラ命令(x64)

push    rbp
→rbpをスタックに積む(rspを更新(+8))
※メソッドを呼んだ頭の部分で、必ずpush rbpをやるっぽい。
sub     rsp,10h
→rspから0x10減算する
lea     rbp,[rsp+10h]
→rbpにrsp+10h番地を入れる
xor     eax,eax
→XORをとる。同じレジスタ同士のXORは毎回0なので、0クリアするときにこれやるっぽい。
mov     dword ptr [rbp-4],eax
→rbp-4番地の値をeaxにする。(C言語の*(rbp-4)=*eax、みたいなものっぽい)
idiv    eax,dword ptr [rbp+20h]
→eaxを[rbp+20h]番地にある値で割って、eaxに入れる
add     eax,2
→eaxに2を足して、eaxに入れる
pop     rbp

メモ

マネージドコードの呼び出し規約は _CLRCALL規約 という。 (そのほかの呼び出し規約には_cdeclstdcallなどがある。→参考)

アセンブラのコードを見たときに、例えば何かのメソッドが呼ばれるときに、

  • どこのレジスタにどういう値が入ってくるか、とか、
  • ローカル変数がどこに入るか、とか

が、呼び出し規約によって変わってくる。

レジスタには、いろんな種類がある。→参考

「R」がつくレジスタは、64bitのレジスタ

_CLRCALL規約では、 メソッドを呼んだときのアセンブラで、

  • 引数の1個目は「EDX」
  • 引数の2個目は「R8D」
  • 引数の3個目は「R9D」

に入る。

[rbp+25h]という書き方は、
rbpの値+25h番地のアドレス、ということを表す。

dword ptr[rbp+25h]という書き方は、
rbp+25h番地にあるdwordの値、ということを表す。

アセンブラは、

  • 左側がデスティネーションレジスタ
  • 右側がソースレジスタ

を表す。例えば

MOV m, rax

だったら、右に書かれたrax(RAXレジスタ)から、左に書かれたメモリに、値をコピーする、ということを表す。

RBPはそのメソッドにいる間は同じ。 RSPはメソッド内でpushがされたら積んだ分(+8)更新される。

参考

呼び出し規約の種類

https://learn.microsoft.com/ja-jp/cpp/cpp/argument-passing-and-naming-conventions?view=msvc-170

レジスタの説明など(x64)

https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/x64-architecture

アセンブラ命令の説明(x64)

https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/x64-instructions

アセンブラ命令の説明(x86)

https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/x86-instructions

レジスタの説明

https://ja.wikibooks.org/wiki/X86%E3%82%A2%E3%82%BB%E3%83%B3%E3%83%96%E3%83%A9/x86%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3