検索まずは、検索! Index人気の20件
最新の20件2018-12-022018-01-092017-05-072017-04-252016-05-012015-02-242014-01-032013-06-252012-12-302012-12-292012-07-272012-07-162012-02-052012-01-292011-10-012011-09-18 |
スタック目次スタックとはLIFO(Last In First Out)形式でデータを出し入れするデータ領域。 スタックの動作(スタックポインタや一回の出し入れで処理するバイト数など)はセグメントの属性によって変わり、 32ビット幅のスタックに16ビットの値をpushすると、アライメントが合わなくなり、著しく処理能力が落ちるだけでなく、場合によっては障害になることもある。 スタックの動き以下は、32bitモード時の一般的なスタックの動き。 push 0x89abcdef定数"0x89abcdef"をpushする。
call _Funcサブルーチン"_Func"をcallする。
retサブルーチン"_Func"からretする。
pop xpushした定数"0x89abcdef"をレジスタ"x"にpopする。
c/c++言語におけるスタックの動きc言語やc++言語では、引数やローカル変数があり、それらの変数はスタックを利用しています。 int main( int argc, char **argv )
{
int i_a = 1;
int i_b = 2;
i_a = Func( i_b ); //i_aに入れる意味は特にない。
}
int Func( int i_value )
{
int i = 2;
char ch = 5;
short sh = 3;
return i_value + i + ch + sh; //全部足して返すだけ。
}
このcソースをアセンブラに直すと、次のような感じになります。多分。 _main: pushl %ebp #ebpをスタックに格納 movl %esp, %ebp #espの値をebpにコピー。 subl $8, %esp #ローカル変数のバイト数分espの値を引く movl $1, -4(%ebp) #ローカル変数:i_aを1で初期化 movl $2, -8(%ebp) #ローカル変数:i_bを2で初期化 pushl -8(%ebp) #ローカル変数:i_bを引数としてスタックに格納 call _Func #関数:Func()を呼び出す。 movl %eax, -4(%ebp) #関数;Func()の戻り値を引数:i_aに格納 movl %ebp, %esp #espを復元 popl %ebp #スタックからebpを復元 ret _Func: pushl %ebp #ebpをスタックに格納 movl %esp, %ebp #espの値をebpにコピー。 subl $12, %esp #ローカル変数のバイト数分espの値を引く movl $2, -4(%ebp) #ローカル変数:iを2で初期化 movl $5, -8(%ebp) #ローカル変数:chを5で初期化 movl $3, -12(%ebp) #ローカル変数:shを3で初期化 movl 8(%ebp), %eax #引数:i_valueをeaxに格納 addl -4(%ebp), %eax #ローカル変数:iをeaxに加算 addl -8(%ebp), %eax #ローカル変数:chをeaxに加算 addl -12(%ebp), %eax #ローカル変数:shをeaxに加算 movl %ebp, %esp #espを復元 popl %ebp #スタックからebpを復元 ret #戻り値はeaxで返す。 main関数実行~Func関数の途中まで
Func関数の途中からFunc関数のreturnまで
まとめc言語やc++言語では、 ebpより上に引数が、 |