0

IA32は、すべてのスタックフレームが16バイトの倍数であることを確認するという規則に従います。関数の例を次に示します。

char *gets( char *s ); //get String
void puts( char *s ); //put string to the screen
void echo()
{
    char buf[8];
    gets(buf);
    puts(buf);
 }

getとputsは単なる関数呼び出しであり、そのままにしておくことができます。

このアセンブリコードは次のとおりです:(FROMCSAPP [コンピュータシステム:プログラマーの視点])

1 echo:
2 pushl %ebp            //Save %ebp on stack
3 movl %esp, %ebp
4 pushl %ebx            //Save %ebx
5 subl $20, %esp        //Allocate 20 bytes on stack
6 leal -12(%ebp), %ebx  //Compute buf as %ebp-12
7 movl %ebx, (%esp)     //Store buf at top of stack
8 call gets             //Call gets
9 movl %ebx, (%esp)     //Store buf at top of stack
10 call puts            //Call puts
11 addl $20, %esp       //Deallocate stack space
12 popl %ebx            //Restore %ebx
13 popl %ebp            // Restore %ebp
14 ret                  //Return

スタックは次のようなものです。

 ________
| old ebp|  4 bytes 
|________|
| ebx    |  4 bytes
|________|           ___
| buf[7] |            |
|________|            |
|  ...   |            |
                      |
                      |
|________|         20 bytes
| buf[0] |            |
|________|  ebp-12    |
|  ...   |            |
                      |
|________|           _|_

では、なぜコンパイラは24バイトではなく20バイトを割り当てるのでしょうか。20 + 4 + 4=28は16バイトの倍数ではないためです。

4

1 に答える 1

3

スタックの一番上にある差出人住所を忘れないでください!ターゲットにジャンプする前に電流をスタックにcallプッシュし、そのPCをポップしてジャンプして戻ります。したがって、スタックはより正確になりますpcret

saved pc
old ebp
ebx
buf[7]
...
buf[0]
...

合計の高さは32バイトです。

于 2013-03-10T05:13:01.397 に答える