将Javascript代码转换为汇编

    将Javascript代码转换为汇编

function print_str(astr)
{
    let pstr = "劝君更尽一杯酒\n西出阳关无故人\n";
    document.write(astr + pstr);
}
print_str("渭城朝雨浥轻尘\n客舍青青柳色新\n")

                        Javascript代码文件:just.js

编译:用 YC命令: ycc just.js 生成执行文件: just.exe
运行:在cmd界面执行just.exe后,输出下列文字:
      渭城朝雨浥轻尘
      客舍青青柳色新
      劝君更尽一杯酒
      西出阳关无故人

编译方式

  1. 命令ycc just.js
    只生成而不运行,只能检查语法错误,不能检查运行时错误。与YC编辑器的F6键功能《生成执行代码》相同。
  2. 命令ycc –c just.js
    编译后自动运行,语法错误和运行时错误都可以检查出来,程序中用到的其它文件都被放入exe。若把程序拷贝到其它地方运行,只需要一个exe文件,而不必附带其它所用到的文件,与YC编辑器的F5键功能《生成js执行代码并检测错误》相同。

汇编代码
    把just.js调入YC编辑器,按Ctrl+F5键,生成下面的汇编代码。分析Javascript程序的汇编代码有助于理解Javascript的运行机理。

try_code  //异常处理函数
{
016C4240 50               push    eax               //push try_pos
016C4241 ff7508           push    dword [ebp+08h]   //push pFunc
016C4244 ff75ac           push    dword [ebp-54h]   //push stk_ptr
016C4247 57               push    edi               //push phtml
016C4248 e81f764902       call    _int64 _stdcall js_try_proc(phtml,stk_ptr,pFunc,try_pos)
016C424D 8be2             mov     esp,edx
016C424F 0bc0             or      eax,eax           //eax!=0时,eax为catch(…) 位置
016C4251 7503             jne     (016C4256 = 016C4253+00000003)
016C4253 8b45a0           mov     eax,dword [ebp-60h]   //eax=程序结束位置
016C4256 ffe0             jmp     eax                   //跳到catch(…)或程序结束位置
}

