1
  1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
Приветствуем вас,Гость, на форуме IFUD.WS. Обязательно рекомендуется к прочтению правила форума http://ifud.ws/threads/obnovleno-pravila-foruma.7759

[FASM x86] Миниатюрня софтверная стековая виртуальная машина

Тема в разделе "Программирование", создана пользователем 0xDADA11C7, 6 янв 2015.

  1. TopicStarter Overlay
    0xDADA11C7

    0xDADA11C7

    Регистрация:
    5 янв 2015
    Сообщения:
    8
    Симпатии:
    23
    Эта ВМ использовалась в пакере, поэтому она имеет некоторые особенности. Должен заметить, что когда я говорю про виртуальную машину, то имею в виду семью подобных виртуальных машин, потому что для каждой потребности генерируеться своя виртуальная машина. Приведенная ниже ВМ официально утверждена "иридиевым" образцом в вакууме для использования в примерах.

    Описание архитектуры виртуальной машины
    • Два 32-розрядных стека - данных и возвратов.
    • Собственное адресное пространство отсуствует, тоесть используется адресное пространство "хоста" (в данном случае x86 IA-32).
    • Формат хранение целых чисел интеливский (little-endian)
    • Доступ к памяти возможен байтами (Byte), словами (2 байти - Word) и двойными словами (4 байта - DWord)
    • размер колибается в границах 700-750 байт
    • номера функций, опкоды команд и расположение полей в структуре каждой ВМ свои
    • выполнено в виде шеллкода
    Исходный код виртуальной машины
    Файл заголовков picovm.inc
    Код:
    struct PICOVM_CONTEXT
    _dstack_size            db ?
    _instruction_pointer    dd ?
    _dstack_begin           dd ?
    _rstack_size            db ?
    _rstack_begin           dd ?
    _rstack_top             dd ?
    _dstack_top             dd ?
    ends
    macro PICOVM_CTX ip, dssz, rssz, rstop, dstop, rsb, dsb {  PICOVM_CONTEXT dssz, ip, dsb, rssz, rsb, rstop, dstop }
    
    PICOVM_FNC_STEP = 0
    PICOVM_FNC_DSPOP = 1
    PICOVM_FNC_RUN = 2
    PICOVM_FNC_RSPOP = 3
    PICOVM_FNC_DSPUSH = 4
    PICOVM_FNC_RSPUSH = 5
    PICOVM_FNC_DEPTH = 6
    
    PICOVM_ADD_OPCODE equ 0x0
    PICOVM_PICK_OPCODE equ 0x1
    PICOVM_NOT_OPCODE equ 0x2
    PICOVM_STOREW_OPCODE equ 0x3
    PICOVM_LOADCW_OPCODE equ 0x4
    PICOVM_AND_OPCODE equ 0x5
    PICOVM_OVER_OPCODE equ 0x6
    PICOVM_DUP_OPCODE equ 0x7
    PICOVM_LOADCB_OPCODE equ 0x8
    PICOVM_XOR_OPCODE equ 0x9
    PICOVM_ROLL_OPCODE equ 0xA
    PICOVM_CALLN_OPCODE equ 0xB
    PICOVM_LOADCD_OPCODE equ 0xC
    PICOVM_CALLA_OPCODE equ 0xD
    PICOVM_JMPR_OPCODE equ 0xE
    PICOVM_SHR_OPCODE equ 0xF
    PICOVM_BELOW_OPCODE equ 0x10
    PICOVM_SHL_OPCODE equ 0x11
    PICOVM_FETCHD_OPCODE equ 0x12
    PICOVM_SUB_OPCODE equ 0x13
    PICOVM_ROT_OPCODE equ 0x14
    PICOVM_RET_OPCODE equ 0x15
    PICOVM_STORED_OPCODE equ 0x16
    PICOVM_DROP_OPCODE equ 0x17
    PICOVM_OR_OPCODE equ 0x18
    PICOVM_ROR_OPCODE equ 0x19
    PICOVM_EQ_OPCODE equ 0x1A
    PICOVM_ROL_OPCODE equ 0x1B
    PICOVM_ABOVE_OPCODE equ 0x1C
    PICOVM_SWAP_OPCODE equ 0x1D
    PICOVM_CALLR_OPCODE equ 0x1E
    PICOVM_FETCHW_OPCODE equ 0x1F
    PICOVM_MOD_OPCODE equ 0x20
    PICOVM_STOREB_OPCODE equ 0x21
    PICOVM_JMPC_OPCODE equ 0x22
    PICOVM_DIV_OPCODE equ 0x23
    PICOVM_MUL_OPCODE equ 0x24
    PICOVM_FETCHB_OPCODE equ 0x25
    PICOVM_JMPA_OPCODE equ 0x26
    PICOVM_HLT_OPCODE equ 0xFF
    
    PICOVM_ERR_NONE          equ  0
    PICOVM_ERR_DSOVERFLOW    equ -1
    PICOVM_ERR_DSUNDERFLOW   equ -2
    PICOVM_ERR_RSOVERFLOW    equ -4
    PICOVM_ERR_RSUNDERFLOW   equ -5
    PICOVM_ERR_UNKNOWNFNC    equ -6
    PICOVM_ERR_UNKNOWNCMD    equ -7
    
    macro PICOVM_CMD cmd, n {
      if cmd eq _LOADCW
        db PICOVM##cmd##_OPCODE
        dw n and 0xffff
      else if cmd eq _LOADCD
        db PICOVM##cmd##_OPCODE
        dd n and 0xffffffff
      else if cmd eq _LOADCB
        db PICOVM##cmd##_OPCODE
        db n and 0xff
      else
        db PICOVM##cmd##_OPCODE
      end if
    }
    
    macro PICOVM_COMMAND_ENTRY link, sz, dsinp, dsoutp {
      dw ((link-__COMMANDS_BEGIN__) shl 0x6) + (sz and 0x7) + ((dsinp and 0x3) shl 0x3) + ((dsoutp and 0x1) shl 0x5)
    }
    
    Главный файл picovm.asm
    Код:
    format binary 
    use32
    org 0x0
    
    include '%FASMINC%\WIN32A.INC'
    include 'picovm.inc'
    
    __VM_BEGIN__:
        pusha
        call    .delta
    .delta:
        sub     DWord [esp], __VM_BEGIN__.delta - __VM_BEGIN__
        pop     ebp
        cmp     eax, 0x6
        ja     .err
        call    .fnc
    
      db  __STEP__
      db  __DSPOP__
      db  __RUN__
      db  __RSPOP__
      db  __DSPUSH__
      db  __RSPUSH__
      db  __DEPTH__
    
    .fnc:
        pop     ecx
        movzx   ecx, Byte [ecx+eax]
        add     ecx, ebp
        call    ecx
        jmp     short _save_eax_edx_stack_up
    .err:
        mov     edx, PICOVM_ERR_UNKNOWNFNC
        jmp     short __RSPUSH__.err
    
    __RSPUSH__:
        pusha
        mov     esi, edx
        call    __DEPTH__
        movzx   ecx, [ebx+PICOVM_CONTEXT._rstack_size]
        cmp     edx, ecx
        jb      .ok
        mov     edx, PICOVM_ERR_RSOVERFLOW
    .err:
        stc
    .up:
        mov     eax, edx
        jmp     short _save_eax_edx_stack_up
    .ok: 
        mov     ecx, [ebx+PICOVM_CONTEXT._rstack_top]
        mov     [ecx], esi
        add     [ebx+PICOVM_CONTEXT._rstack_top], 0x4
        xor     edx, edx
        clc
        jmp     short .up
    
    __RSPOP__:
        pusha
        call    __DEPTH__
        test    edx, edx
        jnz     .ok
        mov     edx, PICOVM_ERR_RSUNDERFLOW
        jmp     short __RSPUSH__.err
    .ok: 
        mov     ecx, [ebx+PICOVM_CONTEXT._rstack_top]
        mov     eax, [ecx-0x4]
        sub     [ebx+PICOVM_CONTEXT._rstack_top], 0x4
        xor     edx, edx
        clc
    _save_eax_edx_stack_up:
        jmp     short _save_eax_edx_stack
    
    __DSPOP__:
        xor     edx, edx
        xor     eax, eax
        inc     eax
        call    __DSCheckInpOutp__
        jc      .err
        mov     ecx, [ebx+PICOVM_CONTEXT._dstack_top]
        mov     eax, [ecx-0x4]
        sub     [ebx+PICOVM_CONTEXT._dstack_top], 0x4
        clc
        ret
    .err:
        xchg    edx, eax
        xor     eax, eax
        stc
        ret
    
    __RUN__:
        test    edx, edx
        jz      .up
        mov     [ebx+PICOVM_CONTEXT._instruction_pointer], edx
    .up:
        mov     edx, [ebx+PICOVM_CONTEXT._instruction_pointer]
        cmp     Byte [edx], PICOVM_HLT_OPCODE
        jz      .ok
        call    __STEP__
    ;    pushf
    ;    pusha
    ;    call    __DEPTH__
    ;    popa
    ;    popf
        jnc     .up
        ret
    .ok:      
        xchg    edx, eax
        xor     eax, eax
        ret
    
    __DSPUSH__:
        xor     eax, eax
        inc     ah
        call    __DSCheckInpOutp__
        jnc     .ok
        mov     eax, edx
        ret
    .ok:
        mov     ecx, [ebx+PICOVM_CONTEXT._dstack_top]
        mov     DWord [ecx], edx
        add     [ebx+PICOVM_CONTEXT._dstack_top], 0x4
        xor     edx, edx
        ret
    
    __DEPTH__:
        pusha
        mov     eax, [ebx+PICOVM_CONTEXT._dstack_top]
        mov     edx, [ebx+PICOVM_CONTEXT._rstack_top]
        sub     eax, [ebx+PICOVM_CONTEXT._dstack_begin]
        shr     eax, 0x2
        sub     edx, [ebx+PICOVM_CONTEXT._rstack_begin]
        shr     edx, 0x2
        clc
    _save_eax_edx_stack:
        mov     DWord [esp+0x14], edx
    _save_eax_stack:
        mov     DWord [esp+0x1C], eax
        popa
        ret
    
    __STEP__:
        pusha
        xor     eax, eax
        push    eax
        mov     esi, [ebx+PICOVM_CONTEXT._instruction_pointer]
        lea     edi, [ebp+cmdsTable]
        movzx   ecx, Byte [esi]
        mov     eax, ecx
        shl     eax, 0x1
        add     edi, eax
        push    edi
        movzx   eax, Byte [edi]
        and     al,  0x3F
        shl     eax, 0x3
        shr     al,  0x6
        call    __DSCheckInpOutp__
        jc      .err
        movzx   eax, Word [edi]
        shr     eax, 0x6
        add     eax, ebp
        add     eax, __COMMANDS_BEGIN__
        push    ebp
        add     DWord [esp], __STEP__.return
        push    eax
        mov     edi, [ebx+PICOVM_CONTEXT._dstack_top]
        mov     edx, DWord [edi-0x8]
        mov     eax, DWord [edi-0x4]
        ret
    .return:
        pop     edx
        mov     eax, DWord [esp]
        test    eax, eax
        jnz     short .err
        mov     ebx, DWord [esp+0x14]
        movzx   edx, Byte [edx]
        and     edx, 0x7
        jz      short .end
        mov     esi, [ebx+PICOVM_CONTEXT._instruction_pointer]
        add     esi, edx
        xor     edx, edx
        jmp     short .end
    .err:
        xchg    edx, eax
        xchg    eax, esi
        stc
    .end:
        mov     eax, esi
        pop     ecx
        mov     [ebx+PICOVM_CONTEXT._dstack_top], edi
        mov     [ebx+PICOVM_CONTEXT._instruction_pointer], esi
    _save_eax_edx_stack_down:
        jmp     short _save_eax_edx_stack
    
    __DSCheckInpOutp__:
        pusha
        xor     edi, edi
        mov     edx, eax
        shr     edx, 0x8
        xchg    esi, eax
        and     esi, 0xff
        call    __DEPTH__
        cmp     eax, esi
        jnl     .outp
        dec     edi
        jmp     short .err
    .outp:
        movzx   esi, Byte [ebx+PICOVM_CONTEXT._dstack_size]
        sub     esi, eax
        cmp     esi, edx
        jnl     .ok
        dec     edi
        dec     edi
    .err:
        stc
        jmp     short .end
    .ok:
        clc
    .end:
        xchg    edi, eax
        jmp     _save_eax_stack
    __COMMANDS_BEGIN__:
    
    _calln_:
        call    eax
        ret
    
    ;_mrtd_:
    ;    call    _crtd_
    ;    sub     [ebx + PICOVM_CONTEXT._rstack_top], 0x4
    ;    ret
    
    _stored_:
        mov     [eax], edx
    _drop2:
        sub     edi, 0x8
        ret
    
    _storew_:
        mov     Word [eax], dx
        jmp     short _drop2
    
    _storeb_:
        mov     Byte [eax], dl
        jmp     short _drop2
    
    _jmpa_:
        mov     esi, eax
        jmp     short _drop_
    
    _jmpr_:
        add     esi, eax
        jmp     short _drop_
    
    _jmpc_:
        test    edx, edx
        jnz     short _jmpc_not
        add     esi, eax
        jmp     short _drop2
    
    _jmpc_not:
        inc     esi
        jmp     short _drop2
    
    _over_:
        xchg    ecx, edx
    ;    jmp     short _save_ecx_up1
    
    ;_depthr_:
    ;    call    __DEPTH__
    ;    xchg    edx, eax
    ;    jmp     short _save_ecx_up1
    
    ;_depthd_:
    ;    call    __DEPTH__
    ;    xchg    ecx, eax
    _save_ecx_up1:
        mov     [edi], ecx
        add     edi, 0x4
        ret
    
    _loadcb_:
        movzx   ecx, Byte [esi+0x1]
        jmp     short _save_ecx_up1
    _loadcw_:
        movzx   ecx, Word [esi+0x1]
        jmp     short _save_ecx_up1
    _loadcd_:
        mov     ecx, [esi+0x1]
        jmp     short _save_ecx_up1
    
    _dup_:
        xchg    ecx, eax
        jmp     short _save_ecx_up1
    
    _drop_:
    
        sub    edi, 0x4
        ret
    
    ;_mdtr_:
    ;    call    _cdtr_
    ;    jmp     short _drop_
    
    _calla_:
        mov     ecx, eax
        mov     edx, esi
        inc     edx
        call    __RSPUSH__
        jc      _err_edx
        mov     esi, ecx
        jmp     short _drop_
    
    _callr_:
        mov     ecx, eax
        mov     edx, esi
        inc     edx
        call    __RSPUSH__
        jc      _err_edx
        add     esi, ecx
        jmp     short _drop_
    
    _mod_:
        mov     ecx, eax
        xchg    eax, edx
        xor     edx, edx
        div     ecx
    _save_edx_down1:
        mov     [edi-0x8], edx
        jmp     short _drop_
    
    _above_:
        xor     ecx, ecx
        cmp     eax, edx
        ja      short _save_ecx_down1
        dec     ecx
    _save_ecx_down1:
        mov     [edi-0x8], ecx
        jmp     short _drop_
    
    _below_:
        xor     ecx, ecx
        cmp     eax, edx
        jb      short _save_ecx_down1
        dec     ecx
        jmp     short _save_ecx_down1
    
    _add_:
        add     eax, edx
        jmp     short _save_eax_down1
    
    _sub_:
        sub     edx, eax
        jmp     short _save_edx_down1
    
    _mul_:
        mul     edx
        jmp     short _save_eax_down1
    
    _xor_:
        xor     eax, edx
        jmp     short _save_eax_down1
    
    _shr_:
        xchg    eax, edx
        xchg    ecx, edx
        shr     eax, cl
        jmp     short _save_eax_down1
    
    _ror_:
        xchg    eax, edx
        xchg    ecx, edx
        ror     eax, cl
        jmp     short _save_eax_down1
    
    _shl_:
        xchg    eax, edx
        xchg    ecx, edx
        shl     eax, cl
        jmp     short _save_eax_down1
    
    _eq_:
        xor     ecx, ecx
        cmp     eax, edx
        jnz     _save_ecx_down1
        dec     ecx
        jmp     short _save_ecx_down1
    
    ;_sar_:
    ;    xchg    eax, ecx
    ;    sar     edx, cl
    ;    xchg    edx, eax
    ;    jmp     short _save_eax_down1
    
    _not_:
        not     eax
        jmp     short _save_eax
    
    _rot_:
        mov     ecx, [edi-0xC]
        mov     [edi-0xC], edx
        mov     [edi-0x8], eax
    _save_ecx_d:
        mov     [edi-0x4], ecx
        ret
    
    ;_sal_:
    ;    xchg    eax, ecx
    ;    sal     edx, cl
    ;    xchg    edx, eax
    ;    jmp     short _save_eax_down1
    
    ;_neg_:
    ;    neg     eax
    ;    jmp     short _save_eax
    
    _div_:
        mov     ecx, eax
        xchg    eax, edx
        xor     edx, edx
        div     ecx
    _save_eax_down1:
        mov     [edi-0x8], eax
        jmp     _drop_
    
    _rol_:
        xchg    eax, edx
        xchg    ecx, edx
        rol     eax, cl
        jmp     short _save_eax_down1
    
    _and_:
        and     eax, edx
        jmp     short _save_eax_down1
    
    _or_:
        or      eax, edx
        jmp     short _save_eax_down1
    
    _swap_:
        xchg    eax, edx
    _save_eax_edx:
        mov     [edi-0x8], edx
    _save_eax:
        xchg    ecx, eax
        jmp     short _save_ecx
    _fetchb_:
        movzx   eax, Byte [eax]
        jmp     short _save_eax
    
    _fetchw_:
        movzx   eax, Word [eax]
        jmp     short _save_eax
    _fetchd_:
        mov     eax, [eax]
        jmp     short _save_eax
    
    ;_esb_:
    ;    cbw
    ;_esw_:
    ;    cwde
    ;    jmp     short _save_eax
    
    _save_ecx:
        mov     [edi-0x4], ecx
        ret
    
    _pick_:
        inc     eax
        inc     eax
        mov     edx, eax
        call    __DSCheckInpOutp__
        jc      _err_
        shl     edx, 0x2
        mov     eax, edi
        sub     eax, edx
        push    DWord [eax]
        pop     DWord [edi-0x4]
        ret
    
    _roll_:
        mov     edx, eax
        inc     eax
        inc     eax
        call    __DSCheckInpOutp__
        jc      _err_
        pusha
        mov     ecx, edx
        xchg    esi, edi
        mov     ebx, ecx
        inc     ebx
        shl     ebx, 0x2
        sub     esi, ebx
        lea     edi, [esi-0x4]
        push    DWord [edi]
        cld
        rep     movsd
        pop     DWord [edi]
        popa
        sub     edi, 0x4
        ret
    
    _drop_d:
        sub     edi, 0x4
        ret
    
    _ret_:
        call    __RSPOP__
        jc      _err_edx
        mov     esi, eax
        ret
    
    ;_cdtr_:
    ;    mov     edx, eax
    ;    call    __RSPUSH__
    ;    jc      short _err_edx
    ;    ret
    
    ;_crtd_:
    ;    mov    edx, [ebx + PICOVM_CONTEXT._rstack_top]
    ;    mov    eax, [ebx + PICOVM_CONTEXT._rstack_begin]
    ;    cmp    edx, eax
    ;    jbe    .err
    ;    mov    ecx, [edx-0x4]
    ;    jmp    _save_ecx_up1
    ;.err:
    ;    mov    eax, PICOVM_ERR_RSUNDERFLOW
    ;    jmp    _err_
    _err_edx:
        xchg   eax, edx
    _err_:
        mov     [esp+0x8], eax
        ret
    
    
    cmdsTable:
     PICOVM_COMMAND_ENTRY _add_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _pick_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _not_, 0x1, 0x1, 0x0
     PICOVM_COMMAND_ENTRY _storew_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _loadcw_, 0x3, 0x0, 0x1
     PICOVM_COMMAND_ENTRY _and_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _over_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _dup_, 0x1, 0x1, 0x1
     PICOVM_COMMAND_ENTRY _loadcb_, 0x2, 0x0, 0x1
     PICOVM_COMMAND_ENTRY _xor_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _roll_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _calln_, 0x0, 0x1, 0x0
     PICOVM_COMMAND_ENTRY _loadcd_, 0x5, 0x0, 0x1
     PICOVM_COMMAND_ENTRY _calla_, 0x0, 0x1, 0x0
     PICOVM_COMMAND_ENTRY _jmpr_, 0x0, 0x1, 0x0
     PICOVM_COMMAND_ENTRY _shr_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _below_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _shl_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _fetchd_, 0x1, 0x1, 0x0
     PICOVM_COMMAND_ENTRY _sub_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _rot_, 0x1, 0x3, 0x0
     PICOVM_COMMAND_ENTRY _ret_, 0x0, 0x0, 0x0
     PICOVM_COMMAND_ENTRY _stored_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _drop_, 0x1, 0x1, 0x0
     PICOVM_COMMAND_ENTRY _or_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _ror_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _eq_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _rol_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _above_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _swap_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _callr_, 0x0, 0x1, 0x0
     PICOVM_COMMAND_ENTRY _fetchw_, 0x1, 0x1, 0x0
     PICOVM_COMMAND_ENTRY _mod_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _storeb_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _jmpc_, 0x0, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _div_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _mul_, 0x1, 0x2, 0x0
     PICOVM_COMMAND_ENTRY _fetchb_, 0x1, 0x1, 0x0
     PICOVM_COMMAND_ENTRY _jmpa_, 0x0, 0x1, 0x0
    
    Характеристики виртуальной машины сохраняються в JSON формате в файле picovm.settings.json
    Код:
    {"date":null,"cmds":["add","pick","not","storew","loadcw","and","over","dup","loadcb","xor","roll","calln","loadcd","calla","jmpr","shr","below","shl","fetchd","sub","rot","ret","stored","drop","or","ror","eq","rol","above","swap","callr","fetchw","mod","storeb","jmpc","div","mul","fetchb","jmpa"],"consts":["STEP","DSPOP","RUN","RSPOP","DSPUSH","RSPUSH","DEPTH"]}
    Примеры использования

    Для сокращения исходного кода я использую следующий макрос
    Код:
    macro @ cmd, p {
     PICOVM_CMD cmd, p
    }
    
    Функция роскодирования BASE85 с пользовательским алфавитом:
    Код:
    ; BASE85
    ;[pAlphabet, pSrc, pDst, Size]
    BASE85:
    @ _DUP
    @ _LOADCW, 0x0
    @ _EQ
    @ _NOT
    @ _LOADCD, .Down-.toDown
    .toDown:
    @ _JMPC
    @ _LOADCB, 0x5
    @ _SUB
    @ _ROT
    ;[pAlphabet, pDst, Size, pSrc]
    @ _LOADCW, 0x3
    @ _PICK
    ;[pAlphabet, pDst, Size, pSrc, pAlphabet]
    @ _SWAP
    ;[pAlphabet, pDst, Size, pAlphabet, pSrc]
    @ _LOADCD, DECODE_DWORD-.toDecodeDWord
    .toDecodeDWord:
    @ _CALLR
    ;[pAlphabet, pDst, Size, pSrc, DW]
    @ _LOADCW, 0x3
    @ _PICK
    ;[pAlphabet, pDst, Size, pSrc, DW, pDst]
    @ _STORED
    ;[pAlphabet, pDst, Size, pSrc]
    @ _ROT
    ;[pAlphabet, Size, pSrc, pDst]
    @ _LOADCD, 0x4
    @ _ADD
    @ _ROT
    ;[pAlphabet, pSrc, pDst, Size]
    @ _LOADCD, BASE85-.toUp
    .toUp:
    @ _JMPR
    .Down:
    @ _DROP
    @ _DROP
    @ _DROP
    @ _DROP
    @ _RET
    
    ;[pAlphabet, pSrc] => [pSrc, DW]
    DECODE_DWORD:
    @ _LOADCB, 0
    @ _OVER
    @ _FETCHB
    ;[pAlphabet, pSrc, 0, [pSrc]]
    @ _LOADCW, 0x3
    @ _PICK
    @ _SWAP
    ;[pAlphabet, pSrc, 0, Alphabet, [pSrc]]
    @ _LOADCD, SEARCHB -.toSearchB1
    .toSearchB1:
    @ _CALLR
    @ _ADD
    @ _SWAP
    @ _LOADCW, 0x1
    @ _ADD
    @ _SWAP
    @ _OVER
    @ _FETCHB
    @ _LOADCD, 0x3
    @ _PICK
    @ _SWAP
    @ _LOADCD, SEARCHB -.toSearchB2
    .toSearchB2:
    @ _CALLR
    @ _LOADCB, 0x55
    @ _MUL
    @ _ADD
    @ _SWAP
    @ _LOADCB, 0x1
    @ _ADD
    @ _SWAP
    @ _OVER
    @ _FETCHB
    @ _LOADCD, 0x3
    @ _PICK
    @ _SWAP
    @ _LOADCD, SEARCHB -.toSearchB3
    .toSearchB3:
    @ _CALLR
    @ _LOADCW, 85*85
    @ _MUL
    @ _ADD
    @ _SWAP
    @ _LOADCB, 0x1
    @ _ADD
    @ _SWAP
    @ _OVER
    @ _FETCHB
    @ _LOADCD, 0x3
    @ _PICK
    @ _SWAP
    @ _LOADCD, SEARCHB -.toSearchB4
    .toSearchB4:
    @ _CALLR
    @ _LOADCD, 85*85*85
    @ _MUL
    @ _ADD
    @ _SWAP
    @ _LOADCW, 0x1
    @ _ADD
    @ _SWAP
    @ _OVER
    @ _FETCHB
    @ _LOADCW, 0x3
    @ _PICK
    @ _SWAP
    @ _LOADCD, SEARCHB -.toSearchB5
    .toSearchB5:
    @ _CALLR
    @ _LOADCD, 85*85*85*85
    @ _MUL
    @ _ADD
    @ _ROT
    @ _DROP
    @ _SWAP
    @ _LOADCD, 0x1
    @ _ADD
    @ _SWAP
    @ _RET
    
    SEARCHB:
    @ _OVER
    @ _SWAP
    .Up:
    @ _OVER
    @ _FETCHB
    @ _OVER
    ;[pMem, pMem, bVal, [pMem], bVal]
    @ _EQ
    ;[pMem, pMem, bVal, BOOL]
    @ _NOT
    @ _LOADCD, .Down-.toDown
    .toDown:
    @ _JMPC
    @ _SWAP
    @ _LOADCB, 0x1
    @ _ADD
    @ _SWAP
    @ _LOADCD, .Up-.toUp
    .toUp:
    @ _JMPR
    .Down:
    @ _DROP
    @ _SWAP
    @ _SUB
    @ _RET
    
    Криптографическая функция RC4
    Код:
    ; [lpBuf, lpKey, dwBufLen, dwKeyLen, pS]
    RC4:
    @ _LOADCB, 0 ;B
    @ _DUP ;A
    @ _ROT
    @ _SWAP
    .for1_up:
    @ _DUP
    @ _LOADCW, 0x100;
    @ _EQ
    @ _NOT
    @ _LOADCD, .for1_down-.tofor1_down
    .tofor1_down:
    @ _JMPC
    @ _OVER
    @ _OVER
    @ _ADD
    @ _OVER
    @ _SWAP
    @ _STOREB
    @ _LOADCB, 0x1                           
    @ _ADD
    @ _LOADCD, .for1_up-.tofor1_up
    .tofor1_up:
    @ _JMPR
    .for1_down:
    @ _DROP
    @ _LOADCB, 0x0
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0]
    .for2_up:
    @ _DUP
    @ _LOADCW, 0x100
    @ _EQ
    @ _NOT
    @ _LOADCD, .for2_down-.tofor2_down
    .tofor2_down:
    @ _JMPC
    @ _OVER
    @ _OVER
    @ _ADD
    @ _FETCHB
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0, pS[A]]
    @ _LOADCB, 0x3
    @ _PICK
    @ _ADD 
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0, pS[A]+B]
    @ _OVER
    @ _LOADCB, 0x5
    @ _PICK
    @ _MOD
    @ _LOADCB, 0x7
    @ _PICK
    @ _ADD
    @ _FETCHB
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0, pS[A]+B, lpKey [A % dwKeyLen]]
    @ _ADD
    @ _LOADCB, 0xFF
    @ _AND
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0, pS[A]+B+lpKey [A % dwKeyLen]]
    @ _LOADCB, 0x3
    @ _ROLL
    @ _DROP
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, pS, A, B]
    @ _ROT
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, A, B, pS]
    @ _ROT
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A]
    @ _OVER
    @ _OVER
    @ _ADD
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A, pS+A]
    @ _LOADCB, 0x2
    @ _PICK
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A, pS+A, pS]
    @ _LOADCB, 0x4
    @ _PICK
    @ _ADD
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A, pS+A, pS+B]
    @ _OVER
    @ _FETCHB
    @ _OVER
    @ _FETCHB
    @ _SWAP
    @ _ROT
    @ _STOREB
    @ _SWAP
    @ _STOREB
    @ _LOADCB, 0x1
    @ _ADD
    @ _LOADCD, .for2_up-.tofor2_up
    .tofor2_up:
    @ _JMPR
    .for2_down:
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A]
    @ _ROT
    ;[lpBuf, lpKey, dwBufLen, dwKeyLen, pS, A, B]
    @ _LOADCB, 0x3
    @ _ROLL
    @ _DROP
    ;[lpBuf, lpKey, dwBufLen, pS, A, B]
    @ _LOADCB, 0x4
    @ _ROLL
    @ _DROP
    @ _SWAP
    ;[lpBuf, dwBufLen, pS, B, A]
    .for3_up:
    @ _LOADCB, 0x3
    @ _ROLL
    @ _DUP
    ;[lpBuf, pS, B, A, dwBufLen, dwBufLen]
    @ _LOADCD, .for3_down-.tofor3_down
    .tofor3_down:
    @ _JMPC
    @ _LOADCB, 0x1
    @ _SUB
    ;[lpBuf, pS, B, A, dwBufLen]
    @ _SWAP
    @ _LOADCB, 0x1
    @ _ADD
    @ _LOADCB, 0xFF
    @ _AND
    ;[lpBuf, pS, A, dwBufLen, (A+1)%255]
    @ _ROT
    ;[lpBuf, pS, dwBufLen, (A+1)%255, B]
    @ _OVER
    @ _LOADCB, 0x4
    @ _PICK
    @ _ADD
    @ _FETCHB
    @ _ADD
    @ _LOADCB, 0xFF
    @ _AND
    @ _OVER
    @ _OVER
    @ _LOADCB, 0x5
    @ _PICK
    @ _ADD
    @ _SWAP
    @ _LOADCB, 0x5
    @ _PICK
    @ _ADD
    @ _OVER
    @ _OVER
    ;
    @ _OVER
    @ _FETCHB
    @ _OVER
    @ _FETCHB
    @ _SWAP
    @ _ROT
    @ _STOREB
    @ _SWAP
    @ _STOREB
    ;
    @ _FETCHB
    @ _SWAP
    @ _FETCHB
    @ _ADD
    @ _LOADCB, 0xFF
    @ _AND
    @ _LOADCB, 0x4
    @ _PICK
    @ _ADD
    @ _FETCHB
    @ _LOADCB, 0x5
    @ _PICK
    @ _FETCHB
    @ _XOR
    @ _LOADCB, 0x5
    @ _PICK
    @ _STOREB
    @ _LOADCB, 0x4
    @ _ROLL
    @ _LOADCB, 0x1
    @ _ADD
    @ _ROT
    @ _ROT
    @ _LOADCB, 0x4
    @ _ROLL
    @ _LOADCB, 0x4
    @ _ROLL
    @ _LOADCB, 0x3
    @ _ROLL
    @ _LOADCB, 0x3
    @ _ROLL
    @ _LOADCB, 0x3
    @ _ROLL
    @ _ROT
    @ _ROT
    @ _SWAP
    @ _LOADCD, .for3_up-.tofor3_up
    .tofor3_up:
    @ _JMPR
    .for3_down:
    @ _DROP
    @ _DROP
    @ _DROP
    @ _DROP
    @ _DROP
    @ _RET
    
    Как сказано выше, каждая виртуальная машина создаеться генератором і являеться уникальной.

    Исходный код генератора виртуальных машин на JavaScript
    picovm.js
    Код:
    var _ = require ('underscore');
    var fs = require ('fs');
    
    Number.prototype.toHex = function() {
        return('0x'+this.toString(16).toUpperCase());};
    
    var fncs = ['RUN', 'STEP', 'DEPTH', 'RSPOP', 'RSPUSH', 'DSPOP', 'DSPUSH'];
    var cmds_array = [];
    var picovm_inc_end = '\
    PICOVM_ERR_NONE          equ  0\n\
    PICOVM_ERR_DSOVERFLOW    equ -1\n\
    PICOVM_ERR_DSUNDERFLOW   equ -2\n\
    PICOVM_ERR_RSOVERFLOW    equ -4\n\
    PICOVM_ERR_RSUNDERFLOW   equ -5\n\
    PICOVM_ERR_UNKNOWNFNC    equ -6\n\
    PICOVM_ERR_UNKNOWNCMD    equ -7\n\n\
    macro PICOVM_CMD cmd, n {\n\
      if cmd eq _LOADCW\n\
        db PICOVM##cmd##_OPCODE\n\
        dw n and 0xffff\n\
      else if cmd eq _LOADCD\n\
        db PICOVM##cmd##_OPCODE\n\
        dd n and 0xffffffff\n\
      else if cmd eq _LOADCB\n\
        db PICOVM##cmd##_OPCODE\n\
        db n and 0xff\n\
      else\n\
        db PICOVM##cmd##_OPCODE\n\
      end if\n\
    }\n\n\
    macro PICOVM_COMMAND_ENTRY link, sz, dsinp, dsoutp {\n\
      dw ((link-__COMMANDS_BEGIN__) shl 0x6) + (sz and 0x7) + ((dsinp and 0x3) shl 0x3) + ((dsoutp and 0x1) shl 0x5)\n\
    }\n\n';
    
    var picovm_asm_begin = 'format binary\n\
    use32\n\
    org 0x0\n\n\
    include \'%FASMINC%\\WIN32A.INC\'\n\
    include \'picovm.inc\'\n\n\
    __VM_BEGIN__:\n\
        pusha\n\
        call    .delta\n\
    .delta:\n\
        sub     DWord [esp], __VM_BEGIN__.delta - __VM_BEGIN__\n\
        pop     ebp\n\
        cmp     eax, 0x6\n\
        ja     .err\n\
        call    .fnc\n';
    
    var picovm_asm_body = '.fnc:\n\
        pop     ecx\n\
        movzx   ecx, Byte [ecx+eax]\n\
        add     ecx, ebp\n\
        call    ecx\n\
        jmp     short _save_eax_edx_stack_up\n\
    .err:\n\
        mov     edx, PICOVM_ERR_UNKNOWNFNC\n\
        jmp     short __RSPUSH__.err\n\n\
    __RSPUSH__:\n\
        pusha\n\
        mov     esi, edx\n\
        call    __DEPTH__\n\
        movzx   ecx, [ebx+PICOVM_CONTEXT._rstack_size]\n\
        cmp     edx, ecx\n\
        jb      .ok\n\
        mov     edx, PICOVM_ERR_RSOVERFLOW\n\
    .err:\n\
        stc\n\
    .up:\n\
        mov     eax, edx\n\
        jmp     short _save_eax_edx_stack_up\n\
    .ok: \n\
        mov     ecx, [ebx+PICOVM_CONTEXT._rstack_top]\n\
        mov     [ecx], esi\n\
        add     [ebx+PICOVM_CONTEXT._rstack_top], 0x4\n\
        xor     edx, edx\n\
        clc\n\
        jmp     short .up\n\n\
    __RSPOP__:\n\
        pusha\n\
        call    __DEPTH__\n\
        test    edx, edx\n\
        jnz     .ok\n\
        mov     edx, PICOVM_ERR_RSUNDERFLOW\n\
        jmp     short __RSPUSH__.err\n\
    .ok: \n\
        mov     ecx, [ebx+PICOVM_CONTEXT._rstack_top]\n\
        mov     eax, [ecx-0x4]\n\
        sub     [ebx+PICOVM_CONTEXT._rstack_top], 0x4\n\
        xor     edx, edx\n\
        clc\n\
    _save_eax_edx_stack_up:\n\
        jmp     short _save_eax_edx_stack\n\n\
    __DSPOP__:\n\
        xor     edx, edx\n\
        xor     eax, eax\n\
        inc     eax\n\
        call    __DSCheckInpOutp__\n\
        jc      .err\n\
        mov     ecx, [ebx+PICOVM_CONTEXT._dstack_top]\n\
        mov     eax, [ecx-0x4]\n\
        sub     [ebx+PICOVM_CONTEXT._dstack_top], 0x4\n\
        clc\n\
        ret\n\
    .err:\n\
        xchg    edx, eax\n\
        xor     eax, eax\n\
        stc\n\
        ret\n\n\
    __RUN__:\n\
        test    edx, edx\n\
        jz      .up\n\
        mov     [ebx+PICOVM_CONTEXT._instruction_pointer], edx\n\
    .up:\n\
        mov     edx, [ebx+PICOVM_CONTEXT._instruction_pointer]\n\
        cmp     Byte [edx], PICOVM_HLT_OPCODE\n\
        jz      .ok\n\
        call    __STEP__\n\
    ;    pushf\n\
    ;    pusha\n\
    ;    call    __DEPTH__\n\
    ;    popa\n\
    ;    popf\n\
        jnc     .up\n\
        ret\n\
    .ok:      \n\
        xchg    edx, eax\n\
        xor     eax, eax\n\
        ret\n\n\
    __DSPUSH__:\n\
        xor     eax, eax\n\
        inc     ah\n\
        call    __DSCheckInpOutp__\n\
        jnc     .ok\n\
        mov     eax, edx\n\
        ret\n\
    .ok:\n\
        mov     ecx, [ebx+PICOVM_CONTEXT._dstack_top]\n\
        mov     DWord [ecx], edx\n\
        add     [ebx+PICOVM_CONTEXT._dstack_top], 0x4\n\
        xor     edx, edx\n\
        ret\n\n\
    __DEPTH__:\n\
        pusha\n\
        mov     eax, [ebx+PICOVM_CONTEXT._dstack_top]\n\
        mov     edx, [ebx+PICOVM_CONTEXT._rstack_top]\n\
        sub     eax, [ebx+PICOVM_CONTEXT._dstack_begin]\n\
        shr     eax, 0x2\n\
        sub     edx, [ebx+PICOVM_CONTEXT._rstack_begin]\n\
        shr     edx, 0x2\n\
        clc\n\
    _save_eax_edx_stack:\n\
        mov     DWord [esp+0x14], edx\n\
    _save_eax_stack:\n\
        mov     DWord [esp+0x1C], eax\n\
        popa\n\
        ret\n\n\
    __STEP__:\n\
        pusha\n\
        xor     eax, eax\n\
        push    eax\n\
        mov     esi, [ebx+PICOVM_CONTEXT._instruction_pointer]\n\
        lea     edi, [ebp+cmdsTable]\n\
        movzx   ecx, Byte [esi]\n\
        mov     eax, ecx\n\
        shl     eax, 0x1\n\
        add     edi, eax\n\
        push    edi\n\
        movzx   eax, Byte [edi]\n\
        and     al,  0x3F\n\
        shl     eax, 0x3\n\
        shr     al,  0x6\n\
        call    __DSCheckInpOutp__\n\
        jc      .err\n\
        movzx   eax, Word [edi]\n\
        shr     eax, 0x6\n\
        add     eax, ebp\n\
        add     eax, __COMMANDS_BEGIN__\n\
        push    ebp\n\
        add     DWord [esp], __STEP__.return\n\
        push    eax\n\
        mov     edi, [ebx+PICOVM_CONTEXT._dstack_top]\n\
        mov     edx, DWord [edi-0x8]\n\
        mov     eax, DWord [edi-0x4]\n\
        ret\n\
    .return:\n\
        pop     edx\n\
        mov     eax, DWord [esp]\n\
        test    eax, eax\n\
        jnz     short .err\n\
        mov     ebx, DWord [esp+0x14]\n\
        movzx   edx, Byte [edx]\n\
        and     edx, 0x7\n\
        jz      short .end\n\
        mov     esi, [ebx+PICOVM_CONTEXT._instruction_pointer]\n\
        add     esi, edx\n\
        xor     edx, edx\n\
        jmp     short .end\n\
    .err:\n\
        xchg    edx, eax\n\
        xchg    eax, esi\n\
        stc\n\
    .end:\n\
        mov     eax, esi\n\
        pop     ecx\n\
        mov     [ebx+PICOVM_CONTEXT._dstack_top], edi\n\
        mov     [ebx+PICOVM_CONTEXT._instruction_pointer], esi\n\
    _save_eax_edx_stack_down:\n\
        jmp     short _save_eax_edx_stack\n\n\
    __DSCheckInpOutp__:\n\
        pusha\n\
        xor     edi, edi\n\
        mov     edx, eax\n\
        shr     edx, 0x8\n\
        xchg    esi, eax\n\
        and     esi, 0xff\n\
        call    __DEPTH__\n\
        cmp     eax, esi\n\
        jnl     .outp\n\
        dec     edi\n\
        jmp     short .err\n\
    .outp:\n\
        movzx   esi, Byte [ebx+PICOVM_CONTEXT._dstack_size]\n\
        sub     esi, eax\n\
        cmp     esi, edx\n\
        jnl     .ok\n\
        dec     edi\n\
        dec     edi\n\
    .err:\n\
        stc\n\
        jmp     short .end\n\
    .ok:\n\
        clc\n\
    .end:\n\
        xchg    edi, eax\n\
        jmp     _save_eax_stack\n\
    __COMMANDS_BEGIN__:\n\n\
    _calln_:\n\
        call    eax\n\
        ret\n\n\
    ;_mrtd_:\n\
    ;    call    _crtd_\n\
    ;    sub     [ebx + PICOVM_CONTEXT._rstack_top], 0x4\n\
    ;    ret\n\n\
    _stored_:\n\
        mov     [eax], edx\n\
    _drop2:\n\
        sub     edi, 0x8\n\
        ret\n\n\
    _storew_:\n\
        mov     Word [eax], dx\n\
        jmp     short _drop2\n\n\
    _storeb_:\n\
        mov     Byte [eax], dl\n\
        jmp     short _drop2\n\n\
    _jmpa_:\n\
        mov     esi, eax\n\
        jmp     short _drop_\n\n\
    _jmpr_:\n\
        add     esi, eax\n\
        jmp     short _drop_\n\n\
    _jmpc_:\n\
        test    edx, edx\n\
        jnz     short _jmpc_not\n\
        add     esi, eax\n\
        jmp     short _drop2\n\n\
    _jmpc_not:\n\
        inc     esi\n\
        jmp     short _drop2\n\n\
    _over_:\n\
        xchg    ecx, edx\n\
    ;    jmp     short _save_ecx_up1\n\n\
    ;_depthr_:\n\
    ;    call    __DEPTH__\n\
    ;    xchg    edx, eax\n\
    ;    jmp     short _save_ecx_up1\n\n\
    ;_depthd_:\n\
    ;    call    __DEPTH__\n\
    ;    xchg    ecx, eax\n\
    _save_ecx_up1:\n\
        mov     [edi], ecx\n\
        add     edi, 0x4\n\
        ret\n\n\
    _loadcb_:\n\
        movzx   ecx, Byte [esi+0x1]\n\
        jmp     short _save_ecx_up1\n\
    _loadcw_:\n\
        movzx   ecx, Word [esi+0x1]\n\
        jmp     short _save_ecx_up1\n\
    _loadcd_:\n\
        mov     ecx, [esi+0x1]\n\
        jmp     short _save_ecx_up1\n\n\
    _dup_:\n\
        xchg    ecx, eax\n\
        jmp     short _save_ecx_up1\n\n\
    _drop_:\n\n\
        sub    edi, 0x4\n\
        ret\n\n\
    ;_mdtr_:\n\
    ;    call    _cdtr_\n\
    ;    jmp     short _drop_\n\n\
    _calla_:\n\
        mov     ecx, eax\n\
        mov     edx, esi\n\
        inc     edx\n\
        call    __RSPUSH__\n\
        jc      _err_edx\n\
        mov     esi, ecx\n\
        jmp     short _drop_\n\n\
    _callr_:\n\
        mov     ecx, eax\n\
        mov     edx, esi\n\
        inc     edx\n\
        call    __RSPUSH__\n\
        jc      _err_edx\n\
        add     esi, ecx\n\
        jmp     short _drop_\n\n\
    _mod_:\n\
        mov     ecx, eax\n\
        xchg    eax, edx\n\
        xor     edx, edx\n\
        div     ecx\n\
    _save_edx_down1:\n\
        mov     [edi-0x8], edx\n\
        jmp     short _drop_\n\n\
    _above_:\n\
        xor     ecx, ecx\n\
        cmp     eax, edx\n\
        ja      short _save_ecx_down1\n\
        dec     ecx\n\
    _save_ecx_down1:\n\
        mov     [edi-0x8], ecx\n\
        jmp     short _drop_\n\n\
    _below_:\n\
        xor     ecx, ecx\n\
        cmp     eax, edx\n\
        jb      short _save_ecx_down1\n\
        dec     ecx\n\
        jmp     short _save_ecx_down1\n\n\
    _add_:\n\
        add     eax, edx\n\
        jmp     short _save_eax_down1\n\n\
    _sub_:\n\
        sub     edx, eax\n\
        jmp     short _save_edx_down1\n\n\
    _mul_:\n\
        mul     edx\n\
        jmp     short _save_eax_down1\n\n\
    _xor_:\n\
        xor     eax, edx\n\
        jmp     short _save_eax_down1\n\n\
    _shr_:\n\
        xchg    eax, edx\n\
        xchg    ecx, edx\n\
        shr     eax, cl\n\
        jmp     short _save_eax_down1\n\n\
    _ror_:\n\
        xchg    eax, edx\n\
        xchg    ecx, edx\n\
        ror     eax, cl\n\
        jmp     short _save_eax_down1\n\n\
    _shl_:\n\
        xchg    eax, edx\n\
        xchg    ecx, edx\n\
        shl     eax, cl\n\
        jmp     short _save_eax_down1\n\n\
    _eq_:\n\
        xor     ecx, ecx\n\
        cmp     eax, edx\n\
        jnz     _save_ecx_down1\n\
        dec     ecx\n\
        jmp     short _save_ecx_down1\n\n\
    ;_sar_:\n\
    ;    xchg    eax, ecx\n\
    ;    sar     edx, cl\n\
    ;    xchg    edx, eax\n\
    ;    jmp     short _save_eax_down1\n\n\
    _not_:\n\
        not     eax\n\
        jmp     short _save_eax\n\n\
    _rot_:\n\
        mov     ecx, [edi-0xC]\n\
        mov     [edi-0xC], edx\n\
        mov     [edi-0x8], eax\n\
    _save_ecx_d:\n\
        mov     [edi-0x4], ecx\n\
        ret\n\n\
    ;_sal_:\n\
    ;    xchg    eax, ecx\n\
    ;    sal     edx, cl\n\
    ;    xchg    edx, eax\n\
    ;    jmp     short _save_eax_down1\n\n\
    ;_neg_:\n\
    ;    neg     eax\n\
    ;    jmp     short _save_eax\n\n\
    _div_:\n\
        mov     ecx, eax\n\
        xchg    eax, edx\n\
        xor     edx, edx\n\
        div     ecx\n\
    _save_eax_down1:\n\
        mov     [edi-0x8], eax\n\
        jmp     _drop_\n\n\
    _rol_:\n\
        xchg    eax, edx\n\
        xchg    ecx, edx\n\
        rol     eax, cl\n\
        jmp     short _save_eax_down1\n\n\
    _and_:\n\
        and     eax, edx\n\
        jmp     short _save_eax_down1\n\n\
    _or_:\n\
        or      eax, edx\n\
        jmp     short _save_eax_down1\n\n\
    _swap_:\n\
        xchg    eax, edx\n\
    _save_eax_edx:\n\
        mov     [edi-0x8], edx\n\
    _save_eax:\n\
        xchg    ecx, eax\n\
        jmp     short _save_ecx\n\
    _fetchb_:\n\
        movzx   eax, Byte [eax]\n\
        jmp     short _save_eax\n\n\
    _fetchw_:\n\
        movzx   eax, Word [eax]\n\
        jmp     short _save_eax\n\
    _fetchd_:\n\
        mov     eax, [eax]\n\
        jmp     short _save_eax\n\n\
    ;_esb_:\n\
    ;    cbw\n\
    ;_esw_:\n\
    ;    cwde\n\
    ;    jmp     short _save_eax\n\n\
    _save_ecx:\n\
        mov     [edi-0x4], ecx\n\
        ret\n\n\
    _pick_:\n\
        inc     eax\n\
        inc     eax\n\
        mov     edx, eax\n\
        call    __DSCheckInpOutp__\n\
        jc      _err_\n\
        shl     edx, 0x2\n\
        mov     eax, edi\n\
        sub     eax, edx\n\
        push    DWord [eax]\n\
        pop     DWord [edi-0x4]\n\
        ret\n\n\
    _roll_:\n\
        mov     edx, eax\n\
        inc     eax\n\
        inc     eax\n\
        call    __DSCheckInpOutp__\n\
        jc      _err_\n\
        pusha\n\
        mov     ecx, edx\n\
        xchg    esi, edi\n\
        mov     ebx, ecx\n\
        inc     ebx\n\
        shl     ebx, 0x2\n\
        sub     esi, ebx\n\
        lea     edi, [esi-0x4]\n\
        push    DWord [edi]\n\
        cld\n\
        rep     movsd\n\
        pop     DWord [edi]\n\
        popa\n\
        sub     edi, 0x4\n\
        ret\n\n\
    _drop_d:\n\
        sub     edi, 0x4\n\
        ret\n\n\
    _ret_:\n\
        call    __RSPOP__\n\
        jc      _err_edx\n\
        mov     esi, eax\n\
        ret\n\n\
    ;_cdtr_:\n\
    ;    mov     edx, eax\n\
    ;    call    __RSPUSH__\n\
    ;    jc      short _err_edx\n\
    ;    ret\n\n\
    ;_crtd_:\n\
    ;    mov    edx, [ebx + PICOVM_CONTEXT._rstack_top]\n\
    ;    mov    eax, [ebx + PICOVM_CONTEXT._rstack_begin]\n\
    ;    cmp    edx, eax\n\
    ;    jbe    .err\n\
    ;    mov    ecx, [edx-0x4]\n\
    ;    jmp    _save_ecx_up1\n\
    ;.err:\n\
    ;    mov    eax, PICOVM_ERR_RSUNDERFLOW\n\
    ;    jmp    _err_\n\
    _err_edx:\n\
        xchg   eax, edx\n\
    _err_:\n\
        mov     [esp+0x8], eax\n\
        ret\n';
    
    var macroparams = [];
    var struc = 'struct PICOVM_CONTEXT\n';
    picovm_struc = _.shuffle(
    [['_dstack_top             dd ?', 'dstop'], 
     ['_dstack_begin           dd ?', 'dsb'],
     ['_rstack_top             dd ?', 'rstop'],
     ['_rstack_begin           dd ?', 'rsb'],
     ['_instruction_pointer    dd ?', 'ip'],
     ['_dstack_size            db ?', 'dssz'],
     ['_rstack_size            db ?', 'rssz']]);
    //picovm_struc+='';
    _.each(picovm_struc, function (a){ 
      struc+=a[0]+'\n'; 
      macroparams.push(a[1]);
    }, this);
    struc+='\nends';
    var macro = 'macro PICOVM_CTX ip, dssz, rssz, rstop, dstop, rsb, dsb {  PICOVM_CONTEXT '+ macroparams.join(', ')+' }\n';
    var cmds = [
    ['fetchb', 0x1, 0x1, 0x0],    
    ['fetchw', 0x1, 0x1, 0x0],
    ['fetchd', 0x1, 0x1, 0x0],
    ['storeb', 0x1, 0x2, 0x0],
    ['storew', 0x1, 0x2, 0x0],
    ['stored', 0x1, 0x2, 0x0],
    ['not', 0x1, 0x1, 0x0],
    ['or', 0x1, 0x2, 0x0],
    ['and', 0x1, 0x2, 0x0],
    ['xor', 0x1, 0x2, 0x0],
    ['loadcb', 0x2, 0x0, 0x1],
    ['loadcw', 0x3, 0x0, 0x1],
    ['loadcd', 0x5, 0x0, 0x1],
    ['rol', 0x1, 0x2, 0x0],
    ['ror', 0x1, 0x2, 0x0],
    ['shl', 0x1, 0x2, 0x0],
    ['shr', 0x1, 0x2, 0x0],
    ['eq',  0x1, 0x2, 0x0],
    ['above', 0x1, 0x2, 0x0],
    ['below', 0x1, 0x2, 0x0],
    ['drop',0x1, 0x1, 0x0],
    ['swap',0x1, 0x2, 0x0],
    ['over',0x1, 0x2, 0x0],
    ['pick',0x1, 0x2, 0x0],
    ['roll',0x1, 0x2, 0x0],
    ['add', 0x1, 0x2, 0x0],
    ['sub', 0x1, 0x2, 0x0],
    ['mul', 0x1, 0x2, 0x0],
    ['div', 0x1, 0x2, 0x0],
    ['mod', 0x1, 0x2, 0x0],
    ['rot', 0x1, 0x3, 0x0],
    ['dup', 0x1, 0x1, 0x1],
    ['jmpr', 0x0, 0x1, 0x0],
    ['jmpa', 0x0, 0x1, 0x0],
    ['jmpc', 0x0, 0x2, 0x0],
    ['calla', 0x0, 0x1, 0x0],
    ['callr', 0x0, 0x1, 0x0],
    ['calln', 0x0, 0x1, 0x0],
    ['ret', 0x0, 0x0, 0x0]];
    
    fncs=_.shuffle(fncs);
    cmds=_.shuffle(cmds);
    var vmconst = [];
    var fncs_inc = '';
    var fncs_asm = '';
    var cmds_inc = '';
    var cmds_asm = 'cmdsTable:\n';
    var i = 0;
    _.each (fncs, function(a) { fncs_inc += 'PICOVM_FNC_'+a+' = '+i+'\n'; fncs_asm += '  db  __'+a+'__\n'; i++;}, this);
    i = 0;
    _.each (cmds, function(a) { 
        cmds_inc += 'PICOVM_'+a[0].toUpperCase()+'_OPCODE equ '+i.toHex()+'\n'; 
        cmds_asm += ' PICOVM_COMMAND_ENTRY _'+a[0]+'_, '+a[1].toHex()+', '+a[2].toHex()+', '+a[3].toHex()+'\n';
        i++;}, this);
    cmds_inc += 'PICOVM_HLT_OPCODE equ 0xFF\n';
    var picovm_asm = picovm_asm_begin +'\n'+fncs_asm +'\n'+ picovm_asm_body + '\n\n'+cmds_asm;
    var picovm_inc = struc +'\n'+macro+'\n'+fncs_inc +'\n' + cmds_inc +'\n' + picovm_inc_end;
    var settings = JSON.stringify({date: null, cmds: _.pluck(cmds, 0), consts: fncs});
    fs.writeFile(process.argv[2]+'\\picovm.settings.json', settings);
    fs.writeFile(process.argv[2]+'\\picovm.asm', picovm_asm);
    fs.writeFile(process.argv[2]+'\\picovm.inc', picovm_inc);
    
    Изначально написано для Please login or register to view links
     
    • Like Like x 6
    Метки:

Поделиться этой страницей

Загрузка...