exercise 1.10
要求:在obj/kern/kernel.asm中找到test_backtrace函数,设置一个断点,检查内核启动后每次该函数被调用时发生了什么。多少个32位字在每次嵌套调用test_backtrace时被压入栈?这些被压栈的字是什么?
解答:
查询被调用过程,最后指向了一个C文件,lab/kern/init.c 其中有该函数的代码。
test_backtrace(int x)
{
cprintf("entering test_backtrace %d\n", x);
if (x > 0)
test_backtrace(x-1);
else
mon_backtrace(0, 0, 0);
cprintf("leaving test_backtrace %d\n", x);
}
显然是个递归调用,循环输出结果如下(推知)
//假设x=3
entering test_backtrace 3
entering test_backtrace 2
entering test_backtrace 1
entering test_backtrace 0
mon_backtrace(0, 0, 0)
leaving test_backtrace 0
leaving test_backtrace 1
leaving test_backtrace 2
leaving test_backtrace 3
回到kernel.asm,line 75就是这个函数的汇编代码,f复制过来如下。能看到把ebp、ebx、eax压栈,ebx压栈两次,则共压栈4个32位字。
// Test the stack backtrace function (lab 1 only)
void
test_backtrace(int x)
{
f0100040: 55 push %ebp
f0100041: 89 e5 mov %esp,%ebp
f0100043: 53 push %ebx
f0100044: 83 ec 0c sub $0xc,%esp
f0100047: 8b 5d 08 mov 0x8(%ebp),%ebx
cprintf("entering test_backtrace %d\n", x);
f010004a: 53 push %ebx
f010004b: 68 80 18 10 f0 push $0xf0101880
f0100050: e8 a3 08 00 00 call f01008f8 <cprintf>
if (x > 0)
f0100055: 83 c4 10 add $0x10,%esp
f0100058: 85 db test %ebx,%ebx
f010005a: 7e 11 jle f010006d <test_backtrace+0x2d>
test_backtrace(x-1);
f010005c: 83 ec 0c sub $0xc,%esp
f010005f: 8d 43 ff lea -0x1(%ebx),%eax
f0100062: 50 push %eax
f0100063: e8 d8 ff ff ff call f0100040 <test_backtrace>
f0100068: 83 c4 10 add $0x10,%esp
f010006b: eb 11 jmp f010007e <test_backtrace+0x3e>
else
mon_backtrace(0, 0, 0);
f010006d: 83 ec 04 sub $0x4,%esp
f0100070: 6a 00 push $0x0
f0100072: 6a 00 push $0x0
f0100074: 6a 00 push $0x0
f0100076: e8 f3 06 00 00 call f010076e <mon_backtrace>
f010007b: 83 c4 10 add $0x10,%esp
cprintf("leaving test_backtrace %d\n", x);
f010007e: 83 ec 08 sub $0x8,%esp
f0100081: 53 push %ebx
f0100082: 68 9c 18 10 f0 push $0xf010189c
f0100087: e8 6c 08 00 00 call f01008f8 <cprintf>
}
f010008c: 83 c4 10 add $0x10,%esp
f010008f: 8b 5d fc mov -0x4(%ebp),%ebx
f0100092: c9 leave
f0100093: c3 ret