找传奇、传世资源到传世资源站!

c# 汇编类代码机器码操作

8.5玩家评分(1人评分)
下载后可评
介绍 评论 失效链接反馈

汇编
from clipboardusing System;using UseAsmCode;

using static UseAsmCode.Invoker;

namespace DllTest
{
    class Program
    {
        static readonly string _stringCopy =
            @"
            ; $first - pointer to string
            ; $second - pointer to length

            mov ebx, $first
            add ebx, 8
            mov ecx, $second
            mov ecx, [ecx]
            inc ecx
            mov eax, addr V_String
            L_loop:
            dec ecx
            mov dx, [ebx ecx*2]
            mov [eax ecx*2], dx
            test ecx, ecx
            jnz L_loop
            asmret

            V_String db 28 dup (0)
            ";

        static readonly string _stringReturn =
            @"
            ; $first - pointer to string
            ; $second - pointer to length

            mov ebx, $first
            mov ecx, $second
            mov ecx, [ecx]
            add ecx, 5
            mov eax, addr V_String
            L_loop:
            dec ecx
            mov dx, [ebx ecx*2]
            mov [eax ecx*2], dx
            test ecx, ecx
            jnz L_loop
            asmret

            V_String db 36 dup (0)
            ";

        static readonly string _getAndReturnObject =
            @"
            mov eax, $first
            asmret
            ";

        static readonly string _fullVonNeumann =
            @"
            ; Constants
            STD_OUTPUT_HANDLE equ -0Bh
            STD_INPUT_HANDLE equ -0Ah
            'Y' equ 59h
            'y' equ 79h
            '0' equ 30h
            'x' equ 78h
            
            ; Extern functions
            extern GetStdHandle lib kernel32.dll
            extern WriteConsoleA lib kernel32.dll
            extern WriteConsoleW lib kernel32.dll
            extern ReadConsoleA lib kernel32.dll
            
            ; Main program
            L_prg:
            xor eax, eax
            db 0Fh, 0C7h, 0F0h, 90h
            push eax
            invoke P_NumToHexString eax, addr V_HexString
            mov edx, addr V_HexString
            add edx, 0Ah
            mov byte [edx], 0Dh
            inc edx
            mov byte [edx], 0Ah
            invoke GetStdHandle STD_OUTPUT_HANDLE
            mov edx, addr V_OutHndl
            mov [edx], eax
            push eax
            invoke WriteConsoleA eax, addr V_HexString, 0Ch, addr V_WriteCount, 0
            pop eax
            invoke WriteConsoleW eax, addr V_ContinueMsg, 13h, addr V_WriteCount, 0
            invoke GetStdHandle STD_INPUT_HANDLE
            mov edx, addr V_InHndl
            mov [edx], eax
            invoke ReadConsoleA eax, addr V_ContinueInput, 3, addr V_ReadCount, 0
            mov edx, addr V_ReadCount
            cmp [edx], 2
            je L_prg
            mov edx, addr V_ContinueInput
            cmp byte [edx], 'Y'
            je L_prg
            cmp byte [edx], 'y'
            je L_prg
            pop eax
            asmret
            
            ; Procedures
            proc P_NumToHexString Number:DWORD, Buffer:DWORD
            mov edi, Buffer
            mov byte [edi], '0'
            mov byte [edi 1], 'x'
            mov byte [edi 0Ah], 0
            mov eax, Number
            mov ebx, 8
            L_loop:
            dec ebx
            mov edx, eax
            lea ecx, [ebx * 4]
            shl edx, cl
            and edx, 0F0000000h
            shr edx, 28
            cmp edx, 0Ah
            jl L_NumToStr
            add edx, 7
            L_NumToStr:
            add edx, 30h
            mov byte [ebx edi 2], dl
            test ebx, ebx
            jnz L_loop
            ret 8
            endp
            
            ; Variables
            V_HexString db 0Dh dup (0)
            V_ContinueMsg dw 'Продолжить? (Y/n)', 0Dh, 0Ah, 0
            V_ContinueInput db 4 dup (0)
            V_OutHndl dd 0
            V_InHndl dd 0
            V_ReadCount dd 0
            V_WriteCount dd 0
            ";

        static readonly string _asmInsertionSort =
            @"
            mov esi, $first
            mov edi, $second
            mov edi, [edi]
            mov ecx, 1
            cmp edi, 1
            jle L_end
            L_loop1:
            mov eax, [esi ecx*4]
            mov edx, ecx
            L_loop2:
            mov ebx, [esi edx*4 - 4]
            cmp eax, ebx
            jg L_loop2end
            mov [esi edx*4], ebx
            dec edx
            jnz L_loop2
            L_loop2end:
            mov [esi edx*4], eax
            inc ecx
            cmp ecx, edi
            jne L_loop1
            L_end:
            asmret
            ";

        static string _str = "Hello, World!";
        static int[] _arr, _arr1, _arr2;

