save_context:
mov %rdi,%rax /* Get our context pointer */
/* Don't need to save A */
mov %rbx, 16(%rax) /* Save B */
mov %r12, 24(%rax) /* Save r12 */
mov %r13, 32(%rax) /* Save r13 (8*3+16)*/
mov %r14, 40(%rax) /* Save r13 */
mov %r15, 48(%rax) /* Save r13 */
mov %rbp, 56(%rax) /* Save frame pointer */
mov %rsp, 64(%rax) /* Save stack pointer */
mov (%rsp), %rdx /* Fetch our return address */
mov %rdx, (%rax) /* Save our return address */
xor %rax,%rax /* Construct return code of 1 */
inc %rax
ret
恢复的过程大概是这样的
restore_context:
mov %rdi,%rax /* Get our context pointer */
mov 64(%rax), %rsp /* Restore stack pointer */
mov (%rax), %rdx /* Fetch our return address */
mov %rdx, (%rsp)
mov 16(%rax),%rbx /* Restore B */
mov 24(%rax), %r12 /* Restore r12 */
mov 32(%rax), %r13 /* Restore r13 */
mov 40(%rax), %r14 /* Restore r14 */
mov 48(%rax), %r15 /* Restore r15 */
mov 56(%rax), %rbp /* Restore frame pointer */
xor %rax,%rax /* Return 0 */
ret
当我使用gdb调试函数时,出现了如下提示信息“在 segmentation fault 后面”。
0x0000000000424c4c <+0>: mov %rdi,%rax
0x0000000000424c4f <+3>: mov 0x18(%rax),%rsp
0x0000000000424c53 <+7>: mov (%rax),%rbx
=> 0x0000000000424c56 <+10>: mov %rbx,(%rsp)
0x0000000000424c5a <+14>: mov 0x10(%rax),%rbx
0x0000000000424c5e <+18>: mov 0x20(%rax),%rbp
0x0000000000424c62 <+22>: mov 0x28(%rax),%r12
0x0000000000424c66 <+26>: mov 0x30(%rax),%r13
0x0000000000424c6a <+30>: mov 0x38(%rax),%r14
0x0000000000424c6e <+34>: mov 0x40(%rax),%r15
0x0000000000424c72 <+38>: xor %rax,%rax
0x0000000000424c75 <+41>: retq
0x0000000000424c76 <+42>: nop
0x0000000000424c77 <+43>: nop
反汇编 save_context
0x0000000000424c1c <+0>: mov %rdi,%rax
0x0000000000424c1f <+3>: mov %rbx,0x10(%rax)
0x0000000000424c23 <+7>: mov %rsp,0x18(%rax)
0x0000000000424c27 <+11>: mov %rbp,0x20(%rax)
0x0000000000424c2b <+15>: mov %r12,0x28(%rax)
0x0000000000424c2f <+19>: mov %r13,0x30(%rax)
0x0000000000424c33 <+23>: mov %r14,0x38(%rax)
0x0000000000424c37 <+27>: mov %r15,0x40(%rax)
0x0000000000424c3b <+31>: mov (%rsp),%rdx
0x0000000000424c3f <+35>: mov %rdx,(%rax)
0x0000000000424c42 <+38>: xor %rax,%rax
0x0000000000424c45 <+41>: inc %rax
0x0000000000424c48 <+44>: retq
0x0000000000424c49 <+45>: nopl (%rax)
有关上下文的更多信息
保存上下文(context) context = {4243415,0,0,4242944,140737488348624,0,0,140737488348368,140737488348312,0}
恢复上下文(new_context) new_context= {4249788,0,0,0,0,0,6719200,6719184,0,0}
恢复上下文后失败。我尝试了save_context然后restore_context。那样可以。只是想确认一下64位的上下文和新上下文是否有什么问题?!?!
以下是32位版本
save_context:
movl 4(%esp),%eax /* Get our context pointer */
/* Don't need to save A */
movl %ebx, 12(%eax) /* Save B */
movl %esi, 16(%eax) /* Save SI */
movl %edi, 20(%eax) /* Save DI */
movl %ebp, 24(%eax) /* Save frame pointer */
movl %esp, 28(%eax) /* Save stack pointer */
movl 0(%esp), %edx /* Fetch our return address */
movl %edx, 0(%eax) /* Save our return address */
xorl %eax,%eax /* Construct return code of 1 */
incl %eax
ret
还原上下文:
restore_context:
movl 4(%esp),%eax /* Get our context pointer */
movl 28(%eax), %esp /* Restore stack pointer */
movl 0(%eax),%edx /* Get our return address */
movl %edx, 0(%esp) /* Put it on the stack in the right
spot. */
movl 12(%eax),%ebx /* Restore B */
movl 16(%eax), %esi /* Restore SI */
movl 20(%eax), %edi /* Restore DI */
movl 24(%eax), %ebp /* Restore frame pointer */
xorl %eax,%eax /* Return 0 */
ret
有什么办法可以解决这个问题吗?
8(%rbp)
,你还没有设置rbp
指向任何地方(除非它是由调用者隐式设置的)。 - Jester(%rsp)
。如果您使用传统的函数序言push %rbp; mov %rsp, %rbp
,那么相同的位置也可以被称为8(%rbp)
。 - Jester0x18(%rdx)
加载了rsp
。请确保它是正确的。 - Jesternew_context
当然应该来自之前的save_context
,你确定你没有破坏它吗?你能否发布完整的代码? - Jester