2011-10-31 135 views
2

我寫了自己的setjmp/longjmp,它符合我的需求,如下所示。我在32位系統上進行了測試,效果很好。我爲此保存和恢復寄存器eax,ebx,ecx,edi,esi,esp,ebp和eip。x86中的額外寄存器64位

但是,我知道,這對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";" \ 
    ) 
+7

你爲什麼寫自己的而不是使用_working_系統? –

+0

就像我說過的,我將它用於特殊目的,這是無法使用現有的setjmpt/longjmp完成的。 – MetallicPriest

回答

7

您的指令序列不保存flags register,它可能甚至應該在IA32中保存。維基百科頁面包含您可以使用的說明pushfpopf

您需要保存所有向量寄存器,除非您知道該程序不使用它們。請注意:它們也可以用於標量浮點,因此您不需要在程序中使用向量化代碼以供它們使用。 噢,如果程序使用浮點,你應該保存歷史浮點棧以防使用。 Dan Kruchinin的答案顯示瞭如何一步保存所有這些。

4

也許你需要保存的x87上下文中還使用FXSAVE/fxrestore說明:http://siyobik.info/main/reference/instruction/FXSAVE

雖然,我不知道FXSAVE/fxresrtore可以從用戶空間應用程序可以安全使用(即超級用戶模式外) ,但你幾乎可以做自己做的每件事。

+0

爲什麼你認爲fxsave在用戶空間中可能不安全?據我所知,這不是特權指令。 – osgx