#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 .)