2
 #include <stdio.h>

 static int i = 100;

 /* Declard as extern since defined in hello.c */
 extern int global;

 int function(char *input)
 {
  printf("%s\n", input);
  return global;
 }; 

    .file   "foo.c"
    .data
    .align 4
    .type   i, @object
    .size   i, 4
i:
    .long   100
    .text
.globl function
    .type   function, @function
function:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
    movl    8(%ebp), %eax
    movl    %eax, (%esp)
    call    puts
    movl    global, %eax
    leave
    ret
    .size   function, .-function
    .ident  "GCC: (Debian 4.4.5-8) 4.4.5"
    .section    .note.GNU-stack,"",@progbits

次の理由は何ですか。

サブル $24、%esp

スタックポインタを 24 バイト減らすことで、ローカル変数用にスタックにスペースを作るのはなぜですか? 関数にはローカル変数はありません。次に、彼は次のことを行います。

movl %eax, (%esp)

なぜ - ebp+8 に保存された値 (ポインター char *input) が eax に移動され、今は puts に渡される必要があるため.. しかし、なぜ彼は前の subl を行うのですか - int の戻り値を保存するには? しかし、それは4バイトです..また、Cは戻り値のためにスタック上にスペースを作る必要がある呼び出し関数をサポートしていないことを読みました(再帰性の問題)。ここで何が起こっているのか教えてください :( ?? 彼はポインター引数をワード境界に揃えている可能性があります..しかし、SysV I386 ABI は、テールパディングが採用されていると言います..

また、

movl %esp, %ebp

esp と ebp の両方が新しい関数スタック フレームのベースを指すことを意味します。しかし、「call function;」があったと仮定します。スタックを検討してください:

pushl ptr //push char *ptr
call function 
{
pushl ebp So stack contains:
ptr
ret-value
ebp
->with-esp-pointing-to-after-ebp
(ESP always points to the top of the stack but after the last pushed   
element..?)

つまり、彼は ebp を esp に設定しています。しかし、pg36 の ABI 仕様である SysV ABI I386 Architecture Processor Supplement 4E では、彼は次のように述べています。 、ebp+0 は、実際には保存された前の ebp の後を指します..???

また別の番組で、

andl $-16, %esp
subl $32, %esp

それで、彼は最初に特に最後の 4 ビットを nueking しています..うーん、それは彼にどのくらいのスペースを与えますか? そして、サブl..

誰かがこれのためのまともなチュートリアルや本を提案できますか..私はアセンブリを習得したくありません.ABI仕様とアライメントとGOT/PLT/仮想アドレス指定とコンパイラ/リンカのものを少し理解するのに十分知りたいだけです- symbolTable/relocation など (私は Levine の本を使用していますが、非常に興味深いものですが、COFF と IBM/Sparc のものもあります :( これが私が ABI 仕様から始めた理由です。Ian Wienand の Web サイトもあります: Computer Science from the Bottom Up .)

4

0 に答える 0