I have a few questions about exception handling in assembly language, Ive been reading up on the subject but have not been able to successfully implement my own handler yet.

First off, I would like to understand stack unwinding better. As I understand it, the PROC macro does something in order for the call stack to be walked in the event of an exception. Im my routines, when an exception occurs, the call stack is only usable to me about 1/2 the time. In every case, the call stack will be clean to the point of a managed to native transition, after that point sometimes the call stack will show the native functions that were traveled through to reach the point of error, other times it doesnt. When an exception is encountered it allways shows me the code that caused the exception, if the call stack is clean (shows the path through the native code), I can usually travel back up to the managed code and inspect the variables and such, if the call stack isnt clean, then usually when I bounce back to the managed code all the variables say something along the lines of them not being defined. My question is, what exactly does it take to set up a function in assembly language for proper unwinding?

All of my functions start off the same, I push all the registers the function uses (except the registers used for passing arguments), then it adjusts the stack frame pointer and calculates the offset to use when calling other functions. The offset is calculated only once at the beggining because in order for everything to work the stack pointer needs to be aligned to 16 bytes, once this offset is calculated I dont use push or pop, if I want to use the stack I use mov instructions. Anyways, the beggining of all functions looks something like this:


	AsmFactorial64 PROC _val:PTR qword

		push	rbx
		push	rdx
		push	rdi
		push	r11
		push	r12
		push	r15
		mov	rax, rbp					;save the current base pointer
		sub	rsp, 128					;make enough room for local vals
		mov	rbp, rsp					;move the stack pointer into the base pointer (the base pointer will be used in place of pushes and pops)
		mov	qword ptr[rbp+8], rax				;save the base pointer on the stack to make it easy to restore
		mov	qword ptr[rbp+16], rcx				;save the passed in argument

		;calculate the offset

		mov	rax, rsp					;move the stack pointer into rax before the following push so it doesnt count it
		push	rdx						;save the rdx register
		sub	rax, 28h					;this is the basic offset for calling functions, room must be made for 4 variables even if they arent used
		xor	rdx, rdx					;clear the rdx register before doing the division
		div	_sixteen					;divide the value in rax by 16
		cmp	rdx, 0						;rdx will contain either 0 or 8 at this point, 
		cmove	rax, _eight					;we want it to contain 8 because when we call a function the return address will be pushed onto the stack thereby aligning 
		cmovne	rax, _zero					;the stack to 16 bytes
		add	rax, 28h					;we add the 28h to whatever we stored in rax to give us the total offset to use when calling functions
		pop	rdx						;restore the contents of the rdx register
		mov	qword ptr[rbp], rax				;mov		_totalsub, rax

		;program code

		;a basic call to a function

		mov	rcx, _val1
		mov	rdx, _val2
		sub	rsp, qword ptr[rbp]
		call	BDMultiply
		add	rsp, qword ptr[rbp]
		mov	_returnval, rax

		;at the end of each function we restore the frame pointer, stack pointer, and pop our saved registers

		mov	rdx, qword ptr[rbp+8]				;move the original value of rbp into rdx
		mov	rsp, rbp					;move the value into rsp
		add	rsp, 128					;adjust rsp by 128 bytes that we saved for our variables
		mov	rbp, rdx					;restore rbp to its original value
		mov	rax, _returnval					;put our return value in rax
		pop	r15
		pop	r12
		pop	r11
		pop	rdi
		pop	rdx
		pop	rbx

	AsmFactorial64 ENDP
My other question is about implementing exception handling in a 64 bit windows system. Everything Ive read so far is based on 32 bit windows and Ive not been able to get it working. To this point for a limited exception handling, Ive been testing for conditions that may cause an exception before it reaches the code that could cause an exception, if my code caught it my code creates an array of 3 qwords with the first two values being 0, 0 and the third value represents a code Ive assigned myself to tell whatever function is getting this returned to it what was caught. This works fine for my code here because in all but a few functions I am returning an array of qwords, and the first element of the array contains the element count of that array (so even if the array represents zero, the first element will contain a 1 and the second will contain a zero), even though this works Im thinking if I didnt have to test for these conditions the functions would execute quicker and still be able to respond to the exceptions in the event one happens.

Also from what Ive been reading, exception handling is thread based, so I would have to setup the exception handlers for each thread? Is there a way to have the handlers installed on thread creation outside of the assembly code? Do I have to make the assembly code thread aware to check if my handlers are installed?

Thanks in advance