• Calling 64-bit assembly language functions lodged inside the Delphi source code


    Code:
    http://www.atelierweb.com/calling-64-bit-assembly-language-functions-lodged-inside-the-delphi-source-code/
    http://www.codeproject.com/Articles/262819/Finally-Bit-Delphi-is-here-and-with-Bit-BASM

    One thing you will notice immediately by looking at the code below is that 32-bit Assembly Language is totally different from 64-bit Assembly language. So, if you want to port 32-bit routines to 64-bit, forget about that and start new ones from scratch.

    Code:
    unit basmTestUnit;
    
    interface
    
    uses
        Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, 
        Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
    
    type
        TBasmTest = class(TForm)
        GroupBox1: TGroupBox;
        lblCaption: TLabel;
        edCaption: TEdit;
        lblInput: TLabel;
        edInput: TEdit;
        btGo: TButton;
    
    procedure btGoClick(Sender: TObject);
    private
    
    public
        { Public declarations }
    end;
    
    var
        BasmTest: TBasmTest;
    
    implementation
    
    {$R *.dfm}
    
    var
        myReturnString : string = 'I am back in Delphi!';
        charCount : integer;
    
    type
        bigarray = array[0..127] of char;
    
    function assemblyTestFunction(myCaption: string; myText : string): bigarray;
    {$IFDEF CPUX86}
    asm
        // This is the 32-bit case with the default Register (Borland Fastcall) calling convention
        // where the Result is an extra var parameter.
        // Arguments are passed in EAX, EDX and ECX, left to right. So, the Result (i.e, the 
        // return value pointer) will come to the function in ECX.
        push edi
        push esi
        push dword ptr 0
        push dword ptr myCaption
        push dword ptr myText
        push dword ptr 0
        mov edi, ecx; // Save the return pointer to EDI because we need ECX as a counter and 
                      // EDI is the destination pointer in a rep movsw instruction
        call MessageBox
        mov esi, dword ptr myReturnString
        mov ecx, [charCount]
        rep movsw
        pop esi
        pop edi
        ret
    end;
    {$ELSE}
    {$IFDEF CPUX64}
        // This is the 64-bit case
        // General rule: Integer and pointer arguments are passed left to right in RCX, RDX, R8
        // and R9. HOWEVER, when there is a large return value, this is the case, RCX contains
        // a pointer to the return space when the callee is called and all Registers usage are
        // pushed one to the right
        //
    asm
        push rsi
        push rdi
        push rbx
        push rbp // Yes, it is a kludge. No need to push rbp, it is just to align the stack.
                 // The alternative is 'and rsp,-16'
        sub rsp, 28h
    
        xor r9, r9
        mov rbx, rcx
        mov rax, rdx
        mov rdx, r8
        mov r8, rax
        xor rcx, rcx
        call MessageBox
    
        mov rdi, rbx
        mov rsi, qword ptr myReturnString
        mov ecx, [charCount]
        rep movsw
        add rsp, 28h
        pop rbp
        pop rbx
        pop rdi
        pop rsi
        ret
    end;
    {$ENDIF CPUX64}
    {$ENDIF}
    
    procedure TBasmTest.btGoClick(Sender: TObject);
    var
        retValue : bigArray;
    begin
        fillchar(retValue, sizeof(bigArray),0);
        charCount := length(myReturnString);
        retValue := assemblyTestFunction(edCaption.Text, edInput.Text);
        showMessage(retValue);
    end;

    Download Example:

    Code:
    http://www.atelierweb.com/downloads/BasmTest.zip


    https://www.board4allcz.eu/showthread.php?t=618277
  • 相关阅读:
    观察者模式
    vim7.4+python3配置
    GAN_李弘毅讲解
    关于Anaconda的环境和包管理
    inception v1-v3 & Xception
    python使用PDB进行调试
    python中“*”、"*args"、"kwargs"三种用法
    解决样本类别不平衡以及困难样本问题的方法总结
    Focal Loss
    RefineDet网络简介(转载)
  • 原文地址:https://www.cnblogs.com/findumars/p/5161468.html
Copyright © 2020-2023  润新知