setjmp函数怎么实现的
时间: 2023-05-19 16:02:16 浏览: 51
setjmp函数是通过保存当前程序状态的一些信息,以便在后续调用longjmp函数时能够恢复到该状态。具体实现方式是将当前程序状态的一些寄存器值、栈指针、程序计数器等信息保存到一个结构体中,然后将该结构体的指针作为返回值返回给调用者。在后续调用longjmp函数时,将该结构体的指针作为参数传入,就可以恢复到之前保存的程序状态。
相关问题
mips汇编指令setjmp和longjmp实现,以及测试函数
MIPS汇编指令setjmp和longjmp的实现:
setjmp:
```assembly
setjmp:
addi $sp, $sp, -8 # 保存栈指针
sw $fp, 4($sp) # 保存帧指针
sw $ra, 0($sp) # 保存返回地址
move $v0, $sp # 将栈指针存入v0,作为跳转点
jr $ra # 返回
```
longjmp:
```assembly
longjmp:
move $sp, $a0 # 恢复栈指针
lw $fp, 4($sp) # 恢复帧指针
lw $ra, 0($sp) # 恢复返回地址
addi $sp, $sp, 8 # 恢复栈指针
jr $ra # 跳转回调用点
```
测试函数:
```c
#include <setjmp.h>
#include <stdio.h>
jmp_buf buf;
void func() {
printf("enter func\n");
longjmp(buf, 1);
printf("exit func\n");
}
int main() {
if (setjmp(buf) == 0) {
printf("enter main\n");
func();
} else {
printf("return from longjmp\n");
}
printf("exit main\n");
return 0;
}
```
输出:
```
enter main
enter func
return from longjmp
exit main
```
mips汇编实现setjmp和longjmp函数,以及测试用例
以下是MIPS汇编实现setjmp和longjmp函数的代码:
```assembly
# setjmp function
# Arguments: $a0 - pointer to jmp_buf
# Returns: 0 (for the initial call), or 1 if returning from longjmp
setjmp:
addi $sp, $sp, -32 # allocate space on the stack
sw $ra, 28($sp) # save return address
sw $fp, 24($sp) # save frame pointer
add $fp, $sp, 32 # set new frame pointer
sw $a0, 0($fp) # save jmp_buf pointer
sw $a1, 4($fp) # save return value
li $v0, 0 # set return value to 0
jr $ra # return to caller
# longjmp function
# Arguments: $a0 - pointer to jmp_buf, $a1 - return value
# Returns: Does not return
longjmp:
lw $fp, 24($sp) # restore frame pointer
lw $ra, 28($sp) # restore return address
addi $sp, $sp, 32 # deallocate stack space
lw $t0, 0($fp) # load jmp_buf pointer
lw $t1, 4($fp) # load return value
sw $a1, 0($t0) # store return value in jmp_buf
addi $v0, $zero, 1 # set return value to 1
jr $t1 # jump to saved return address
# test case
main:
addi $sp, $sp, -32 # allocate space on the stack
sw $ra, 28($sp) # save return address
sw $fp, 24($sp) # save frame pointer
add $fp, $sp, 32 # set new frame pointer
# setjmp call
la $a0, jmp_buf # load jmp_buf pointer
jal setjmp # call setjmp
move $t0, $v0 # save return value
li $v0, 10 # set $v0 to 10
sw $v0, 0($t0) # store $v0 in jmp_buf
# longjmp call
la $a0, jmp_buf # load jmp_buf pointer
lw $a1,