0

私は次の一連の記事を読んでいます: http://www.altdevblogaday.com/2011/11/09/a-low-level-curriculum-for-c-and-c

表示されている逆アセンブル コードと、同じコードを実行しているときに作成した逆アセンブル コードはかなり異なり、違いを説明する理解がありません。

行ごとにステップスルーして、各ステップで何をしているのかを説明できる人はいますか? 私が行った検索から、最初の数行はフレームポインターと関係があるように感じます。また、逆アセンブルされたコードには、新しい値を配置する前にレジスターが空であることを保証する余分な行がいくつかあるようです (不在)記事のコードから)

XCode 4 内から g++ コンパイラを使用して、OSX (元の作成者は Windows を使用) でこれを実行しています。これらの差異が OS やアーキテクチャ (32 ビットと 64 ビットの違い) によるものであるかどうかについては、私にはまったくわかりません。またはコンパイラ自体。それは私が推測するコードである可能性さえあります-私のものはメイン関数宣言内にラップされていますが、元のコードはこれについて言及していません。

私のコード:

int main(int argc, const char * argv[])
{

    int x = 1;
    int y = 2;
    int z = 0;

    z = x + y;

}

私の逆アセンブルコード:

0x100000f40:  pushq  %rbp
0x100000f41:  movq   %rsp, %rbp
0x100000f44:  movl   $0, %eax
0x100000f49:  movl   %edi, -4(%rbp)
0x100000f4c:  movq   %rsi, -16(%rbp)
0x100000f50:  movl   $1, -20(%rbp)
0x100000f57:  movl   $2, -24(%rbp)
0x100000f5e:  movl   $0, -28(%rbp)
0x100000f65:  movl   -20(%rbp), %edi
0x100000f68:  addl   -24(%rbp), %edi
0x100000f6b:  movl   %edi, -28(%rbp)
0x100000f6e:  popq   %rbp
0x100000f6f:  ret    

元の記事から逆アセンブルされたコード:

mov    dword ptr [ebp-8],1
mov    dword ptr [ebp-14h],2
mov    dword ptr [ebp-20h],0
mov    eax, dword ptr [ebp-8]
add    eax, dword ptr [ebp-14h]
mov    dword ptr [ebp-20h],eax

行ごとの完全な内訳は非常に啓発的ですが、これを理解するための助けをいただければ幸いです。

4

3 に答える 3

2

元の記事のコードはすべてあなたのコードの中にあり、その周りに余分なものがあります。これ:

0x100000f50:  movl   $1, -20(%rbp)
0x100000f57:  movl   $2, -24(%rbp)
0x100000f5e:  movl   $0, -28(%rbp)
0x100000f65:  movl   -20(%rbp), %edi
0x100000f68:  addl   -24(%rbp), %edi
0x100000f6b:  movl   %edi, -28(%rbp)

この記事で説明した 6 つの命令に直接対応しています。

于 2013-02-22T22:29:53.243 に答える
0

まず、「元の記事から」としてリストされているアセンブラーは「Intel」構文を使用しています。投稿の「逆アセンブル出力」は「AT&T 構文」です。%これは、命令への引数の順序が「後ろから前」であることを説明しています[どちらが正しいか間違っているかについて議論するのはやめましょう?] $。また、メモリー位置/レジスターへのオフセットが参照される方法にも違いがありますdword ptr [reg+offs]。Intel アセンブラーlでは、命令のサフィックスとして に変換され、 offs(%reg).

32 ビット対 64 ビットでは、一部のレジスタの名前が変更されます -記事のコード%rbpと同じです。ebp

実際のオフセット (例-20) は、一部にはレジスタが 64 ビットで大きいためだけでなくargcargv関数の引数の一部として関数の開始の一部として格納されているため、異なります-元の感じがあります記事は実際には とは異なる機能を分解していますmain

于 2013-02-22T22:36:36.303 に答える