VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > 汇编语言 >
  • C#嵌入x86汇编——一个GPIO接口的实现

开始进入工业自动化,买的工控机带有GPIO接口,可用于直接控制继电器。

从厂家拿到接口手册一看,居然是汇编直接操作端口,基本上是IN/OUT指令了。接口很简单,计算位移,读取;计算位移,写入。

这种接口,常见有四种办法,分别是四种语言实现,一是直接写ASM,不过要公开给C#做的应用程序调用,很不容易,另外三种是C/C++/Delphi嵌入汇编,倒是问题不大。

接口实在是小,不想大动干戈,所以想了别的办法。

第五种,用C++/CLI,这也是一个不错的主意。但是我甚至想省掉这个接口DLL,于是有了第六种办法:C#嵌入x86汇编。

 

C#是没办法像C/C++/Delphi那样直接嵌入x86汇编的,所以需要做点手脚。

在汇编里面,我们为了修改一个软件经常找一块空白区域来写汇编代码,然后Jmp过去执行。(不明白这一句话的可以跳过,或者去看雪论坛)

但是显然要在C#代码里面这么做很不现实,即使用C/C++编译得到obj,C#也没办法链接这个obj。(这个涉及编译的也可以跳过)

回头一想(其实不是现在想,07年就做过C#嵌入汇编),其实C#也跑在x86上,IL指令最终还是要编译成x86汇编指令的,我们应该可以这些写汇编指令,所需要的只是一块空间而已。

我们可以申请一块非托管空间嘛,于是有:

// 分配内存
var ptr = Marshal.AllocHGlobal(code.Length);

有了空间,我们就可以把二进制的汇编指令给写进去啦:

// 写入汇编指令
Marshal.Copy(code, 0, ptr, code.Length);

然后呢?.Net提供一个途径,让我们可以把一个内存指针转为一个委托(一直都说.Net的委托其实就是C/C++的函数指针哈):

// 转为委托
return (T)(Object)Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));

 

那么,剩下的问题,就是如何把汇编转为二进制了!

这个我们是不能像C/C++/Delphi那样直接写汇编指令的,所以得走点弯路。

我的做法是用OD随便打开一个程序,在上面直接写汇编代码,然后把汇编的十六进制复制出来,放到C#代码中。

剩下的就不多说了,直接上代码吧!

 

GPIO接口实现

 

image

这里有个旧版本:http://bbs.53wb.com/forum.php?mod=viewthread&tid=137



如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
我不相信神话,我只相信汗水!我不相信命运,我只相信双手!
 
出处:https://www.cnblogs.com/nnhy/archive/2012/05/10/2493761.html

相关教程