xv6中`popl 0(%eax)`指令含义的技术咨询(OSTEP)
xv6 swtch函数中popl指令的误解解析
先看《操作系统导论(Operating Systems: Three Easy Pieces)》第6章里的xv6上下文切换代码片段:
... void swtch(struct context **old, struct context *new); # # Save current register context in old # and then load register context from new. .globl swtch swtch: # Save old registers movl 4(%esp), %eax # put old ptr into eax popl 0(%eax) # save the old IP movl %esp, 4(%eax) # and stack movl %ebx, 8(%eax) # and other registers ...
你对movl 4(%esp), %eax的理解是对的:这条指令把栈上偏移4字节处的内容(也就是swtch函数的第一个参数old,即旧上下文的指针)加载到%eax寄存器中。
你之前的误解出在popl 0(%eax)的操作对象上:0(%eax)不是指%eax寄存器本身,而是指以%eax中的值为基地址、偏移0字节的内存地址。
具体来说:
- 执行这条指令时,%eax里存的是旧上下文结构体的内存地址
0(%eax)就是这个结构体的起始位置,对应结构体中用来保存指令指针(IP)的字段popl 0(%eax)的作用是:从当前栈顶弹出一个值(这个值就是调用swtch函数时被压入栈的返回地址,也就是旧执行流的下一条指令地址),并把这个值写入到0(%eax)指向的内存位置(也就是旧上下文的IP字段)
这样操作并不会覆盖%eax寄存器的值,因为popl的目标是内存地址,不是寄存器。你的猜测完全正确,这条指令是把返回地址保存到旧上下文结构体里,而非修改%eax。
内容的提问来源于stack exchange,提问作者ssapgosu
相关产品推荐
相关产品推荐

