Closed
Description
Calling conventions
MIPS has had several calling conventions, especially on the 32-bit platform.
从上图可以看出,需要保存的寄存器如下:
$gp
global pointer$fp
frame pointer$sp
stack pointer$s0–$s7
saved temporaries
调试下setjmp函数,发现还会保存下面两个寄存器:
$ra
return address,函数返回地址,其实就是跳转的PC了,参考The jal Instruction$fp
,$s8
, 保存的是这个寄存器,应该是s8用作fp了。
Jmpbuf
jmpbuf的布局如下:
#define JB_SP 0 /* Stack pointer */
#define JB_RA 11 /* Return address */
#define JB_GP 1 /* Global pointer */
#define JB_S0 3 /* S0-S7, Saved temporaries */
#define JB_S1 4 /* S0-S7, Saved temporaries */
#define JB_S2 5 /* S0-S7, Saved temporaries */
#define JB_S3 6 /* S0-S7, Saved temporaries */
#define JB_S4 7 /* S0-S7, Saved temporaries */
#define JB_S5 8 /* S0-S7, Saved temporaries */
#define JB_S6 9 /* S0-S7, Saved temporaries */
#define JB_S7 10 /* S0-S7, Saved temporaries */
#define JB_FP 2 /* FP/S8 Frame pointer */
选择将SP放在第一个位置,是为了方便更换:
#elif defined(__mips__)
/* https://github.com/ossrs/state-threads/issues/21 */
#define MD_USE_BUILTIN_SETJMP
#define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jb[0]))
Return value
写两个函数返回0和1,可以发现返回值是寄存器$v0
。
由于$ra
是函数的返回地址,所以返回都是跳转到$ra
。
li $v0, 1 /* Set return value to 1 */
jr $ra /* Return to the saved return address */