I'm writing a Forth programming system using nasm assembly language. I have a quite good error recovery system that catches more or less all compile errors - the action it takes is to restore the entire system to the state that prevailed before I started typing the line containing the error. There's a command history, so that puts me in a position to just "up arrow" back to the offending line of input, correct my goof, and hit Enter to try again.
Forth does not offer any significant protection against addressing errors or arithmetic errors like divide by zero. These are common errors in a Forth environment. Currently they segfault my system and send me back to bash. I'd like to catch these errors and respond by running through the error handling process described above. I'm trying, but for the life of me I can't figure out how to catch the addressing fault signal that ends in a segfault. Furthermore, I'm finding that existing information online about this stuff is 1) highly C-centric and 2) often conflicting across sources.
So, in general I'm asking for "excellent references" on this kind of work, particularly in assembly language. Specifically, though, I can add that in these situations I do not want to ultimately return to the precise point I was at when the fault occurred. I want to abandon that ongoing work and re-enter my command interpreter after restoring my state. I've been telling myself this means I want to "diddle" the processor context the system saves on the stack and uses to return to my code - if I can alter the value of a couple of registers (the instruction pointer and my "Forth level instruction pointer," which is just another register), then it should do precisely what I want.
The references I've seen say that the third parameter sent to my signal handler should be a pointer to that context structure, and it seems that parameter three should be in DX. If that's correct, then the task is pretty simple and only would take a few lines of assembly code, but I haven't been able to get it to work yet. I've tried to use gdb on this, but I'm not sure it's meant to work with signal handlers - when execution stops at the breakpoint I set in the handler, the instruction pointer doesn't have the expected value and rdx contains 1, which is clearly not a pointer to anything.
So, that's my story - hope someone can offer some good advice.
PS: I use no C libraries of any kind in this system, and I don't need to do any system calls from the handler or anything like that.
Right now I've tried this:
mov rax, [rdx+0x38] ; machine return: next
mov [rdx+0x80], rax
add rax, err_p-o ; Forth return is err
mov [rdx+0x28], rax
mov rax, 8 ; error 8 to stack
mov [rdx+0x70], rax
xor rax, rax
ret
The first two lines are meant to point the instruction pointer to the code I want to run, which is always addressed by r15 in my system, the next two are meant to aim the "Forth instruction pointer" at an error word, the next two place a parameter for that error word into rcx, and the xor ax, ax was to provide a success return, which I don't know is required. I'm referring here with these register names to the location of that register's value in the context structure, of course. My Forth caches the top stack element in rcx.