• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評論-2670  文章-0  trackbacks-0
                光能編譯匯編還是不行的,因為很多東西在編譯的時候不知道,典型的比如放常量那部分的指針等等。主要原因還是因為x87(指FPU部分)沒有指令包含浮點立即數,所有裝載浮點常數的指令都要求提供指針。所以諸如double a=1.2;之類的代碼,需要將1.2預先放置在一個地方然后確定指針的位置。

                于是就遇到了一個問題,如何將編譯后才知道的指針地址寫進去呢?唯一的辦法就是在二進制代碼那里留空,然后使用一張新表記錄哪些地方是需要鏈接的時候填充的。于是可以使用如下結構來構造一張鏈接符號表:
            1 struct LinkingRef
            2 {
            3     VInt            ID;
            4     VInt            Offset;
            5     VSize            Position;
            6     VByte            Bits;//0->8, 1->16, 2->32
            7     VInt            Instruction;
            8 };
                其中ID代表鏈接的對象,譬如可以將0作為常數緩沖區的指針,其他數字作為外部函數的地址等等。Offset代表一個常量偏移,可以將ID所代表的地址加上一個數字之后存放在指令緩沖區的Position偏移處。至于地址的大小使用Bits來表達(因為整數也可以如此搞)。Instruction記錄的是使用這個鏈接單元的指令序號,用于生成錯誤信息。

                于是在編譯之后就可以填充鏈接信息,然后進行鏈接了。這個做完以后就只剩下一個問題了。我們不僅需要常量緩沖區、還需要變量緩沖區,那么如何在常量緩沖區填充之后鎖定呢(為了在試圖修改的時候拋出異常)?Windows API提供了VirtualAlloc、VirtualProtect和VirtualFree來幫我們完成這項工作。為了簡化操作,使用以下的類用于控制內存空間:
             1             struct VL_AsmExecutable
             2             {
             3             private:
             4                 VPointer                FConstantBuffer;
             5                 VPointer                FVariableBuffer;
             6                 VPointer                FInstructionBuffer;
             7                 VInt                    FConstantSize;
             8                 VInt                    FVariableSize;
             9                 VInt                    FInstructionSize;
            10                 VBool                    FAvailable;
            11 
            12             public:
            13                 VL_AsmExecutable();
            14                 ~VL_AsmExecutable();
            15 
            16                 void                    Allocate(VInt Constant , VInt Variable , VInt Instruction);
            17                 void                    Protect();
            18                 void                    Release();
            19                 VPointer                GetConstant();
            20                 VPointer                GetVariable();
            21                 VPointer                GetInstruction();
            22             };

                這里是實現部分:
             1             VL_AsmExecutable::VL_AsmExecutable()
             2             {
             3                 FConstantBuffer=0;
             4                 FVariableBuffer=0;
             5                 FInstructionBuffer=0;
             6                 FConstantSize=0;
             7                 FVariableSize=0;
             8                 FInstructionSize=0;
             9                 FAvailable=false;
            10             }
            11 
            12             VL_AsmExecutable::~VL_AsmExecutable()
            13             {
            14                 Release();
            15             }
            16 
            17             void VL_AsmExecutable::Allocate(VInt Constant , VInt Variable , VInt Instruction)
            18             {
            19                 Release();
            20                 FConstantSize=Constant?Constant:1;
            21                 FVariableSize=Variable?Variable:1;
            22                 FInstructionSize=Instruction?Instruction:1;
            23                 FConstantBuffer=VirtualAlloc(0,FConstantSize,MEM_COMMIT,PAGE_READWRITE);
            24                 FVariableBuffer=VirtualAlloc(0,FVariableSize,MEM_COMMIT,PAGE_READWRITE);
            25                 FInstructionBuffer=VirtualAlloc(0,FInstructionSize,MEM_COMMIT,PAGE_READWRITE);
            26                 FAvailable=true;
            27             }
            28 
            29             void VL_AsmExecutable::Protect()
            30             {
            31                 if(FAvailable)
            32                 {
            33                     DWORD OldProtect=0;
            34                     VirtualProtect(FConstantBuffer,FConstantSize,PAGE_READONLY,&OldProtect);
            35                     VirtualProtect(FInstructionBuffer,FInstructionSize,PAGE_EXECUTE_READ,&OldProtect);
            36                 }
            37             }
            38 
            39             void VL_AsmExecutable::Release()
            40             {
            41                 if(FAvailable)
            42                 {
            43                     VirtualFree(FConstantBuffer,FConstantSize,MEM_RELEASE);
            44                     VirtualFree(FVariableBuffer,FVariableSize,MEM_RELEASE);
            45                     VirtualFree(FInstructionBuffer,FInstructionSize,MEM_RELEASE);
            46                     
            47                     FConstantBuffer=0;
            48                     FVariableBuffer=0;
            49                     FInstructionBuffer=0;
            50                     FConstantSize=0;
            51                     FVariableSize=0;
            52                     FInstructionSize=0;
            53                     FAvailable=false;
            54                 }
            55             }
            56 
            57             VPointer VL_AsmExecutable::GetConstant()
            58             {
            59                 return FConstantBuffer;
            60             }
            61 
            62             VPointer VL_AsmExecutable::GetVariable()
            63             {
            64                 return FVariableBuffer;
            65             }
            66 
            67             VPointer VL_AsmExecutable::GetInstruction()
            68             {
            69                 return FInstructionBuffer;
            70             }

                到了這里就可以修改上一篇文章列出的匯編代碼了。我們將數組{10,1,2,3,4,5,6,7,8,9,10}存放進常量空間然后求和:
             1 VL_AsmCompiled* Compile()
             2 {
             3     VL_AsmProgram Program;
             4     {
             5         VInt Params[]={10,1,2,3,4,5,6,7,8,9,10};
             6         Program.ConstantBuffer.Write(&Params,sizeof(Params));
             7     }
             8     {
             9         // XOR EAX, EAX
            10         INSTRUCTION(XOR)
            11         PARAM_REG_32(EAX)
            12         PARAM_REG_32(EAX)
            13         // MOV EDI, #CONSTANT_BUFFER_POINTER
            14         INSTRUCTION(MOV)
            15         PARAM_REG_32(EDI)
            16         PARAM_IMM_32(0)
            17         LINK(VL_AsmProgram::CONSTANT_BUFFER_POINTER,0);
            18         // MOV ECX, [EDI]
            19         INSTRUCTION(MOV)
            20         PARAM_REG_32(ECX)
            21         PARAM_MI_32(NONE,1,EDI,0)
            22         // @BEGIN:
            23         LABEL(BEGIN)
            24             // CMP ECX, 0
            25             INSTRUCTION(CMP)
            26             PARAM_REG_32(ECX)
            27             PARAM_IMM_32(0)
            28             // JE @END
            29             INSTRUCTION(JE)
            30             PARAM_LABEL(END)
            31             // ADD EAX, [ECX * 4 + EDI]
            32             INSTRUCTION(ADD)
            33             PARAM_REG_32(EAX)
            34             PARAM_MI_32(ECX,4,EDI,0)
            35             // SUB ECX, 1
            36             INSTRUCTION(SUB)
            37             PARAM_REG_32(ECX)
            38             PARAM_IMM_32(1)
            39             // JMP @BEGIN
            40             INSTRUCTION(JMP)
            41             PARAM_LABEL(BEGIN)
            42         // @END:
            43         LABEL(END)
            44         // RET
            45         INSTRUCTION(RET)
            46     }
            47     VL_AsmCompiled* Compiled=Compile(&Program);
            48     if(Compiled->Errors.GetCount())
            49     {
            50         PrintErrors(Compiled);
            51         delete Compiled;
            52         return 0;
            53     }
            54     else
            55     {
            56         return Compiled;
            57     }
            58 }

                然后使用下面的代碼執行編譯后的機器碼:
             1 void RunExecutable(VL_AsmExecutable* Executable)
             2 {
             3     VPointer Buffer=Executable->GetInstruction();
             4     VInt Output=0;
             5     __asm
             6     {
             7         PUSHAD
             8         MOV EAX, dword ptr[Buffer]
             9         INT 3
            10         CALL EAX
            11         MOV dword ptr[Output], EAX
            12         POPAD
            13     }
            14     GetConsole()->Write(L"結果:EAX="+VUnicodeString(Output)+L"\r\n");
            15 }
            16 
            17 void vlmain()
            18 {
            19     GetConsole()->SetTitle(L"Vczh Library++ 2.0 Assembler");
            20     GetConsole()->SetTestMemoryLeaks(true);
            21     GetConsole()->SetPauseOnExit(true);
            22 
            23     VL_AsmCompiled* Compiled=Compile();
            24     if(Compiled)
            25     {
            26         VL_AsmExecutable* Executable=Link(Compiled);
            27         if(Compiled->Errors.GetCount())
            28         {
            29             PrintErrors(Compiled);
            30         }
            31         if(Executable)
            32         {
            33             RunExecutable(Executable);
            34             delete Executable;
            35         }
            36         delete Compiled;
            37     }
            38 }

                鏈接器就完成了。
            posted on 2009-02-22 22:41 陳梓瀚(vczh) 閱讀(1930) 評論(1)  編輯 收藏 引用 所屬分類: JIT

            評論:
            # re: JIT腳本引擎:完成鏈接器的核心功能 2009-02-23 05:21 | Corner Zhang
            這廝咋動作這么快呀!呵呵  回復  更多評論
              
            久久久久久亚洲精品成人| 久久青青草原精品影院| 色综合久久天天综线观看| 久久天天躁狠狠躁夜夜网站| 久久久久久国产精品美女| 国内精品伊人久久久久影院对白| 一本久久a久久精品vr综合| 亚洲精品WWW久久久久久| 日本久久中文字幕| 色偷偷91久久综合噜噜噜噜| 天天综合久久一二三区| 中文字幕无码久久久| 久久九九兔免费精品6| 一本久久a久久精品综合香蕉 | 国产精品久久久久蜜芽| 香蕉久久永久视频| 久久国产精品无码HDAV| 91精品日韩人妻无码久久不卡| 久久亚洲av无码精品浪潮| 国产A级毛片久久久精品毛片| 国产精品久久久久国产A级| 久久亚洲精品中文字幕三区| 久久久久亚洲AV综合波多野结衣 | 久久综合伊人77777麻豆| 久久综合给合久久狠狠狠97色| 嫩草影院久久国产精品| 伊人久久大香线蕉综合热线| 久久精品国产亚洲AV嫖农村妇女| 精品多毛少妇人妻AV免费久久| 久久精品卫校国产小美女| 久久久精品日本一区二区三区| 狠狠88综合久久久久综合网| 亚洲精品乱码久久久久久蜜桃| 国产精品一区二区久久精品| 久久精品国产久精国产一老狼| 国产69精品久久久久9999| 久久精品人人做人人爽电影蜜月| 亚洲国产精品一区二区三区久久 | 欧美粉嫩小泬久久久久久久 | 日本久久久久久久久久| 日本欧美国产精品第一页久久|