0

これを続けるために: C プログラムのデバッグ (int 宣言) より多くのコードをテストし、コンパイラがそれにどのように反応するかを確認することにしました。そこで、ローカル変数をテストするためにこれを試すことにしました。

#include <stdio.h>
main()
{
  int a,b,c,d,e,f,g;
  a=0xbeef;
  b=0xdead;
  c=0x12;
  d=0x65;
  e=0xfed;
  f=0xaa;
  g=0xfaceb00c;
  a=a+b;
  printf("%d",a);
}

わかりました、int a、b、c を実行しました... メインのフレーム サイズをテストし、サブ $0x10,%esp が成長していることを確認します (私は Linux を使用しているため、サブである可能性があります)。 $0x30,%esp したがって、「disas main」コマンドを使用した gdb の出力は次のとおりです。

   0x0804841c <+0>:  push   %ebp
   0x0804841d <+1>:  mov    %esp,%ebp
   0x0804841f <+3>:  and    $0xfffffff0,%esp
   0x08048422 <+6>:  sub    $0x30,%esp ;7 int vars 4-byte is 7*4=28. 30 is enough
   0x08048425 <+9>:  movl   $0xbeef,0x14(%esp)
   0x0804842d <+17>: movl   $0xdead,0x18(%esp)
   0x08048435 <+25>: movl   $0x12,0x1c(%esp)
   0x0804843d <+33>: movl   $0x65,0x20(%esp)
   0x08048445 <+41>: movl   $0xfed,0x24(%esp)
   0x0804844d <+49>: movl   $0xaa,0x28(%esp)
   0x08048455 <+57>: movl   $0xfaceb00c,0x2c(%esp)
   0x0804845d <+65>: mov    0x18(%esp),%eax
   0x08048461 <+69>: add    %eax,0x14(%esp)
   0x08048465 <+73>: mov    0x14(%esp),%eax
   0x08048469 <+77>: mov    %eax,0x4(%esp)
   0x0804846d <+81>: movl   $0x8048510,(%esp)
   0x08048474 <+88>: call   0x80482f0 <printf@plt>
   0x08048479 <+93>: leave  
   0x0804847a <+94>: ret    

この行: 0x0804841f <+3>:and $0xfffffff0,%esp and 演算子とは何ですか? なぜ大きな数があるのですか?

なぜ movl コマンドのオフセットが負でないのか:movl $0xa,-0x4(%ebp) これまでのところ、AND は 1 と 1 が 1、0 と 0 が 0、1 と 0 が 0 などのような論理演算子であることを知っています。この場合、%esp には、メイン関数を呼び出した人のベース フレーム アドレスである ebp 値があります。

これがこのようにコンパイルされる理由を説明できる人はいますか?

私は何かが欠けていると思います。編集:これについて話しているstackoverflowのいくつかの「トピック」を見ました。共有します: link1 link2 link3

4

1 に答える 1