我一直在为Linux用NASM编写一个程序。我希望能够从我为SIGFPE建立的信号处理程序中返回到正常的代码路径。精简后的示例代码为:
section .text
global _start
_start: ; --- Enter the program ---
mov ebx,8 ; Load the signal to handle (SIGFPE)
mov ecx,.handle ; Load the handler address
mov eax,48 ; Load the syscall number for signal
int 0x80 ; Establish the handler
mov ebx,0 ; Prepare a divisor for SIGFPE
idiv ebx ; Divide edx:eax by 0
mov ebx,0 ; Set exit status 0 (shouldn't get here)
jmp .exit ; Exit the program
.handle: ; --- Handle a divide exception ---
mov ebx,31 ; Set exit status 31 (instead of real handling)
.exit: ; --- Exit the program ---
mov eax,1 ; Load the syscall number for exit
int 0x80 ; Exit back to the system
这里的幻数是为了代码的紧凑性。
在iDiv指令之前,特别是0xffffcc00
。在进入信号处理程序时,特别是0xffffc52c
。已经有相当多的东西被放到了堆栈上!关于__nr_sigback的信息很多。我试着用它也没什么运气。处理程序中的ret
指令只是让我返回到IDIV指令,这次没有处理程序。
我可以在.handle
标签上做些什么才能安全地回到主线,您有什么想法吗?
(我知道Sigaction是可用的,但我想了解这种情况下发生了什么。)
将返回一个简单的ret
,以便重新尝试故障指令。使用sigaction
注册带有SA_SIGINFO
标志的信号处理程序时,第三个参数是指向ucontext_t
的指针,该指针包含可更改的已保存状态。