用nm命令得到switch_to的地址 lb 0xc00037e0
最初进入内核时的esp值:0xc009f000
main esp: 0xc009ef14
c之后单步调试,记录下执行完某些指令时的寄存器值:
执行完mov eax,[esp+20] eax: 0xc009e000 (cur) esp: 0xc009ef04
执行完mov eax,[esp+24] eax: 0xc0100000 (next) esp: 0xc009ef04
执行完mov esp,[eax]: esp: 0xc0100e50
push ebp, ebp: 0x00000000 esp: 0xc0100e60
mov ebp, ebp: 0xc0100e60 esp: 0xc0100e60
不断c,n直到mov esp,[eax],查看esp值
esp: 0xc0101e50
esp: 0xc009ef04
esp: 0xc0100d3c
esp: 0xc0101d3c
esp: 0xc009ef04
esp: 0xc0100d3c
esp: 0xc0101d64
esp: 0xc009ef04
esp: 0xc0100d80
esp: 0xc0101d3c
esp: 0xc009ef04
esp: 0xc0100d3c
esp: 0xc0101d3c
总共三个线程,三个PCB块,三个不同的栈指针
注意:一开始切换到A和B线程时是加载执行函数运行,和之后的切换行为不一样。
main线程栈是0xc009ef04,argA线程栈是0xc0100e60 ,argB线程栈是0xc0101d3c
可见,大多数情况下,esp在切入切出后都能回复到原始值,并不会导致栈本身的增长,这是因为切换的总过程并不会往栈里面塞东西。也可以看到相同特权级下发生中断的时候不会使用中断栈来保存寄存器值。
至于偶尔出现的d80情况,可以解释成为中断发生在打印函数中间,此时栈可能在打印函数之中压入了某些值尚未出栈。