x86 64 位中的额外寄存器
我编写了自己的setjmp/longjmp,它符合我的需求,如下所示。我在32位系统上测试过,效果很好。为此,我保存和恢复寄存器 eax、ebx、ecx、edi、esi、esp、ebp 和 eip。
然而,我知道,这对于 64 位系统来说是不够的。首先,我想我需要用rX替换寄存器eX。其次,我想我需要保存x86-64位中的8个额外寄存器,它们是r8、r9、r10、r11、r12、r13、r14、r15。这样就足够了,还是我需要做更多的事情?
#define MY_SETJMP(n) __asm__ __volatile__ ("movl %eax, regax"#n";" \
"movl %ebx, regbx"#n";" \
"movl %ecx, regcx"#n";" \
"movl %edi, regdi"#n";" \
"movl %esi, regsi"#n";" \
"movl %esp, regsp"#n";" \
"movl %ebp, regbp"#n";" \
"call next"#n";" \
"next"#n": pop regip"#n";" \
"addl $6, regip"#n";" \
)
#define MY_LONGJMP(n) __asm__ __volatile__ ("movl regax"#n", %eax;" \
"movl regbx"#n", %ebx;" \
"movl regcx"#n", %ecx;" \
"movl regdi"#n", %edi;" \
"movl regsi"#n", %esi;" \
"movl regsp"#n", %esp;" \
"movl regbp"#n", %ebp;" \
"jmp *regip"#n";" \
)
I have written my own setjmp/longjmp which fits my needs, as shown below. I tested it on 32 bit systems and it works good. I save and restore registers eax, ebx, ecx, edi, esi, esp, ebp and eip for that purpose.
However, I know, this would not be enough for a 64 bit system. First of all, I think I need to replace registers eX with rX. Secondly, I think I need to save the 8 extra registers found in x86-64 bit, which are r8, r9, r10, r11, r12, r13, r14, r15. Would that be enough, or do I need to do more?
#define MY_SETJMP(n) __asm__ __volatile__ ("movl %eax, regax"#n";" \
"movl %ebx, regbx"#n";" \
"movl %ecx, regcx"#n";" \
"movl %edi, regdi"#n";" \
"movl %esi, regsi"#n";" \
"movl %esp, regsp"#n";" \
"movl %ebp, regbp"#n";" \
"call next"#n";" \
"next"#n": pop regip"#n";" \
"addl $6, regip"#n";" \
)
#define MY_LONGJMP(n) __asm__ __volatile__ ("movl regax"#n", %eax;" \
"movl regbx"#n", %ebx;" \
"movl regcx"#n", %ecx;" \
"movl regdi"#n", %edi;" \
"movl regsi"#n", %esi;" \
"movl regsp"#n", %esp;" \
"movl regbp"#n", %ebp;" \
"jmp *regip"#n";" \
)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的指令序列不会保存 标志寄存器,它可能甚至应该在IA32。维基百科页面包含可用于执行此操作的指令
pushf
和popf
。您需要保存所有向量寄存器,除非您知道程序不使用它们。请注意:它们也可用于标量浮点,因此您不需要在程序中包含矢量化代码即可使用它们。
哦,如果程序使用浮点,你应该保存历史浮点堆栈以备不时之需。 Dan Kruchinin 的答案展示了如何一步保存所有这些。
Your sequence of instruction does not save the flags register, which it probably should even in IA32. The wikipedia page contains the instructions
pushf
andpopf
that you can use to do so.You need to save all the vector registers, unless you know that the program doesn't use them. Beware: they can also be used for scalar floating-point, so you do not need to have vectorized code in your program for them to be in use.
Oh, and if the program uses floating-point, you should save the historical floating-point stack in case that is used. Dan Kruchinin's answer shows how to save all these in one step.
可能您还需要使用 fxsave/fxrestore 指令保存 x87 上下文: http://siyobik.info/ main/reference/instruction/FXSAVE
虽然,我不确定 fxsave/fxresrtore 是否可以从用户空间应用程序安全地使用(即在管理员模式之外),但你可以这样做几乎所有的事情都是 fxsave 自己做的。
Probably you need to save x87 context as well using fxsave/fxrestore instructions: http://siyobik.info/main/reference/instruction/FXSAVE
Though, I'm not sure fxsave/fxresrtore can be safely used from user-space application (i.e. outside of supervisor mode), but you can do almost everything fxsave does by yourself.