- 论坛徽章:
- 0
|
本帖最后由 blake326 于 2012-06-04 11:06 编辑
switch的源码是这个:
它定义了ebx, ecx, edx, esi, edi几个局部变量(prev的内核栈上),然后output把这些变量写到相应的寄存器上了。这时什么意思?
但是具体这个内联汇编的流程看得不懂我。
这些局部变量存的什么值,每见到哪里用到了?
应该switch_to会保存ebx,ecx等到内核栈上,为什么这里好像颠倒了,把堆栈上的局部变量往寄存器写呢?
#define switch_to(prev, next, last) \
do { \
/* \
* Context-switching clobbers all registers, so we clobber \
* them explicitly, via unused output variables. \
* (EAX and EBP is not listed because EBP is saved/restored \
* explicitly for wchan access and EAX is the return value of \
* __switch_to()) \
*/ \
unsigned long ebx, ecx, edx, esi, edi; \
\
asm volatile("pushfl\n\t" /* save flags */ \
"pushl %%ebp\n\t" /* save EBP */ \
"movl %%esp,%[prev_sp]\n\t" /* save ESP */ \
"movl %[next_sp],%%esp\n\t" /* restore ESP */ \
"movl $1f,%[prev_ip]\n\t" /* save EIP */ \
"pushl %[next_ip]\n\t" /* restore EIP */ \
__switch_canary \
"jmp __switch_to\n" /* regparm call */ \
"1:\t" \
"popl %%ebp\n\t" /* restore EBP */ \
"popfl\n" /* restore flags */ \
\
/* output parameters */ \
: [prev_sp] "=m" (prev->thread.sp), \
[prev_ip] "=m" (prev->thread.ip), \
"=a" (last), \
\
/* clobbered output registers: */ \
"=b" (ebx), "=c" (ecx), "=d" (edx), \
"=S" (esi), "=D" (edi) \
\
__switch_canary_oparam \
\
/* input parameters: */ \
: [next_sp] "m" (next->thread.sp), \
[next_ip] "m" (next->thread.ip), \
\
/* regparm parameters for __switch_to(): */ \
[prev] "a" (prev), \
[next] "d" (next) \
\
__switch_canary_iparam \
\
: /* reloaded segment registers */ \
"memory"); \
} while (0)
另外我objdump -S sched.o 的结果, 没有看到相关ebx, ecx, edx, esi, edi的过程:
45658 #ifndef __ARCH_WANT_UNLOCKED_CTXSW
45659 spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
45660 8d2: 8d 43 10 lea 0x10(%ebx),%eax
45661 8d5: b9 d2 08 00 00 mov $0x8d2,%ecx
45662 8da: ba 01 00 00 00 mov $0x1,%edx
45663 8df: e8 fc ff ff ff call 8e0 <schedule+0x624>
45664 #endif
45665
45666 /* Here we just switch the register state and the stack. */
45667 switch_to(prev, next, prev);
45668 8e4: 8b 45 a8 mov -0x58(%ebp),%eax
45669 8e7: 89 fa mov %edi,%edx
45670 8e9: 9c pushf
45671 8ea: 55 push %ebp
45672 8eb: 89 a0 08 03 00 00 mov %esp,0x308(%eax)
45673 8f1: 8b a7 08 03 00 00 mov 0x308(%edi),%esp
45674 8f7: c7 80 10 03 00 00 0c movl $0x90c,0x310(%eax)
45675 8fe: 09 00 00
45676 901: ff b7 10 03 00 00 pushl 0x310(%edi)
45677 907: e9 fc ff ff ff jmp 908 <schedule+0x64c>
45678 90c: 5d pop %ebp
45679 90d: 9d popf
45680 90e: 89 45 a0 mov %eax,-0x60(%ebp)
45681 /*
45682 * this_rq must be evaluated again because prev may have moved
45683 * CPUs since it called schedule(), thus the 'rq' on its stack
45684 * frame will be invalid.
45685 */
45686 finish_task_switch(this_rq(), prev); |
|