2011-06-22 6 views
0

x86 ASMの次のコードは誰に教えてください。それは大きなファイルのほんの一部ですが、それは私を倒しているこのビットです。x86アセンブリコード

find_max: 
    6 .LFB0: 
    7   .cfi_startproc 
    8   pushq %rbp 
    9   .cfi_def_cfa_offset 16 
10   movq %rsp, %rbp 
11   .cfi_offset 6, -16 
12   .cfi_def_cfa_register 6 
13   movl %edi, -20(%rbp) 
14   movl -20(%rbp), %eax 
15   cltq 
16   movl a(,%rax,4), %eax 
17   movl %eax, -4(%rbp) 
18   movl -20(%rbp), %eax 
19   movl %eax, -8(%rbp) 

は具体的には、

  • は、ライン13上の%EDIで、最初は何ですか?
  • コードが-20(%rbp)を参照しているのはなぜですか?
  • 16行目はどうしますか?
  • 32ビットレジスタと64ビットレジスタの背後にある(例えば15行目の場合の)切り替えの背景には何がありますか?

私は、これは以下のような何かを行く得るために解体Cコード:

extern int a[]; 

int find_max(int n) 
{ 
    int max = a[n]; 
    int pos = n; 
    int x; 

    while (n > 0) 
    { 
     n--; 
     x = a[n]; 

     if (x > max) 
     { 
      max = x; 
      pos = n; 
     } 
    } 
    return pos; 
} 
+0

Cコードをお持ちの場合は、それが何をしているのか分かりませんか?あなたは正確に何を求めようとしていますか? –

答えて

7

は、ライン13上の%ediで、最初は何ですか?

rdiは、AMD/Linux 64ビットABI用の最初のパラメータ受け渡しレジスタです。あなたの関数が32ビットのintパラメータを取るので、ediがこのコードで使用されています。


なぜコードが-20(%rbp)を参照していますか?

これは、渡されたパラメータをスタックに保存しています。おそらくあなたは最適化が低いか全くないので、すべての変数が実際のメモリアドレスを得ていると思います。最適化を有効にすると、これらの操作が表示されなくなることがあります。


そしてライン16は、正確に何をするのでしょうか?

ライン16は、配列インデックス操作です:

movl a(,%rax,4), %eax 

AT & T構文メモリアドレッシングを探して少し奇妙です。

セグメントオーバーライド:それのようにブレークダウンあなたのケースでは符号付きオフセット(ベース、インデックス、スケール)

、配列のアドレスは、オフセットフィールドとして使用されている、あなたは何の基盤を持っていませんレジスタまたはセグメントのオーバーライドの場合、縮尺は4、使用されるインデックスレジスタはraxです。で、たとえば(32ビットレジスタおよび64ビットレジスタの後ろに切り替えるの背後にある知恵は何

eax = *(int *)((char *)a + (rax * 4)) 

:それは、このC-ような擬似コードの線に沿って何かを破壊します15行目の場合)?

私はライン15上のような何も表示されませんが、あなたの関数は、intを多く使用しているために行うの理由がある - intは32ビット型であるため、コンパイラは、32ビットレジスタを使用しています。コンパイラが一時レジスタを使用している場合は、ネイティブの64ビットサイズを選択します。

+0

最後の行は 'eax = *((int *)((char *)a + rax * 4));'のようなものです。コードは、intのサイズを考慮しています。 – cHao

+0

@cHao、ええ、それはもっと明白な説明です。私は元のコードのいくつかの類似点に一致させるために、私の例でそれからいくつかの冗長性を圧縮しました。私はそれを更新します。 –

+0

ありがとうございました。それは物事を大きくしてくれました。 :) @cHao、あなたにも感謝:) – arkati

関連する問題