假设我们在答案中使用NASM:how to write hellow world in assembly under windows。
关于汇编和c#或任何其他.net语言,我得到了一些想法和问题。
首先,我希望能够创建一个具有以下函数HelloWorld
的库,该函数具有以下参数:
在C#中,方法签名会像这样:void HelloWorld(string name)
,它会打印出类似
Hello World来自 name
我已经搜索了一下但是找不到那么好的和干净的材料让我开始。我之前知道一些基本的程序集gas
。
所以任何指向正确方向的指针都非常适用。
总结
奖金功能
在程序集或c中创建库时,您是否遵循某种“预定义”方式,即c调用对话,是否正确?
答案 0 :(得分:11)
这样的事情会让你找到一个可用的DLL:
extern _printf
section .text
global _hello
_hello:
push ebp
mov ebp, esp
mov eax, [ebp+12]
push eax
push helloWorld
call _printf
add esp, 8
pop ebp
ret
export _hello
helloWorld: db 'Hello world from %s', 10, 0
然后你需要使用P / Invoke调用'hello'函数。它不会自行清理,所以你需要将CallingConvention设置为Cdecl;你还需要告诉它你正在使用ANSI字符串。未经测试,但应该可以正常工作。
using System.Runtime.InteropServices;
namespace Test {
public class Test {
public static Main() {
Hello("C#");
}
[DllImport("test.dll", EntryPoint="hello", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
public static extern Hello(string from_);
}
}
答案 1 :(得分:3)
我将首先介绍做你想做的事情的基本指导原则。然后我将尝试解释如何做Hello World示例。
第一步是编写一个函数,并从中创建dll。汇编中的函数应该遵循一个调用标准,stdcall是最常见的一个(你可以阅读更多关于stdcall和其他调用标准的here)可以找到用asm创建一个dll的例子here
第二步是使用P / Invoke以托管语言导入方法。您可以阅读更多相关信息here
就是这样......
现在,对于您提到的示例,您需要创建一个asm函数,该函数接受所有输入参数并将其传递给知道如何打印到stdout的其他函数(如上所述,从标准c lib中打印printf,或使用winapi)调用here)
之后,您需要将dll导入C#,如上所述。您应该特别注意的事项是字符串的字符编码和数据清理。它们都在我提供的第3个链接中提到(编组文本部分)。
奖金部分:
答案 2 :(得分:1)
这是一个非常好的问题,值得我投票。关于你的问题,Cody指出他的汇编程序例程的唯一方法就是基于它构建DLL,并从那里使用p / Invoke使用诸如
之类的interop[DllImport("mylib.dll")]
等。但是,遗憾的是,由于C#或任何其他语言的性质,CLR运行时环境正在使用托管代码。让CLR或汇编程序设置堆栈框架,注册,然后从本地世界交叉跳转到托管世界会很尴尬。这将是一件毛茸茸的工作,但如果有人见过这样的事情,请在我的答案结束时发表评论,我会相应地修改这个答案。
因此,据我所知,没有办法通过汇编程序在汇编程序中使用系统寄存器(如eax,ebx,堆栈帧等)将一个汇编程序内联到CLR代码中,就像样本一样。 Cody上面提供的代码在他的回答中提供。在这种情况下,它将适用于C / C ++:
void foo(void){ _asm{ xor ecx, ecx mov eax, 1 .... } }
从CLR的角度来看这样做会很好,以便进一步优化代码,至少在理论上这对CLR实际托管这样的事情是一个不可逾越的工作,有一个异常......可以使用Managed C ++编译器完成此操作,但无论如何 NOT 来自VB.NET / C#:
private void mycsfunction(string s){ // Managed code ahoy StringBuilder sb = new StringBuilder(s); ...... _asm{ push ebp mov ebp, esp lea edx, offset sb .... mov eax, 1 pop ebp } }
然而,在这个主题上,可以将IL代码生成到本机汇编程序,现在,正如我写的那样,我不能100%确定是否可以反过来这样做,请参阅here有关如何发生这种情况的详细说明
但是然而,处理CLR程序集的唯一方法是手写IL代码并改为编译它,即直接编译CLR运行时的汇编程序,其方式与本机汇编程序可以由本机调用(读取NON-CLR二进制文件),请参阅本文here,了解如何完成此操作。
答案 3 :(得分:0)
在我看来,你的问题是双重的:
2的答案是使用P / Invoke。有关该主题的大量文档和教程可用,例如: http://msdn.microsoft.com/en-us/magazine/cc164123.aspx