您的位置:首页 > 编程语言 > C#

C#里到底怎么样才能嵌入汇编?

2010-12-15 12:52 288 查看
这是一个老生常谈的问题,但是我昨天又遇到了。敝人不才,实在想象不出C#里怎么能在直接写汇编,直接操作寄存器,直接调用系统中断。。。。。。我回答:由于。net是虚拟了没有CPU的虚拟机,所以不能直接操作寄存器,所以也就不能直接nested汇编。我理解的嵌入就应该是C里的asm(C++里的_asm)

首先看看什么样才是嵌入,查了一下词典,是镶入,好了,不picky了,直接进入正题。

查了一下园子,有如下一些可参考的帖子:

《C#内嵌汇编代码的讨论》

《在.net程序中嵌入asm汇编代码》

《C#调用汇编dll (载)》

《一个C#内联汇编的类 》

诸如此类的,他们的方案大概分为两类:

1.将汇编写在native code的 dll里,然后通过DllImport来调用

2.利用DllImport Windows API,再将汇编码注入调用。

上面的方法看似不同,其实实质相同,都是托管代码对非托管的调用。而且这两种方法都不能叫做嵌入,只能叫做调用而已。第二种方法有些“奇技淫巧”的意味。而且两种方法有个巨大的弊端:均不能实现连调。还有离直接书写汇编相聚深远。

在上面的《在.net程序中嵌入asm汇编代码》 文中的后面的评论中,敝人已经给这个问题发表了评论

可是不幸的是,大家没有看到,而且本人昨天还被人耻笑了一番。

遂有了此文

写个简单的:实现从一个数begin到end的累加,只是demo。

新建一个C++的CLR类库
inline int SumASM(int begin, int end)
{
_asm
{
xor eax, eax //eax清零
mov ecx, end //循环计数放入ecx,不解释
}
lable:
_asm
{
cmp ecx,begin //查看ecx是否到达下限begin
jl exit //如果小于begin则跳出
add eax,ecx //开始累加
loop lable //ecx循环,每次会自减1
}
exit:;
}

然后新建一个class,用作C++/CLI的wrapper
.h
using namespace System;

namespace CPPWrapper {

public ref class Class1
{
// TODO: Add your methods for this class here.
public: static int Sum(int begin,int end);

};
}

.cpp

int CPPWrapper::Class1::Sum(int begin, int end)
{
return SumASM(begin, end);
}

PS: SumASM 如果放在同一个cpp里,要放在Sum方法的前面,这个也不解释。

下面各建一个C++/CLI和C# 的Console application,用作caller。
记得同样得添加引用

using namespace System;
using namespace CPPWrapper;
int main(array<System::String ^> ^args)
{
int a=Class1::Sum(1,100);
return 0;
}
C#的我不写了。
用C++/CLI,这样就可以实现连调了。从托管代码到非托管调试。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: