0

ここにループがあることは知っていますが、何が起こっているのか理解できません。もっと正確に言うと、最初の3行で何が起こっているのでしょうか。

0x08048d45 <phase_2+42>:        lea    -0x14(%ebp),%ebx
0x08048d48 <phase_2+45>:        mov    -0x8(%ebx),%eax
0x08048d4b <phase_2+48>:        add    -0x4(%ebx),%eax
0x08048d4e <phase_2+51>:        cmp    %eax,(%ebx) //compare register values
0x08048d50 <phase_2+53>:        je     0x8048d57 <phase_2+60> // if true, jump to 0x08048d57
0x08048d52 <phase_2+55>:        call   0x8049155 <func> //calls func otherwise
0x08048d57 <phase_2+60>:        add    $0x4,%ebx //add 4 to ebx
0x08048d5a <phase_2+63>:        lea    -0x4(%ebp),%eax
0x08048d5d <phase_2+66>:        cmp    %eax,%ebx //compare register values
0x08048d5f <phase_2+68>:        jne    0x8048d48 <phase_2+45> // if true, jump to 0x08048d48 
4

2 に答える 2

3
lea    -0x14(%ebp),%ebx

これは効果的に行い%ebx = %ebp - 0x14ます。Load Effective Address命令は、非常に高速で単純な数学演算を実行する能力のために悪用されることがよくあります。

mov    -0x8(%ebx),%eax

これは%eax = *(%ebx - 0x8)、つまり、に値をロードし%ebx - 0x8ます%eax

add    -0x4(%ebx),%eax

これはし%eax += *(%ebx - 0x4)ます。

cmp    %eax,(%ebx) //compare register values
je     0x8048d57 <phase_2+60> // if true, jump to 0x08048d57
call   0x8049155 <func> //calls func otherwise

これらの3つの命令は同等ですif (%eax != *%ebx) func();

add    $0x4,%ebx //add 4 to ebx

これはし%ebx += 4ます。

lea    -0x4(%ebp),%eax

これはを計算し%eax = %ebp - 0x4ます。

cmp    %eax,%ebx //compare register values
jne    0x8048d48 <phase_2+45> // if true, jump to

これらの2つはに等しいdo { ... } while (%eax != %ebx)です。

%ebpベースポインタです。これは、呼び出し元のスタック(上位の関数)と呼び出し先のスタック(現在の関数)の間の分割点を指します。その上には、それ自体の保存された値、この関数への戻りアドレスと引数があります(レジスタ呼び出し規約が使用された場合を除く)。その下にはローカル変数があるため%ebp - 0x14、32ビット整数の配列へのポインターである可能性があります。これは、%ebx後で段階的にインクリメントされ4、整数の加算が使用されるためです。アセンブリコード全体は、Cで同様のものに変換される必要があります。

int arr[6];

for (i = 0; i < 4; i++)
{
   if (arr[i] + arr[i+1] != arr[i+2])
      func();
}

または、負のオフセットが必要な場合:

for (i = 2; i < 6; i++)
{
   if (arr[i-2] + arr[i-1] != arr[i])
      func();
}
于 2012-11-02T23:15:59.820 に答える
2

反対の構文は嫌いAT&Tですが、あなたが求めているのは次のとおりです。

  • leaが?
  • movが?
  • 違いはなんですか?// it is confusing

lea「ロード実効アドレス」の略です。ソースオペランドによる位置参照のアドレスをデスティネーションオペランドにロードします。たとえば、次の目的で使用できます。

lea ebx, [ebx+eax*8]

1 つの命令で (64 ビット/要素の配列で)ebxポインター項目をさらに移動します。eax基本的に、x86 アーキテクチャでサポートされている複雑なアドレッシング モードを利用して、ポインターを効率的に操作できます。

lea eax, [var] — the address of var is placed in EAX. see [here][3]

mov eax, [ebx]  ; Move the 4 bytes in memory at the address contained in EBX into EAX

ここで説明されている違い:

MOVとLEAの違いは何ですか

アセンブリ コードの最初の 3 行目はc、次の方法でスタック上の変数を宣言するソース コードのローカル変数を設定します。

u32 *ptr = %ebp - 0x14;
u32 var1 = *(ptr - 0x8);
u32 var2 = var1 + *(ptr- 0x4) ;
于 2012-11-02T23:03:29.607 に答える