digitalmars.D.learn - asm stackframe question
- Stefan (27/27) Apr 07 2012 As a little learning exercise for D I’m writing a fixed point
- bearophile (6/7) Apr 07 2012 Use the "naked" attribute and do it all by yourself? Keep also in
- Stefan (8/11) Apr 08 2012 Then I would also have to do the throw
- Stefan (14/16) Apr 08 2012 BTW: The GCC backend has a pretty powerful ASM support where
- Timon Gehr (7/33) Apr 07 2012 The D calling convention leaves stack cleanup up to the callee. Either
- Stefan (7/13) Apr 08 2012 Hi Timon,
As a little learning exercise for D I’m writing a fixed point library. Part of this is checking standard integer operations for overflows. This is the code for adding 2 longs: int64 add64ov(int64 a, int64 b) { int64 res; asm { mov EAX,a ; mov EDX,a+4 ; add EAX,b ; adc EDX,b+4 ; jo overflow ; mov res,EAX ; // Not optimal: cannot do a ret here because of stack frame previously not correctly set mov res+4,EDX; } return res; overflow: throw new OverflowException("Overflow in 64 bit addition"); } The detour via the res variable is costly; the standard epilogue (I probably need a frame pointer for the exception throw to work): mov ESP, EBP pop EBP ret creates an access violation. Ideas, anyone?
Apr 07 2012
Stefan:Ideas, anyone?Use the "naked" attribute and do it all by yourself? Keep also in mind that D functions that contain ASM don't get inlined in DMD (and probably elsewhere too). Bye, bearophile
Apr 07 2012
On Saturday, 7 April 2012 at 23:50:42 UTC, bearophile wrote:Use the "naked" attribute and do it all by yourself?Then I would also have to do the throw a) fully by myself (with mangling, etc), or b) at least get the stack frame in order so that the throw finds the stack the way it expects...Keep also in mind that D functions that contain ASM don't get inlined in DMD (and probably elsewhere too).Yes, but I don't have much of a choice here... Cheers, Stefan
Apr 08 2012
On Saturday, 7 April 2012 at 23:50:42 UTC, bearophile wrote:Keep also in mind that D functions that contain ASM don't get inlined in DMD (and probably elsewhere too).BTW: The GCC backend has a pretty powerful ASM support where inlining IS possible and you can simply say things like 'give me a free register which supports the XYZ operation' and the backend optimizer does the register juggling (such as saving any used registers on the stack first or choosing a free one) for you - which is essential for sensible inlining. OK, that's not of much use on an architecture with a feeble register set such as i386, but it's a pretty powerful feature with architectures with lots of general registers such as m68k or SPARC. But I'm drifting off... Cheers, Stefan
Apr 08 2012
On 04/08/2012 12:13 AM, Stefan wrote:As a little learning exercise for D I’m writing a fixed point library. Part of this is checking standard integer operations for overflows. This is the code for adding 2 longs: int64 add64ov(int64 a, int64 b) { int64 res; asm { mov EAX,a ; mov EDX,a+4 ; add EAX,b ; adc EDX,b+4 ; jo overflow ; mov res,EAX ; // Not optimal: cannot do a ret here because of stack frame previously not correctly set mov res+4,EDX; } return res; overflow: throw new OverflowException("Overflow in 64 bit addition"); } The detour via the res variable is costly; the standard epilogue (I probably need a frame pointer for the exception throw to work): mov ESP, EBP pop EBP ret creates an access violation. Ideas, anyone?The D calling convention leaves stack cleanup up to the callee. Either mark your function as extern(C) or use leave ret 16 The second option might not be portable across all currently available compilers though.
Apr 07 2012
On Sunday, 8 April 2012 at 01:15:48 UTC, Timon Gehr wrote:The D calling convention leaves stack cleanup up to the callee. Either mark your function as extern(C) or use leave ret 16 The second option might not be portable across all currently available compilers though.Hi Timon, Works fine, thanks! I don't worry too much about compatibility - GCD uses a completely different ASM notation anyway. Cheers, Stefan
Apr 08 2012