-
April 14th, 2013, 06:22 AM
#1
A few questions about exception handling
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:
Code:
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
RET
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
-
April 14th, 2013, 05:28 PM
#2
Re: A few questions about exception handling
Wow , that's tricky! Exception handling at machine code level is a quite specific topic I've never dealt with before. And then it's about x64, with which I have no practical experience either, as you know. In particular when it comes to the x64 calling convention, and a thorough knowledge of that is most certainly required to answer your question. I hope someone reads the thread who can...
Except perhaps for this small aspect of your question of probably rather marginal importance:
Originally Posted by AKRichard
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?
From what I recall, I assume you're talking of the managed code wrapping your assembly language routines. Basically you're right, exception handling works per thread. But what's so complicated in catching exceptions at the outermost call nesting level in the worker thread function and somehow pass an error-indicating object back to the invoking thread, which may, among other infotmation, contain the originally caught Exception object? Alternatively, instead of creating a Thread object and starting it, you may start your worker thread function by constructing a delegate referring to it, and then using the delegate's BeginInvoke() method (see http://msdn.microsoft.com/en-us/libr...v=vs.100).aspx). Then, when an uncaught exception is thrown in the worker thread, the thread dies more or less silently, but the exception gets rethrown in the invoking thread when it calls the delegate's EndInvoke() method.
Yes, there is sort of a global catch-all, and in .NET that is the AppDomain::UnhandledException event. But that should only be used as a very last resort: The effort you'd need to take to ensure your app hasn't already been irreparably destabilized when the event gets raised probably is much larger than that for proper exception handling in the first place. There's a functionally similar mechanism for native C++, but I don't recall how to set that up.
Some additional information that may or may not be helpful in your scenario: Managed exceptions appear in native calling code as SEH exceptions wth exception code 0xE0434F4D. Some native exceptions (e.g. access violation or some floaing point exceptions) are mapped to appropriate .NET exceptions for calling managed code. Those that can't be mapped appear as System::Runtime::InteropServices::SEHException.
BTW: It's probably irrelevant for the demonstrational purpose why you posted it here, and perhaps I simply missed something, but does your assembly language function calculate a factorial at all? I don't seem to see any recursion or loop in there. Also, you seem to pass two parameters to BDMultiply, while your function apparently only takes one, and I can't see where they come from.
Last edited by Eri523; April 14th, 2013 at 05:47 PM.
I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.
This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.
-
April 15th, 2013, 02:04 AM
#3
Re: A few questions about exception handling
Hello Eri523, How you been doing?
Some additional information that may or may not be helpful in your scenario: Managed exceptions appear in native calling code as SEH exceptions
SEH was the direction I was thinking of going in. I was wondering how much trouble it would be to implement at the assembly level. In all honesty, the main reason I have been thinking of attempting to implement this is for debugging the assembly code. Right now I have working code and when an exception is thrown it is because I didnt set something up correctly not because an algorithm isnt functioning correctly. However, when implementing something new, or even making changes to allready running algorithms, sometimes I get exceptions with very little information to help me track down the bug, which at times, leads to seemingly endless hours of debugging trying to catch the exception or otherwise tracking down the bug. I was of the mind if I implemented my own exception handling it may make debugging simpler as I could include my own information about what happened. The code base for the basic set of classes is allready some 200,000 lines of code (about 1/2 for the 32 bit version and 1/2 for the 64 bit version) of which about 1/2 of that is in assembly.
Anyways, SEH seemed like the most logical way to go for this.
BTW: It's probably irrelevant for the demonstrational purpose why you posted it here, and perhaps I simply missed something, but does your assembly language function calculate a factorial at all? I don't seem to see any recursion or loop in there. Also, you seem to pass two parameters to BDMultiply, while your function apparently only takes one, and I can't see where they come from.
that wasnt actual production code, I copied and pasted parts of a function to show how I was setting up the stack frames in relation to my question about stack unwinding, and I dont think I copied all the code from the same function, anyways, I didnt want to post the entire function when I was just trying to show how my stack frames are set up to see if I was doing it correctly. This is a big part of why Ive been thinking of implementing exception handling myself. Id say about 1/2 the time when Im debugging and something goes wrong, the exception will break in at the managed code level and give the System::Runtime::InteropServices::SEHException with little evidence of what actually caused the exception. Even if I get lucky and the exception breaks into the native code (in the assembly function) it usually shows me the point that caused the exception, but without the callstack, I cant back up through the function calls to see where the actual problem is.
Thats the whole reason I brought up the question about stack unwinding first, if I could figure out where I am going wrong with setting up the stack so that it ALLWAYS has the call stack available, that would be a tremendous help in itself.
Of course, I probably should have done this before I had most of it complete, the integer, decimal, and fraction classes are pretty much complete, I am working on putting the finishing touches on the complex forms of the decimal and fraction classes, I have all the trig functions, sqrt, nthroot, and some number theory stuff implemented. Im still playing with the memory management stuff, but after learning a few tricks, that has become less important then it was, and I still have to go back through and bring the 32 bit version up to date since Ive been primarily working on, and the last thing to work on is to provide more generic versions of some of the routines, it all works fine on the newer 64 bit amd and intel chips, but some of the algorithms break on some of the older stuff.
In particular when it comes to the x64 calling convention, and a thorough knowledge of that is most certainly required to answer your question. I hope someone reads the thread who can...
again, I am sure its because I am doing something wrong in setting up the stack frame, I think when I do end up with the call stack its just dumb luck. Thats not a bad idea about using the delegate for thread invocation. I was just hoping there was a way to set it up once and have it automatically replicate to any other thread that was created, that way it could be set up in my initialization routine (which only gets called once on the first time any of the assembly routines are called no matter how many threads are created). Ive been reading that MS has default handlers installed for all the exceptions, and that you can chain the exceptions along, so Ive been trying to figure out if its possible to install my own handler in place of their default ones, my handler could look at the exception and if it decided it wasnt in my code it could just pass it down to the original default handler.
-
April 16th, 2013, 05:35 PM
#4
Re: A few questions about exception handling
So you're aware of the IDE menu option Debugging > Exceptions, where you can specify in detail on which types of exception the debugger shall break when they occur and before the runtime scans the call stack upward to find a responsible exception hander (the so-called first chance exception), it just doesn't help really much? Breaking on most exception types is disabled there by default, and in complicated debugging scenarios like yours it can be quite helpful to fine-tune debugger behavior by enabling a few of them that are more or less specifically related to your scenario. (Actually, I about just as much use that menu item to disable a few of the exceptions breaking on is enabled by default, but that's another story I think.)
Do I get you right that you don't intend to throw exceptions yourself from your assembly routines, you just want to maintain proper stack traces? In that case I'm not quite sure what you mean by "include [your] own information about what happened", when the problem actually is to get hands on the exception information in the first place. Or are you thinking of something like more or less classical logging? Of course you can always do that, mostly independent of exception handling. And that wouldn't even necessariliy mean logging to debug output or even a log file; you may as well maintain your own diagnostic data structures that you then can examine in case of failure. That's quite some effort probably, but there's some chance it will really pay.
The incomplete stack trace problem isn't specific to code involving assembly language (you may already have noticed that). I sometimes encounter that too (even with programs not even involving native C++ code of my own), and I don't really like it either... So it may actually not be strictly related to improper stack frame setup at all. It appears to prevalently occor when something goes wrong in code being executed in response to a Windows message (well, in a Windows Forms app that's more or less most of the code... ). Multithreading may increase the probability of that problem to occur, but it's definitely not strictly related to that either: I've quite some times seen that in single-threaded (at least regarding my own code) apps and/or happening in the main (GUI) thread.
If you want to use it for diagnostic purposes only, IMO the two kinds of "global catch-all" I mentioned, which intercept execution right before the runtime's or OS' unhandled exception handler is invoked, are really worth consideration. In that case I think you wouldn't worry too much about your app being destabilized anyway, and that may be a good place to pick up the diagnostic data you collected, as mentioned above, and do diagnostic things with it. That's probably just what these emergency mechanisms are meant to be used for.
I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.
This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.
-
April 17th, 2013, 03:36 PM
#5
Re: A few questions about exception handling
So you're aware of the IDE menu option Debugging > Exceptions, where you can specify in detail on which types of exception the debugger shall break when they occur and before the runtime scans the call stack upward to find a responsible exception hander (the so-called first chance exception), it just doesn't help really much? Breaking on most exception types is disabled there by default, and in complicated debugging scenarios like yours it can be quite helpful to fine-tune debugger behavior by enabling a few of them that are more or less specifically related to your scenario. (Actually, I about just as much use that menu item to disable a few of the exceptions breaking on is enabled by default, but that's another story I think.)
I actually use these settings quite a bit while debugging now, unfortunately they only take me so far at times.
Do I get you right that you don't intend to throw exceptions yourself from your assembly routines, you just want to maintain proper stack traces? In that case I'm not quite sure what you mean by "include [your] own information about what happened", when the problem actually is to get hands on the exception information in the first place.
What I actually was talking about there, I would like to either fix the problem with the stack trace or figure out how to throw my own exceptions so that I could (hopefully) include some pertinent info on why the exception happened. I am still reading up on the "global catch-all" that you mentioned, and will probably have a question or two about that once I try it out. I havent had the time to work on anything the last few days as Ive been dealing with sick kids and a sick dog while being sick myself.
I have logging capabilities in my code, unfortunately, most of the time when I am trying to track a bug down, its something that only happens once in every hundred thousand runs or something which leaves quite a log file to go through. When I am debugging, I run my programs in single-threaded mode (in the sense I dont spin up any other threads), Ive learned lately to watch what thread the error happans on, as Ive been running into problems with the garbage collection thread after I made changes to the memory management routine.
It seems like everytime I post here, it boils down to a debugging question. I am looking into a modern book on assembly programming to see if there may be something more I can do in my coding style to help. The only thing Ive read is "The art of assembly language" but I run into conflicting ideas when reading some of the recent blogs and web pages. For instance, I started out breaking the algorithms down into small parts, but then read that all the jumping costs too much time so that should be brought to a minimum, but trying to put all that code in one algorithm makes it hard to maintain, for example, my division algorithm contains some 1,000 lines of code when I call out to other routines within it, putting it all into a single algorithm without any calls it jumped to almost 15,000 lines of code, while it did make it run faster, it was almost impossible to maintain. I have learned my lesson about commenting in the code through
-
April 24th, 2013, 10:15 AM
#6
Re: A few questions about exception handling
As I understand it, the PROC macro does something in order for the call stack to be walked in the event of an exception.
No.
PROC is not a macro
it's an assembler directive that indicates the logical start of a procedure/function.
Technically you don't even need to use PROC/ENDP to make things work. you could also just write a label and explicitely extern it.
It's just an easier way to write a label (the word before 'PROC') and potentially signal to the linker that this label needs to be extern so it is accessible from outside. You can give the assembler extra information so that the assembler can use the right type of 'ret'. By having a PROC/ENDP this also makes segment packing possible, and could allow for dead function removal in the link stage.
PROC in and by itself is in no way related to exception handling (C++ exceptions or SEH)
if you need stack unwinding, you will need to explicitely write code for this. THis is a very complex subject, and not something you'll easily find information for. It usually involves maintaining additional structures that get set up at the start of a function and are cleaned up in the end. and writing explicit cleanup code for each function where you need stack unwinding.
-
April 26th, 2013, 03:53 PM
#7
Re: A few questions about exception handling
Youre right about that OReubens, especially for x64, I have found some info about setting up the stack framesomething along the lines of:
Code:
Func PROC FRAME
push r10
.pushreg r10
push r12
.pushreg r12
.endprolog
.
.
.
rest of function
Func ENDP
which I played around with but I havent found how the epilog is supposed to go. All i know is that, sometimes, when an exception occurs in the assembly code, I have the call stack showing the assembly functions that were called. I am most of the way into creating my own call stack, so that I can keep track of the variables and such through the seperate calls, but if I could set up my functions properly for the crt exception handling then that would be great.
The only part that I think my own call stack would benefit over the crt's is that I am trying to implement a seperate stack for mine so that stack/heap corruption (hopefully) wont affect it.
if I am showing the prolog correctly, you wouldnt happen to know how the epilog is supposed to look would you?
-
April 26th, 2013, 03:59 PM
#8
Re: A few questions about exception handling
by the way, any suggestions on books on modern assembly programming? everything Ive been finding is at least 4 or 5 years old. I am looking for something on general programming. I wouldnt say a begginers guide, but something that covers a little of everything, API calls, writing algorithms, error handling. Ive been using the art of assembly language as a general guide, and Ive spent a lot of time on google.
-
April 28th, 2013, 10:14 PM
#9
Re: A few questions about exception handling
So, I am getting closer to having the exception handling set up, but Ive run into a different problem now. I have the following text equate:
Code:
_totalsub equ<qword ptr[rbp]> ;this is where the _totalsub variable is held
which is relevant to the following call:
Code:
sub rsp, _totalsub
call malloc
add rsp, _totalsub
Now up to this code,the stack is setup correctly, rbp points to the bottom of the stack and the address it points to contains the value of 28h and rsp==rbp. When the program reaches this call it subtracts 28h from the value contained in rsp and stores it back in the rsp register (and the subtract goes correctly), the call to malloc returns what appears to be a valid pointer, but when it gets to the add instruction rbp hasnt changed, rsp still contains 28h less than rbp, and the value pointed to by rbp still contains 28h, when the add instruction executes though, 60h is added to rsp (instead of the 28h), and the value pointed to by rbp gets set to 0. At this point teh only value that is correct is the rbp register itself, though the value it points to is no longer valid.
_totalsub is calulated at the beggining of every function and contains either 28h or 30h depending on how many pushes were used at the beggining of the function.
What am I missing here?
-
April 29th, 2013, 08:42 AM
#10
Re: A few questions about exception handling
Originally Posted by AKRichard
All i know is that, sometimes, when an exception occurs in the assembly code, I have the call stack showing the assembly functions that were called.
Now THIS is setting up a stack frame and it has no direct relation to exceptions or stack unwinding.
This is just about starting your function in a "standard way" so that essentially your stack ends up being a linked list of the local stacks of function to function call.
And this typically involves copying the stackpointer in another register which you then cannot use for anything else. In Intel CPU's this means you can't use BP (16bit) EBP (32bit) or RBP (64bit) as this is your stack frame pointer.
These might help:
http://www.altdevblogaday.com/2012/0...-stack-frames/
http://blogs.msdn.com/b/ntdebugging/...k-walking.aspx
I am most of the way into creating my own call stack, so that I can keep track of the variables and such through the seperate calls, but if I could set up my functions properly for the crt exception handling then that would be great.
somewhat of a futile approach I'm afraid.
If your assembly code itself could throw a SEH, the recommended approach is to explicitely either avoid or trap it in the assembly code.
if you can't, then the next best thing is to write the SEH trap in C++ wrapper and call your assembly function from the C++ wrapper (but this gives you a double call which you probably want to avoid). You could also macro a try/except around your assembly call, but that could end up being an even worse solution since you then have stack unwind information everywhere your asm function is called.
Trying to throw an exception explicitely from asm will be compiler specific and could even change version to version (I know it has in the past for VC), trying to 'pass through' an exception from a lower level call is equally problematic, but why would you want to call a C++ function (that can throw) from asm ?
'normal' prolog/epilog wouldbe dependant on the OS. There's several ways you could implement this I'm not sure Windows64 does it the same way say linux64 does.
For windows:
http://msdn.microsoft.com/en-us/libr...(v=vs.80).aspx
-
April 30th, 2013, 11:12 AM
#11
Re: A few questions about exception handling
in reference to the first link you posted http://www.altdevblogaday.com/2012/0...-stack-frames/. Looking at the diagram of the stack frame at the beggining of the article, you notice 2 orange blocks marked as padding? the placement of the padding would indicate a need to have the stack frame 16 byte aligned at those specific locations(Im not talking as in absolute address location, but a location relative to the other parts of the stack frame). The reason I bring this up is because reading his description of the various part of the stack frame, it sounds as if the lower orange block is used to align the local variable block above it.
He says that the stack grows up in his diagram (so the further up you go the lower the address?) the way I am understanding the article, the non-volatil registers are saved first as evidenced by the fact that that area is directly above the push rbp pointer and return address. Then a possible alignment block, which isnt needed if there are an even number of saved non-valitols figuring the return address puts the stack pointer 8 bytes off of a 16byte alignment, then the pushed rbp register brings it back into alignment. Anyways, the way he describes the padding at that location, it sounds to me as if it is meant to keep the top of the local variables block 16 byte aligned.
The top of the local variable block is also aligned to 16 bytes. 16 is the number though shalt align to, and the number for the alignment shall be 16. That’s the reason for those orange blocks, the padding to keep these blocks of memory aligned. The one higher on the stack only exists if the maximum number of parameters passed to functions is greater than 4 and is an odd number. The existence of the one lower on the stack depends on the size of the non-volatile register save block (including the frame pointer) and the size of the local variables block. Its home is between those two blocks.
He mentions in that paragraph that the lower padding block is supposed to be situated between the non-volitals block and the local variables block, and he also says it is there to make the top of the local variable block 16 byte alinged. I do not understand why that paddings existence would depend on the local variables block above it. I can understand it depending on the non-volitals block (he top of it would not be 16 byte aligned if an odd number of pushes happened) then use the padding to bring it back, but what if the top of the non-volitals IS aligned but you allocate 16X + 8 bytes for the local variables (never mind for the moment you could just add 8 bytes of deadspace to that allocation) if that padding block is required to be in that location, that would make the bottom of the local variables stack 8 bytes out of alignment which would be bad if you were storing xmm registers there wouldnt it?
-
May 1st, 2013, 07:57 PM
#12
Re: A few questions about exception handling
Now Im getting frustrated, there is something seriously wrong with how I am understanding the stack frame setup. Id like to share 2 examples so that, hopefully, someone can point out what I am doing wrong. In this first example, everything executes just fine, it saves the registers like it should, and pops them back allright, but after it executes the last pop instruction, instead of executing the RET that is immediately after it, it jumps to the first instruction in the in the function that follows it.
Code:
GetMem64 PROC FRAME:ExceptionFilter2 tsize:qword
push_reg rbp ;save non-volatil
.pushreg rbp
push_reg rbx ;save non-volatil
.pushreg rbx
push_reg rdi ;save non-volatil
.pushreg rdi
push_reg rsi ;save non-volatil
.pushreg rsi
push_reg r12 ;save non-volatil
.pushreg r12
push_reg r13 ;save non-volatil
.pushreg r13
push_reg r14 ;save non-volatil
.pushreg r14
push_reg r15 ;save non-volatil
.pushreg r15
sub rsp, 304 ;allocate enough room on the stack to save volatil registers and local variables
.allocstack 304
lea rbp, [rsp+144] ;set the frame pointer to the center of the local variables block
.setframe rbp, 144
.endprolog
mov qword ptr[rbp+144], rdx ;save rdx
mov qword ptr[rbp+136], r8 ;save r8
mov qword ptr[rbp+128], r9 ;save r9
mov qword ptr[rbp+120], r10 ;save r10
mov qword ptr[rbp+112], r11 ;save r11
;Body Of Function
add rsp, 304 ;reset the stack pointer and pop the non-volatils
pop r15
pop r14
pop r13
pop r12
pop rsi
pop rdi
pop rbx
pop rbp
RET
GetMem64 ENDP
Free64 PROC _memaddress:qword
.
.
.
this second piece is a modified version of what I saw on the msdn site at :http://msdn.microsoft.com/en-us/libr...v=vs.100).aspx, and it does the same thing, it executes the function correctly, but jumps past the RET after the last pop instruction to the first instruction in the function following it.
Code:
GetMem64 PROC FRAME:ExceptionFilter2 tsize:qword
alloc_stack(sizeof MyFrame + 312) ;allocate enough room on the stack to save volatil registers and local variables
save_reg rbp, MyFrame.SavedRbp ;save non-volatil
save_reg rbx, MyFrame.SavedRbx ;save non-volatil
save_reg rdi, MyFrame.SavedRdi ;save non-volatil
save_reg rsi, MyFrame.SavedRsi ;save non-volatil
save_reg r12, MyFrame.SavedR12 ;save non-volatil
save_reg r13, MyFrame.SavedR13 ;save non-volatil
save_reg r14, MyFrame.SavedR14 ;save non-volatil
save_reg r15, MyFrame.SavedR15 ;save non-volatil
set_frame rbp, 144 ;set the frame pointer to the center of the local variables block
.endprolog
mov qword ptr[rbp+144], rdx ;save rdx
mov qword ptr[rbp+136], r8 ;save r8
mov qword ptr[rbp+128], r9 ;save r9
mov qword ptr[rbp+120], r10 ;save r10
mov qword ptr[rbp+112], r11 ;save r11
;Body Of Function
add rsp, (sizeof MyFrame+312) ;reset the stack pointer and pop the non-volatils
pop r15
pop r14
pop r13
pop r12
pop rsi
pop rdi
pop rbx
pop rbp
RET
GetMem64 ENDP
Free64 PROC _memaddress:qword
.
.
.
In both examples, if I remove the FRAME after the PROC and comment out anything that starts with the . the problem goes away and executes just fine, and in both examples, if I cause an exception control is never sent to the handler. What am I doing wrong?
-
May 3rd, 2013, 04:55 PM
#13
Re: A few questions about exception handling
Hello AKRichard,
I saw your profile and i know that you have information about c++ and assembly
i hope you help me about convert the following C++ code into assembly
int x, y;
while(x > y--)
{
if (x>0 && y<0)
x = y = pow(x , y);
else if(--x > y++)
x = x && y;
else
y = ( x & y)>> 3;
}
Thank you very much .
-
May 3rd, 2013, 09:45 PM
#14
Re: A few questions about exception handling
I saw this post the other day, and I have to agree with both responses you got. First off this piece of code doesnt look like it would acomplish anything meaningfull. If it is homework, show what youve got so far and what exactly you are having problems wiith and youll probably get someone to help you. If people thinkl you are just trying to get someone to do the work for you, they wont help, but if you show youve at least made an effort, they are much more willing to help. Lastly, as allready mentioned, if you run this through the compiler youll be able to see what gets generated.
-
May 4th, 2013, 08:20 AM
#15
Re: A few questions about exception handling
I'm having some problems with convert the c++ code to assembly i need to check it , i didn't know
what the initial value of the AX and BX the program emu8086 give me error
MOV AX,
MOV BX,
DEC BX
CMP AX,BX
JC NEXT
JMP EXIT
NEXT CMP AX,0
JG COND1
JMP ELSE1
COND1 CMP BX,0
JLE POWER
ELSE1 DEC AX
INC BX
CMP AX,BX
JC COND2
POWER MOV AX,BX
MUL BX
JMP EXIT
COND2 CMP AX,0
JNE COND3
JMP ELSE2
COND3 CMP BX,0
JNE COND4
JMP ELSE2
COND4 MOV AX,1
JMP EXIT
ELSE2 AND AX,BX
MOV CL,3
SHR AX,CL
MOV BX,AX
EXIT HLT
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|