PC-Mapped Exceptions

From RAD Studio
Jump to: navigation, search

Go Up to MacOS Application Development

Mac and Linux systems use Program Counter (PC)-mapped exceptions, whereas Windows (Win32) uses registration records linked on the stack.

Unwinding Assembly Routines

Assembly routines cannot catch exceptions. Moreover, you must take care when calling assembly routines, because of the unwinding specifics. This aspect is important in case non-assembly code calls assembly code that in turn calls non-assembly code. When an exception is raised/thrown, the stack unwinder throws away stack frames that the exception passes. The unwinder process has to restore various critical registers as it goes. These include the stack pointer and frame pointer. There are things you can do in assembly code to make this unwind process impossible, and you have to avoid doing these things. One key item is that if you modify the stack pointer by a variable amount, the unwinder is not able to unwind the frame without some help. For example:

sub esp, eax


sub esp, 0xF
and esp, 0xFFFFFFF0

Either of the above constructs in assembly code makes the unwinder unable to unwind the given procedure. In order for the unwinder to be able to unwind a procedure that includes instructions like this, you must include a stack frame in your code:

push ebp
mov ebp, esp

The creation of the stack frame must be the first two instructions of your code. When the assembly code is compiled, this instruction sequence is recognized by the compiler and the compiler generates specialized unwind information for the routine. If the frame is not present, the compiler inspects the entire assembly routine attempting to analyze how the code is modifying the stack in order to unwind the modifications in the event of an exception being raised/thrown.