9. スタックフレーム - サンプル
void test2(int a, int b)
{
char s[10];
}
void test1(int a, int b)
{
int n = 10;
int m = 20;
test2(n + a, m + b);
}
int main(int argc, char **argv)
{
test1(1, 2);
return 0;
}
10. 低位アドレス スタックフレーム
esp
s
test2() のスタックフレーム
Saved ebp
Ret address
test1() で引数の n と m にするには、この
a ようになる
movl %eax, 8(%ebp) <- a にアクセス
b
test1() のスタックフレーム movl %edx, 12(%ebp) <- b にアクセス
n
ローカル変数の場合は、
m movl -4(%ebp), %eax <- m にアクセス
Saved ebp movl -8(%ebp), %edx <- n にアクセス
Ret address
a
main() のスタックフレーム
b
Saved ebp
高位アドレス
14. Stack 操作の命令 - Push/Pop
void push_pop(void)
{
int n = 0x20;
printf("before: n is 0x%xn", n); $ ./a.out
before: n is 0x20
asm volatile("push $0x10;nt" after: n is 0x10
"pop %
[output];nt"
:[output]
"=g"(n));
printf("after: n is 0x%xn", n);
}
44. switch_to - 概要
arch/x86/include/asm/system.h
44/*
45 * Saving eflags is important. It switches not only IOPL
between tasks,
46 * it also protects other tasks from NT leaking through
sysenter etc.
47 */
48#define switch_to(prev, next, last)
このマクロはカレントプロセスの eip 、 esp 、 ebp の保存と、
次のプロセスのために eip 、 esp 、 ebp の設定、 __switch_to()
の呼出をします。 __switch_to() から戻った時点で、プロセスが
切り替わっています。
60. スレッド構造体
typedef struct _Thread {
struct _Thread *next;
int thread_id;
unsigned long context[CONTEXT_SIZE];
char *stack_top; /* NULL if this is main() thread */
int status;
} Thread;
61. メインスレッド
void ThreadMain(int argc, char **argv)
{
int t1, t2;
t1 = ThreadCreate(f, 1);
printf("create a new thread (i=%d) [id=%d]n", 1, t1);
t2 = ThreadCreate(f, 2);
printf("create a new thread (i=%d) [id=%d]n", 2, t2);
ThreadYield();
printf("main thread finished.n");
}
65. ThreadYeild- 前半
void ThreadYield()
{
Thread *t;
int found = 0;
for (t = threadList->next; t; t = t->next) {
if (t && t->status == RUNNING && t != currentThread) {
found = 1;
break;
}
}
66. ThreadYeild- 後半
if (found) {
Thread *cur = currentThread;
currentThread = t;
printf("switch id %d to %dn", cur->thread_id, t->thread_id);
_ContextSwitch(cur->context, t->context);
} else if (currentThread->thread_id == MAIN_THREAD_ID) {
// main thread's state is FINISH.
printf("There is only main threadn");
} else {
printf("There is no active threadn");
}
}
68. スレッドの実行内容
void f(int i)
{
int n = 0;
for (n = 0; n < 10; n++) {
printf("thread(%d): %d.n", i, n);
ThreadYield();
}
printf("thread (i=%d) finished.n", i);
}
69. 実行結果
[masami@moon]~/experiment/thread% ./test1
create a new thread (i=1) [id=1]
create a new thread (i=2) [id=2]
switch id 0 to 2
thread(2): 0.
switch id 2 to 1
thread(1): 0.
switch id 1 to 2
~
switch id 1 to 2
thread (i=2) finished.
switch id -1 to 1
thread (i=1) finished.
switch id -1 to 0
main thread finished.