//全局代码
0 var this                                              //变量this
1 var print_str  funcNo=1 argnum=1  obj_10000111        //变量print_str
2 var document                                          //变量document
{
08C20790 55               push    ebp
08C20791 8bec             mov     ebp,esp
08C20793 83ec60           sub     esp,0x00000060
08C20796 53               push    ebx
08C20797 56               push    esi
08C20798 57               push    edi
08C20799 8b5d08           mov     ebx,dword [ebp+08h]  //ebx = FUNC_STRUCTDATA *pFunc
08C2079C ff7344           push    dword [ebx+44h]      //push pFunc->arg_ebp
08C2079F 896b44           mov     dword [ebx+44h],ebp  //pFunc->arg_ebp = ebp
08C207A2 bfc87da404       mov     edi,0x04A47DC8       //edi = phtml
08C207A7 8b37             mov     esi,dword [edi]  //esi = jdt->func_stack_Mem.locvarBuf
08C207A9 8965ac           mov     dword [ebp-54h],esp         //try_stack = esp
08C207AC c745a05908c208   mov     dword [ebp-60h],0x08C20859  //try_exitPos = 08C20859
08C207B3 8d8424e0ef0a00   lea     eax,[esp+AEFE0h]
08C207BA 3b8700030000     cmp     eax,dword [edi+300h]     //比较esp+AEFF0h 和s tack_top
08C207C0 770b             ja      (08C207CD = 08C207C2+0000000b)      //判断堆栈是否溢出
08C207C2 57               push    edi
08C207C3 e80bb4f3fa       call    int _stdcall memory_overflow(YHTML *jdt)//堆栈溢出处理
08C207C8 e9733aaaf8       jmp     (016C4240 = 8C207CD+f8aa3a73)           //退出程序
08C207CD 83ec20           sub     esp,0x00000020
08C207D0 66c704240608     mov     word [esp],0x0806    //设置[esp] = "渭城朝雨浥轻尘..."
08C207D6 c74424080889a408 mov     dword [esp+08h],0x08A48908
08C207DE c744240c10000000 mov     dword [esp+0Ch],0x00000010
08C207E6 54               push    esp                   //push  argval
08C207E7 6a01             push    0x00000001            //push  argnum = 1
08C207E9 8d442418         lea     eax,[esp+18h]
08C207ED 50               push    eax                   //push  pReturnV
08C207EE 807e1007         cmp     byte [esi+10h],0x07   //判断变量是否是对象
08C207F2 740c             je      (08C20800 = 08C207F4+0000000c)
08C207F4 8d5610           lea     edx,[esi+10h]
08C207F7 52               push    edx   //push srcdat  嵌入到Javascript的C/C++函数之地址
08C207F8 57               push    edi   //push phtml
08C207F9 e88abbf7fa       call    void js_call_cpp_function(jdt,...)   //调用c/c++函数
08C207FE eb42             jmp     (08C20842 = 8C20800+0000042)
08C20800 8b7e1c           mov     edi,dword [esi+1Ch]   //以下代码取出变量, 如:print_str
08C20803 ba806967ff       mov     edx,0xFF676980
08C20808 2b5618           sub     edx,dword [esi+18h]
08C2080B 8b4738           mov     eax,dword [edi+38h]
08C2080E 8b0490           mov     eax,dword [eax+edx*4]
08C20811 8b00             mov     eax,dword [eax]
08C20813 8b4824           mov     ecx,dword [eax+24h]       //[ecx] = print_str
08C20816 80790c11         cmp     byte [ecx+0Ch],0x11       //判断变量是否是JS函数
08C2081A 75d8             jne     (08C207F4 = 08C2081C+ffffffd8)
08C2081C 8b4010           mov     eax,dword [eax+10h]
08C2081F 83f800           cmp     eax,0x00000000            //判断是否是JS内置函数
08C20822 7f0d             jg      (08C20831 = 08C20824+0000000d)
08C20824 6a00             push    0x00000000                //push objdat  以下执行JS内置函数
08C20826 50               push    eax                       //push funcNo
08C20827 6a00             push    0x00000000                //push new_flag
08C20829 57               push    edi                       //push phtml
08C2082A e800baf7fa       call    void _stdcall js_call_inner_function(YHTML *jdt,...)
08C2082F eb11             jmp     (08C20842 = 8C20831+0000011)
08C20831 6a00             push    0x00000000
08C20833 6a00             push    0x00000000
08C20835 8b9714020000     mov     edx,dword [edi+214h]
08C2083B 8b0482           mov     eax,dword [edx+eax*4]
08C2083E 50               push    eax
08C2083F ff5008           call    dword [eax+08h]         //调用 print_str() 函数
08C20842 83c410           add     esp,0x00000010
08C20845 66833c2406       cmp     word [esp],0x0006       //判断函数返回值是否需释放内存
08C2084A 750a             jne     (08C20856 = 08C2084C+0000000a)
08C2084C ff742408         push    dword [esp+08h]
08C20850 e8dfb3f3fa       call    void free(void *_Memory) //释放字符串所占内存
08C20855 59               pop     ecx
08C20856 83c410           add     esp,0x00000010
08C20859 8b5d08           mov     ebx,dword [ebp+08h]   //ebx = pFunc
08C2085C 8f4344           pop     dword [ebx+44h]       //pop  pFunc->arg_ebp
08C2085F 5f               pop     edi
08C20860 5e               pop     esi
08C20861 5b               pop     ebx
08C20862 8be5             mov     esp,ebp
08C20864 5d               pop     ebp
08C20865 c21800           ret     0018
}

