CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 27
  1. #1
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    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

  2. #2
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    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:

    Quote Originally Posted by AKRichard View Post
    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.

  3. #3
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    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.

  4. #4
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    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.

  5. #5
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    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

  6. #6
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    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.

  7. #7
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    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?

  8. #8
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    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.

  9. #9
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    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?

  10. #10
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: A few questions about exception handling

    Quote Originally Posted by AKRichard View Post
    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

  11. #11
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    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?

  12. #12
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    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?

  13. #13
    Join Date
    Apr 2013
    Posts
    6

    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 .

  14. #14
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    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.

  15. #15
    Join Date
    Apr 2013
    Posts
    6

    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

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured