Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/whiteblackgoose/asmtodelegate
Compile asm code into C# functions on fly!
https://github.com/whiteblackgoose/asmtodelegate
Last synced: 17 days ago
JSON representation
Compile asm code into C# functions on fly!
- Host: GitHub
- URL: https://github.com/whiteblackgoose/asmtodelegate
- Owner: WhiteBlackGoose
- License: mit
- Created: 2021-10-20T19:55:34.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2022-02-05T18:04:16.000Z (almost 3 years ago)
- Last Synced: 2024-10-19T18:47:27.829Z (30 days ago)
- Language: C#
- Size: 95.7 KB
- Stars: 112
- Watchers: 6
- Forks: 7
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Asm To Delegate
Compile asm code into C# functions on fly! For now supports only x86 Windows 64-bit.
## Get started
Get the lib (it's probably distributed by nuget) and it's recommended to write these usings:
```cs
using Iced.Intel;
using static Iced.Intel.AssemblerRegisters;
using AsmToDelegate;
```## Examples
### Add two integers
Adds two integers:
```cs
var asm = new Assembler(bitness: 64);
asm.mov(rax, rcx);
asm.add(rax, rdx);
asm.ret();
var add = asm.ToFunctionPointerWinX64();
Assert.Equal(44ul, add(31, 13));
```### Something complex
Finds `a * b + c * d`:
```cs
var asm = new Assembler(bitness: 64);var a = rcx;
var b = rdx;
var c = r8;
var d = r9;asm.mov(rax, a);
asm.imul(rax, b);
asm.mov(rbx, c);
asm.imul(rbx, d);
asm.add(rax, rbx);
asm.ret();
var add = asm.ToFunctionPointerWinX64();
Assert.Equal(210L, add(5, 2, 10, 20));
```... assuming the [conventions](https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160).
### Compute TSC
Returns [**Time Stamp Counter**](https://en.wikipedia.org/wiki/Time_Stamp_Counter):
```cs
var asm = new Assembler(bitness: 64);
asm.rdtsc();
asm.shl(rdx, 32);
asm.add(rax, rdx);
asm.ret();
var tsc = asm.ToFunctionPointerWinX64();
Console.WriteLine($"{tsc()} cycles since last reset");
```### What about F#?
F# has *computation expressions* which allow for an absolutely mind-blowing syntax.
Here's the same function which computes the number of cycles.
```fs
open AsmToDelegate.FSharplet getCycles = asm {
rdtsc
shl rdx 32uy
add rax rdx
ret
}printfn $"{getCycles ()}"
```Feedback from [Fred](https://github.com/333fred):
![feedback](./feedback.png)
## NaiveNanoBench
I was inspired by [nanoBench](https://github.com/andreas-abel/nanoBench), advanced linux tool for measuring
costs of different instructions. So I made a *very* naive version of it for C#.Here's an example. We measure the time taken by `mov rcx, 6` instruction.
```cs
using Iced.Intel;
using static Iced.Intel.AssemblerRegisters;
using AsmToDelegate;
using NaiveNanoBench;var movFunction = new Assembler(bitness: 64);
for (int i = 0; i < 1000; i++)
{
movFunction.mov(rcx, 6);
}
movFunction.ret();var compiled = movFunction.ToUnmanagedFunctionWinX64();
var bench = new NanoBench(userInvokationsPerCall: 1000);
bench.Bench(compiled.Delegate);
bench.ShowDistributionOfResults();
```It will warm up the thing until it more or less understands what time it takes to run the delegate,
then it will switch to the actual measurement phase, perform 100 measurements where each of them
takes approximately 1 second, and return the mean and the distribution. It all depends on a *lot*
of factors, so I will just show the result (you can bench your own), as it's an example for the lib,
not real answer to "how much time it takes to run a single `mov`".```
mean: 175 ns.
```![](./distr.png)