第1关:0号进程和1号进程的mynext变量的取值变化
1.1号进程的 output_char 函数调用会执行几次?
2.每次调用时,1 号进程和 0 号进程的 mynext 变量的值分别是多少?
首先,在0号进程和1号进程处分别打断点
因为我们已经知道了mynext变量的线性地址,所以使用commands命令直接在每个断点展示mynext变量的值
接下来就是一直c,直到结束
值得注意的是,尝试输入过几次答案都测评失败,有两个问题:
第一个,我们找到源码,
可以看出是先执行out_putchar函数,然后mynext的值+1,要注意这个变化。
第二个,就是输入答案的时候必须是十进制。
最终答案:
1.1 号进程的 output_char 函数调用会执行几次?(6)
2.每次调用时,1 号进程和 0 号进程的 mynext 变量的值分别是多少?(1,1)(2,7)(3,7)(4,7)(5,7)(6,7)
注:如果括号不够可以自行使用英文括号补充格式为(,),如果括号数量不对评测时将会报错。
第2关:LDTR 寄存器
1 号进程(在用户态)运行时,LDTR 寄存器的值是多少?它指向 GDT 中的几号描述符?该段描述符内存的段起始地址是多少?指向哪个进程的 ldt 数组?
0 号进程(在用户态)运行时,LDTR 寄存器的值是多少?它指向 GDT 中的几号描述符?该段描述符内存的段起始地址是多少?指向哪个进程的 ldt 数组?
这里首先就遇到了第一个很让人头疼的问题,要找LDTR寄存器的值要用dbg模式,而不能使用gdb调试,而且打断点的时候要用地址打断点
然后执行,通过sreg命令查看LDTR寄存器的值
通过LDTR的值0x28,可以看出0号进程它指向GDT表中的5号描述符,1号进程以此类推,而且前面我们已经知道了它的起始地址,这里不在赘述。
最终答案:
1.1 号进程(在用户态)运行时,LDTR 寄存器的值是多少?(0x0038)它指向 GDT 中的几号描述符?(7)该段描述符内存的段起始地址是多少?(0xfff2d0)指向哪个进程的 ldt 数组?(1)
2.0 号进程(在用户态)运行时,LDTR 寄存器的值是多少?(0x0028)它指向 GDT 中的几号描述符?(5)该段描述符内存的段起始地址是多少?(0x1ed70)指向哪个进程的 ldt 数组?(0)
第3关:内核代码段和数据段的段基址
1.0 号进程执行到 sys_pause 时,默认数据段(CS)和默认数据段(DS)的值分别是多少?其基地址分别是多少?
2.1 号进程执行到 sys_pause 时,默认数据段(CS)和默认数据段(DS)的值分别是多少?其基地址分别是多少?
首先在0号进程的pause和1号进程的psuse打上断点,然后c执行
首先来到0号进程,通过info registers命令查看cs和ds寄存器的值
此时段内不再存放段基址,而是段描述符在段描述符表中的索引值,cs和ds段都在GDT表中,分别为1号、2号描述符。接下来查看GDT表
计算得到1号、2号描述符即cs、ds段的基址都是0x0
进程1类似,不再赘述
最终答案:
1.0 号进程执行到 sys_pause 时,默认数据段(CS)和默认数据段(DS)的值分别是多少?(0x8)(0x10)其基地址分别是多少?(0x0)(0x0)
2.1 号进程执行到 sys_pause 时,默认数据段(CS)和默认数据段(DS)的值分别是多少?(0x8)(0x10)其基地址分别是多少?(0x0)(0x0)