Let's say we use NASM as they do in this answer: how to write hellow world in assembly under windows.
I got a couple of thoughts and questions regarding assembly combined with c# or any other .net languages for that matter.
First of all I want to be able to create a library that has the following function HelloWorld
that takes this parameter:
In C# the method signature would looke like this: void HelloWorld(string name)
and it would print out something like
Hello World from name
I've searched around a bit but can't find that much good and clean material for this to get me started. I know some basic assembly from before mostly gas
though.
So any pointers in the right direction is very much apprechiated.
To sum it up
Bonus features
When creating libraries in assembly or c, you do follow a certain "pre defined" way, the c calling convetion, correct?
Something like this should get you a working 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
You then just need to call the 'hello' function using P/Invoke. It doesn't clean up after itself, so you need to set CallingConvention to Cdecl; you also need to tell it you're using ANSI strings. Untested, but it should work fine.
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_);
}
}
I will first cover basic guidelines for doing what you want.. then I will try to explain how to do the Hello World example.
The first step would be writing a function, and making dll out of it. Function in assembly should adhere to one of calling standards, stdcall is the most common one (you can read more about stdcall and other calling standards here) An example of creating an dll with asm can be found here
The second step would be to import the method in a managed language using P/Invoke. You can read more about it here
And that's it..
Now for your mentioned example, you will need to make an asm function that takes all the input parameters and passes it to some other function that knows how to print to stdout (printf from standard c lib as mentioned above, or using winapi calls like here)
After that you'll need to import the dll to C#, as described above. Things you should take special care about are, character encoding for strings and clean up of data. They are all mentioned in the 3rd link I provided (marshaling text section).
Bonus part:
This is a very good question and deserves a vote from me. In relation to your question, the only way this can be done as Cody has pointed out his assembler routine, is to build a DLL based on that, and from there to use p/Invoke using interops such as
[DllImport("mylib.dll")]
etc. However, unfortunately, due to the nature of the C# or any other language for that matter, the CLR runtime environment is using the managed code. It would be awkward in having the CLR or the assembler to set up the stack frame, registers, then cross jumping from native world to the managed world. That would be a hairy job to do, but if anyone has seen that kind of thing, please leave a comment at the end of my answer and I will amend this answer accordingly.
And therefore, to my knowledge, there is no way to inline an assembler routine, by assembler, in that context, using system registers such as eax, ebx, stack frames etc, into a CLR code, just like the sample of code that Cody above has supplied in his answer. It would have held true with C/C++ in this case:
void foo(void){ _asm{ xor ecx, ecx mov eax, 1 .... } }
It would be nice to do that from the CLR perspective like this in order to optimize code further, in theory at least but that would be an insurmountable job for the CLR to actually host that kind of thing like this, there is one exception... it can be done with Managed C++ compiler which can do this, but NOT from VB.NET/C# anyway:
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 } }
However, while on the subject, it can be done to generate IL code to native assembler, now, as I write this, I am not 100% sure if this can be done in the reverse, See here for a detailed description of how this can happen
But however, the only way of working on CLR assembly is handwriting the IL code and compiling it instead, that is, the assembler of the CLR runtime, directly, in very much the same way as native assembler can be called by native (read NON-CLR binaries), see this article here on how to accomplish this also.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With