        static void Main(string[] args)
        {
            unsafe
            {
                InvokeAsm((void*)0, (void*)0, new SASMCode(
                    @"
                    STD_OUTPUT_HANDLE equ -0Bh

                    extern GetStdHandle lib kernel32.dll
                    extern WriteConsoleW lib kernel32.dll
                
                    invoke GetStdHandle STD_OUTPUT_HANDLE
                    mov edx, addr V_OutHndl
                    mov [edx], eax
                    invoke WriteConsoleW eax, addr V_HelloMsg, 0Eh, addr V_WriteCount, 0
                    asmret

                    V_HelloMsg dw 'Hello World!', 0Dh, 0Ah, 0
                    V_OutHndl dd 0
                    V_WriteCount dd 0
                    ").Code);
            }
            Console.WriteLine();

            Console.WriteLine($"Исходная строка: {_str}");
            int l_len = _str.Length;
            SASMCode c1 = new SASMCode(_stringCopy);
            SafeInvokeAsm(ref _str, ref l_len, c1.Code);
            Console.WriteLine($"Строка в переменной V_String SASM-кода: {c1.GetWStringVariable("V_String")}");
            Console.WriteLine();

            Console.WriteLine($"Исходная строка: {_str}");
            SASMCode c2 = new SASMCode(_stringReturn);
            string copy = SafeInvokeAsm<string, int, string>(ref _str, ref l_len, (byte[])c2);
            Console.WriteLine($"Строка, указатель на которую вернул ассемблерный код: {copy}");
            Console.WriteLine();

            Random rnd = new Random();
            Console.WriteLine($"Передаём объект типа {rnd.GetType()} с хеш-кодом {rnd.GetHashCode()}.");
            Random retRnd = SafeInvokeAsm<Random, Random, Random>(ref rnd, ref rnd, new SASMCode(_getAndReturnObject));
            Console.WriteLine($"Получили объект типа {retRnd.GetType()} с хеш-кодом {retRnd.GetHashCode()}.");
            Console.WriteLine("Проверка функциональности - 10 случайных целых из интервала [0; 5).");
            for (int i = 0; i < 10; i )
            {
                Console.Write(retRnd.Next(0, 5) " ");
            }
            Console.WriteLine();
            Console.WriteLine();

            DateTime n = DateTime.Now;
            SASMCode full = new SASMCode(_fullVonNeumann);
            Console.WriteLine($"Время трансляции: {DateTime.Now - n}.");
            unsafe
            {
                int selected = (int)InvokeAsm((void*)0, (void*)0, (byte[])full);
                Console.WriteLine($"Вы выбрали число {selected} (0x{Convert.ToString(selected, 16)}).");
            }
            Console.WriteLine();

            Console.Write("Введите размер массива для сортировки: ");
            int arraySize = Convert.ToInt32(Console.ReadLine());
            _arr = new int[arraySize];
            _arr1 = new int[arraySize];
            _arr2 = new int[arraySize];
            Random rand = new Random();
            for (int i = 0; i < arraySize; i ) { _arr[i] = rand.Next(); }
            Array.Copy(_arr, _arr1, arraySize);
            Array.Copy(_arr, _arr2, arraySize);
            DateTime start1 = DateTime.Now;
            SASMCode sort = new SASMCode(_asmInsertionSort);
            DateTime start2 = DateTime.Now;
            unsafe
            {
                fixed (int* arrPtr = _arr1)
                {
                    InvokeAsm(arrPtr, &arraySize, (byte[])sort);
                }
            }
            DateTime finish = DateTime.Now;
            Console.WriteLine($"Сортировка вставками на ассемблере заняла (в т.ч. время трансляции): {finish - start1} ({start2 - start1}).");
            start1 = DateTime.Now;
            for (int i = 1; i < _arr2.Length; i )
            {
                int tmp = _arr2[i];
                int j = i - 1;
                for (; j >= 0; j--)
                {
                    if (_arr2[j] > tmp) { _arr2[j 1] = _arr2[j]; }
                    else
                    {
                        break;
                    }
                }
                _arr2[j 1] = tmp;
            }
            finish = DateTime.Now;
            Console.WriteLine($"Сортировка вставками на C# заняла: {finish - start2}.");
            Array.Sort(_arr);
            bool equal = true;
            for (int i = 0; i < arraySize; i )
            {
                if (_arr[i] != _arr1[i] || _arr[i] != _arr2[i])
                {
                    Console.WriteLine($"Разные значения на позиции {i} (ожидаемое - ассемблер - C#): {_arr[i]} - {_arr1[i]} - {_arr2[i]}...");
                    equal = false;
                    break;
                }
            }
            if (equal) { Console.WriteLine("Массивы отсортированы корректно!"); }
        }

        private static void _saveByteCode(SASMCode _c)
        {
            System.IO.BinaryWriter writer = new System.IO.BinaryWriter(new System.IO.FileStream("bcode.bin", System.IO.FileMode.Create));
            writer.Write(_c.Code);
            writer.Close();
        }
    }
}

评论

发表评论必须先登陆, 您可以 登陆 或者 注册新账号 !


在线咨询: 问题反馈
客服QQ:174666394

有问题请留言,看到后及时答复