xv6是利用stack push pop的相對位置,效率高,但需小心過程中esp的修改(但其實這部份在gcc/assembler 的x86 calling convention已經幫coder做掉了,由ebp 這個reg 保存了call instruction之前esp的值。
pushl %esp
call trap
addl $4, %esp
JOS是在trap return執行前 灌給esp 其保存的trap frame 位置。優點是在中間的stack 操作, 可以放心盡量使用,只要沒有破壞原本的trap frame 資料基本完整性即可 。但差在效能上的多執行一個function call的動作。
void env_pop_tf (struct Trapframe *tf)
{
__asm __volatile ("movl %0,%%esp\n" "\tpopal\n" "\tpopl %%es\n" "\tpopl %%ds\n" "\taddl $0x8,%%esp\n" /* skip tf_trapno and tf_errcode */
"\tiret"::"g" (tf):"memory");
panic ("iret failed"); /* mostly to placate the compiler */
}
同一目標,二種實踐。