AccessViolationException may also be a result of Data Execution Prevention (DEP). Code has to be marked as executable otherwise you get an exception with DEP enabled.
Using "assembly" is platform (architecture and OS as well) dependent so you either can use VirtualAlloc with PAGE_EXECUTE_READWRITE or HeapCreate with HEAP_CREATE_ENABLE_EXECUTE without making your code less portable. This may be the cause of the MS.NET failure but you really should respect the ABI like Rodrigo said. Kornél 2008/10/7 Markus Johnsson <[EMAIL PROTECTED]>: > Hi Rodrigo, > > Thank you for a helpful answer. Will explore further later this week. > > Markus > > 2008/10/7 Rodrigo Kumpera <[EMAIL PROTECTED]> >> >> Hi Markus, >> >> Your code works by pure luck as it doesn't respect the ABI of neither >> platforms. >> >> If you really want to follow this path, make sure you first undestand the >> ABI used by your platform and generate >> code that follows it. >> >> For example, your code uses ebx, a callee saved reg, without saving it at >> prologue and restoring at epilogue. >> >> You can start by taking a look at the wikipedia entry >> http://en.wikipedia.org/wiki/Application_binary_interface and then >> dig further in the calling convention part of it - this is specially >> important for windows. >> >> Good luck, >> Rodrigo >> >> >> >> On Mon, Oct 6, 2008 at 6:59 PM, Markus Johnsson >> <[EMAIL PROTECTED]> wrote: >>> >>> Hi, >>> I've been experimenting with x86 assembly coding and execution from >>> within C#, and was happy to get some code (see below) to work. However, when >>> I tried it on Windows and .NET it failed with an AccessViolationException. >>> Should I expect it to fail on mono too in a future release? Is there a >>> better way to do this (i.e. executing x86 code without using a C >>> library)? Using mono the code below compiles and runs fine on both Windows >>> (mono 2.0) and Linux (mono svn). >>> cheers >>> Markus >>> >>> using System; >>> using System.Text; >>> using System.Runtime.InteropServices; >>> class X86AssemblyExec { >>> [UnmanagedFunctionPointer(CallingConvention.Cdecl)] >>> private delegate int TheDelegate(); >>> public static void Main(string[] args) { >>> // x86 assembly: >>> // mov eax 8 B8 08 00 00 00 >>> // mov ebx 9 BB 09 00 00 00 >>> // add eax ebx 01 d8 >>> // ret C3 >>> // opcode >>> byte [] code = new byte[14]; >>> code[0] = (byte) 0xB8; >>> code[1] = (byte) 0x08; >>> code[2] = (byte) 0x00; >>> code[3] = (byte) 0x00; >>> code[4] = (byte) 0x00; >>> >>> code[5] = (byte) 0xBB; >>> code[6] = (byte) 0x09; >>> code[7] = (byte) 0x00; >>> code[8] = (byte) 0x00; >>> code[9] = (byte) 0x00; >>> >>> code[10] = (byte)0x01; >>> code[11] = (byte)0xd8; >>> >>> code[12] = (byte)0xC3; >>> >>> code[13] = 0; >>> unsafe { >>> fixed (void *ptr = code) { >>> >>> // create the delegate >>> TheDelegate del = (TheDelegate) >>> Marshal.GetDelegateForFunctionPointer( >>> new IntPtr(ptr), typeof(TheDelegate)); >>> >>> // call the function >>> int x = del(); >>> >>> // outputs 17 >>> Console.WriteLine(x); >>> } >>> } >>> } >>> } >>> >>> _______________________________________________ >>> Mono-list maillist - [email protected] >>> http://lists.ximian.com/mailman/listinfo/mono-list >>> >> > > > _______________________________________________ > Mono-list maillist - [email protected] > http://lists.ximian.com/mailman/listinfo/mono-list > > _______________________________________________ Mono-list maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-list
