在 C# 中使用 C/内联汇编
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18836120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using C/inline assembly in C#
提问by Tigress
Is there some method of using C source mixed with inline asm (this is notC++ code) in a C# app? I'm not picky about how it gets done, if it requires compiling the C/asm into a DLL alongside the C# app, so be it. I'm aware there's no provision for using assembly inside C#, hence this question.
是否有某种方法可以在 C# 应用程序中使用与内联 asm(这不是C++ 代码)混合的 C 源代码?我对它是如何完成的并不挑剔,如果它需要将 C/asm 与 C# 应用程序一起编译成一个 DLL,就这样吧。我知道在 C# 中没有使用程序集的规定,因此这个问题。
Sample code of what I'm trying to incorporate:
我试图合并的示例代码:
SomeFunc(unsigned char *outputData, unsigned char *inputData, unsigned long inputDataLength)
{
_asm
{
//Assembly code that processes inputData and stores result in outputData
}
}
There are some pointer/variable declarations in the C code before that function is declared, but beyond that it's all inline assembly, the declarations are used in the assembly code if that effects anything.
在声明该函数之前,C 代码中有一些指针/变量声明,但除此之外,它都是内联汇编,如果有任何影响,则在汇编代码中使用这些声明。
Objective is to pass 'inputData' from C# and then have access to 'outputData' in the C# program in some fashion. Normally we'd just rewrite the assembler code in native C# but we're on a tight schedule for getting a prototype together and don't see any reason to reinvent the wheel right away if we can temporarily use the existing C/assembly code in some fashion.
目标是从 C# 传递“inputData”,然后以某种方式访问 C# 程序中的“outputData”。通常我们只会用原生 C# 重写汇编代码,但我们的原型制作时间很紧,如果我们可以暂时使用现有的 C/汇编代码,我们看不出有任何理由立即重新发明轮子一些时尚。
采纳答案by Torgrim Brochmann
A good example on how to do this is provided at http://www.codeproject.com/Articles/1392/Using-Unmanaged-code-and-assembler-in-C
http://www.codeproject.com/Articles/1392/Using-Unmanaged-code-and-assembler-in-C提供了一个关于如何执行此操作的好示例
回答by Elshan
Try with Inline IL in C# / VB.Net
在 C#/VB.Net 中尝试使用内联 IL
http://blogs.msdn.com/b/jmstall/archive/2005/02/21/377806.aspx
http://blogs.msdn.com/b/jmstall/archive/2005/02/21/377806.aspx
And This(Dynamically Writing and Executing Native Assembly in C#)
这(在 C# 中动态编写和执行本机程序集)
http://blogs.msdn.com/b/devinj/archive/2005/07/12/438323.aspx
http://blogs.msdn.com/b/devinj/archive/2005/07/12/438323.aspx
回答by Trojaner
It's actually very easy and does not even require reflection.
这实际上非常简单,甚至不需要反思。
[SuppressUnmanagedCodeSecurity]
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int AssemblyAddFunction(int x, int y);
[DllImport("kernel32.dll")]
private static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
....................................
byte[] assembledCode =
{
0x55, // 0 push ebp
0x8B, 0x45, 0x08, // 1 mov eax, [ebp+8]
0x8B, 0x55, 0x0C, // 4 mov edx, [ebp+12]
0x01, 0xD0, // 7 add eax, edx
0x5D, // 9 pop ebp
0xC3 // A ret
};
int returnValue;
unsafe
{
fixed (byte* ptr = assembledCode)
{
var memoryAddress = (IntPtr) ptr;
// Mark memory as EXECUTE_READWRITE to prevent DEP exceptions
if (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress,
(UIntPtr) assembledCode.Length, 0x40 /* EXECUTE_READWRITE */, out uint _))
{
throw new Win32Exception();
}
var myAssemblyFunction = Marshal.GetDelegateForFunctionPointer<AssemblyAddFunction>(memoryAddress);
returnValue = myAssemblyFunction(10, -15);
}
}
Console.WriteLine($"Return value: {returnValue}"); // Prints -5
I have written a blog post on this: https://esozbek.me/inline-assembly-in-csharp-and-dotnet/
我写了一篇关于此的博客文章:https: //esozbek.me/inline-assembly-in-csharp-and-dotnet/