----------------函数 print_str(astr)   func=1  parentFunc=0  argnum=1
0 var astr         //形式变量
1 const this       //this对象
2 const arguments  //arguments 对象
3 let pstr         //局部变量
{
08BB29A8 55              push    ebp
08BB29A9 8bec            mov     ebp,esp
08BB29AB 81eca0000000    sub     esp,0x000000A0
08BB29B1 53              push    ebx
08BB29B2 56              push    esi
08BB29B3 57              push    edi
08BB29B4 8b5d08          mov     ebx,dword [ebp+08h]  //ebx = pFunc
08BB29B7 ff7344          push    dword [ebx+44h]      //push  pFunc->arg_ebp
08BB29BA 896b44          mov     dword [ebx+44h],ebp  //pFunc->arg_ebp = ebp
08BB29BD 8b4304          mov     eax,dword [ebx+04h]
08BB29C0 83f808          cmp     eax,0x00000008
08BB29C3 7506            jne     (08BB29CB = 08BB29C5+00000006)
08BB29C5 53              push    ebx      //申请局部堆栈指针缓冲区
08BB29C6 e8ab90fafa      call    int _stdcall alloc_function_locmem(FUNC_STRUCTDATA *pFunc)
08BB29CB 8d9560ffffff    lea     edx,[ebp-A0h]
08BB29D1 8b0b            mov     ecx,dword [ebx]
08BB29D3 891481          mov     dword [ecx+eax*4],edx  //设置局部堆栈地址
08BB29D6 ff4304          inc     dword [ebx+04h]        //局部堆栈号 += 1
08BB29D9 b001            mov     al,0x01                //al = undefined
08BB29DB 8b4d14          mov     ecx,dword [ebp+14h]    //ecx = 函数返回值地址
08BB29DE 8801            mov     byte [ecx],al          //设置函数返回值 = undefined
08BB29E0 888560ffffff    mov     byte [ebp-A0h],al      //设置 astr = undefined
08BB29E6 888570ffffff    mov     byte [ebp-90h],al      //设置 this = undefined
08BB29EC 884580          mov     byte [ebp-80h],al      //设置 arguments = undefined
08BB29EF 884590          mov     byte [ebp-70h],al      //设置 pstr = undefined
08BB29F2 8b4d18          mov     ecx,dword [ebp+18h]
08BB29F5 83f901          cmp     ecx,0x00000001
08BB29F8 7605            jbe     (08BB29FF = 08BB29FA+00000005)
08BB29FA b901000000      mov     ecx,0x00000001
08BB29FF c1e102          shl     ecx,0x02
08BB2A02 8b751c          mov     esi,dword [ebp+1Ch]
08BB2A05 8dbd60ffffff    lea     edi,[ebp-A0h]
08BB2A0B f3a5            repe    movsd
08BB2A0D bfc87da404      mov     edi,0x04A47DC8
08BB2A12 8b472c          mov     eax,dword [edi+2Ch]   //eax = pFunction
08BB2A15 8945a8          mov     dword [ebp-58h],eax
08BB2A18 ff772c          push    dword [edi+2Ch]  //push  pFunction
08BB2A1B ff7508          push    dword [ebp+08h]  //push  pFunc
08BB2A1E 8f472c          pop     dword [edi+2Ch]  //pop   pFunction
08BB2A21 8b37            mov     esi,dword [edi]
08BB2A23 8965ac          mov     dword [ebp-54h],esp
08BB2A26 c745a0ef2abb08  mov     dword [ebp-60h],0x08BB2AEF
08BB2A2D 837f2800        cmp     dword [edi+28h],0x00000000
08BB2A31 7407            je      (08BB2A3A = 08BB2A33+00000007)
08BB2A33 33c0            xor     eax,eax
08BB2A35 e90618b1f8      jmp     (016C4240 = 8BB2A3A+f8b11806)
08BB2A3A 66c745900608    mov     word [ebp-70h],0x0806    //设置pstr的类型为JS_string_const
08BB2A40 c74598e088a408  mov     dword [ebp-68h],0x08A488E0 //设置pstr = "劝君更尽一杯酒..."
08BB2A47 c7459c0f000000  mov     dword [ebp-64h],0x0000000F //设置pstr.length = 15
08BB2A4E 8d8424e0ef0a00  lea     eax,[esp+AEFE0h]
08BB2A55 3b8700030000    cmp     eax,dword [edi+300h]      //比较esp+AEFF0h 和s tack_top
08BB2A5B 770b            ja      (08BB2A68 = 08BB2A5D+0000000b)   //判断堆栈是否溢出
08BB2A5D 57              push    edi
08BB2A5E e87091fafa      call    int _stdcall memory_overflow(YHTML *jdt) //堆栈溢出处理
08BB2A63 e9d817b1f8      jmp     (016C4240 = 8BB2A68+f8b117d8)            //退出程序
08BB2A68 83ec20          sub     esp,0x00000020
08BB2A6B 83ec10          sub     esp,0x00000010
08BB2A6E 8d5590          lea     edx,[ebp-70h]
08BB2A71 52              push    edx              //push  pstr
08BB2A72 8d9560ffffff    lea     edx,[ebp-A0h]    //edx = astr 的地址
08BB2A78 52              push    edx              //push  astr
08BB2A79 8d442408        lea     eax,[esp+08h]    //eax = stk_ptr
08BB2A7D 50              push    eax              //push  stk_ptr
08BB2A7E e88ba4fefa      call    void _stdcall js_val_add_val_to_stack(JSVAL *stk_ptr,...)
08BB2A83 83c410          add     esp,0x00000010
08BB2A86 8b4424f0        mov     eax,dword [esp-10h]   //esp-10h = astr + pstr 的地址
08BB2A8A 663d0601        cmp     ax,0106
08BB2A8E 7507            jne     (08BB2A97 = 08BB2A90+00000007)
08BB2A90 0d00020000      or      eax,0x00000200
08BB2A95 eb05            jmp     (08BB2A9C = 8BB2A97+0000005)
08BB2A97 0d00010000      or      eax,0x00000100
08BB2A9C 890424          mov     dword [esp],eax
08BB2A9F 8b4424f8        mov     eax,dword [esp-08h]
08BB2AA3 89442408        mov     dword [esp+08h],eax
08BB2AA7 8b4424fc        mov     eax,dword [esp-04h]
08BB2AAB 8944240c        mov     dword [esp+0Ch],eax
08BB2AAF 54              push    esp               //push  argval = astr + pstr
08BB2AB0 6a01            push    0x00000001        //push  argnum = 1
08BB2AB2 8d55c0          lea     edx,[ebp-40h]
08BB2AB5 52              push    edx               //push  desJval
08BB2AB6 6a02            push    0x00000002        //push  LOCAL_pos
08BB2AB8 68f2000001      push    0x010000F2        //push  vName = 010000F2
08BB2ABD 6899990000      push    0x00009999        //push  var_deep
08BB2AC2 57              push    edi               //push  phtml
08BB2AC3 e86e94fefa      call    JSVAL* _stdcall js_get_parent_var(YHTML *jdt,...)
08BB2AC8 8bd8            mov     ebx,eax           //eax = objdat
08BB2ACA 53              push    ebx               //push  objdat
08BB2ACB 6a00            push    0x00000000        //push  new_flag = 0
08BB2ACD 68f2030001      push    0x010003F2        //push  vName = 010003F2
08BB2AD2 57              push    edi               //push  phtml   call document.write()
08BB2AD3 e8cf7efefa      call    void _stdcall js_call_object_method(YHTML *jdt,...)
08BB2AD8 83c410          add     esp,0x00000010
08BB2ADB 66833c2406      cmp     word [esp],0x0006   //[esp] = document.write() 的返回值
08BB2AE0 750a            jne     (08BB2AEC = 08BB2AE2+0000000a)
08BB2AE2 ff742408        push    dword [esp+08h]
08BB2AE6 e84991fafa      call    void free(void *_Memory) //释放字符串所占内存
08BB2AEB 59              pop     ecx
08BB2AEC 83c410          add     esp,0x00000010
08BB2AEF 8b5d08          mov     ebx,dword [ebp+08h]   //ebx = pFunc
08BB2AF2 807b4b00        cmp     byte [ebx+4Bh],0x00
08BB2AF6 7406            je      (08BB2AFE = 08BB2AF8+00000006)
08BB2AF8 57              push    edi
08BB2AF9 e8bb8bfafa      call    void _stdcall save_parent_local_var(YHTML *jdt)
08BB2AFE b904000000      mov     ecx,0x00000004
08BB2B03 8db560ffffff    lea     esi,[ebp-A0h]
08BB2B09 66813e0604      cmp     word [esi],0x0406  //以下循环释放局部变量字符串所占内存
08BB2B0E 750b            jne     (08BB2B1B = 08BB2B10+0000000b)
08BB2B10 51              push    ecx
08BB2B11 ff7608          push    dword [esi+08h]
08BB2B14 e81b91fafa      call    void free(void *_Memory) //释放字符串所占内存
08BB2B19 59              pop     ecx
08BB2B1A 59              pop     ecx
08BB2B1B 83c610          add     esi,0x00000010
08BB2B1E e2e9            loop    (08BB2B09 = 08BB2B20+ffffffe9)
08BB2B20 8b4d18          mov     ecx,dword [ebp+18h]
08BB2B23 e31e            jecxz   (08BB2B43 = 08BB2B25+0000001e)
08BB2B25 8b751c          mov     esi,dword [ebp+1Ch]
08BB2B28 803e06          cmp     byte [esi],0x06
08BB2B2B 7511            jne     (08BB2B3E = 08BB2B2D+00000011)
08BB2B2D 807e0101        cmp     byte [esi+01h],0x01    //以下循环释放形式变量字符串所占内存
08BB2B31 770b            ja      (08BB2B3E = 08BB2B33+0000000b)
08BB2B33 51              push    ecx
08BB2B34 ff7608          push    dword [esi+08h]
08BB2B37 e8f890fafa      call    void free(void *_Memory) //释放字符串所占内存
08BB2B3C 59              pop     ecx
08BB2B3D 59              pop     ecx
08BB2B3E 83c610          add     esi,0x00000010
08BB2B41 e2e5            loop    (08BB2B28 = 08BB2B43+ffffffe5)
08BB2B43 837b0c00        cmp     dword [ebx+0Ch],0x00000000  //判断本函数是否调用了eval()函数
08BB2B47 7406            je      (08BB2B4F = 08BB2B49+00000006)
08BB2B49 57              push    edi    //以下释放 eval() 语句所申请的内存
08BB2B4A e8818ffafa      call    void _stdcall eval_var_free(YHTML *jdt)
08BB2B4F 807d1000        cmp     byte [ebp+10h],0x00         //判断是否用 new 调用了该函数
08BB2B53 740f            je      (08BB2B64 = 08BB2B55+0000000f)
08BB2B55 8b4514          mov     eax,dword [ebp+14h]         //eax = 返回值地址
08BB2B58 803807          cmp     byte [eax],0x07             //判断返回值是否是对象
08BB2B5B 7407            je      (08BB2B64 = 08BB2B5D+00000007)
08BB2B5D 50              push    eax    //eax = 返回值地址
08BB2B5E 57              push    edi    //如果返回值不是对象, 则调用下面函数创建new所需对象
08BB2B5F e8de8dfafa      call    void _stdcall create_this_object(YHTML *jdt,JSVAL *pJval)
08BB2B64 8f472c          pop     dword [edi+2Ch]     //pop  pFunction
08BB2B67 ff4b04          dec     dword [ebx+04h]     //局部堆栈号 -= 1
08BB2B6A 8f4344          pop     dword [ebx+44h]     //pop pFunc->arg_ebp
08BB2B6D 5f              pop     edi
08BB2B6E 5e              pop     esi
08BB2B6F 5b              pop     ebx
08BB2B70 8be5            mov     esp,ebp
08BB2B72 5d              pop     ebp
08BB2B73 c21800          ret     0018
}

注:生成Javascript汇编代码主要由文件ycjit.cpp完成,还有许多优化空间待将来实现。64位版本Javascript转汇编正在测试中。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值