Mini VM

Тема в разделе "WASM.ZEN", создана пользователем marlboro, 18 ноя 2006.

  1. marlboro

    marlboro New Member

    Публикаций:
    0
    Регистрация:
    26 июн 2005
    Сообщения:
    35
    Вот решил сварганить что-нибудь на падобии того, о чем писали в соседнем топике http://www.wasm.ru/forum/viewtopic.php?id=8642
    Вообщем эта вм понимает только одну команду csub dest, src, которая действует следующим образом:

    if overflow_flag = 0
    overflow_flag = dest < src
    dest = dest-src
    else
    overflow_flag = 0
    end if

    Есть только один регистр ip в него можно писать(но команды csub ip,ip нету). При вызове vm в качестве параметров передаются: entry (указатель с которого начнуться интерпретироваться команды), base (относительно неё ведутся операции с памятью) и tail(команды выполняются пока ip < tail). Каждая из трех видов команды кодируется как байт операции и параметры(размером в слово). Соответственно имеем:

    syntax: csub [a],
    bin: db 010b, dw b, dw a

    syntax: csub ip,[a]
    bin: db 110b, dw a

    syntx: csub [a],ip
    bin: db 000b, dw a

    А вот исходник и макросы для поддержки:
    Код (Text):
    1. macro parse_operand operand
    2. {
    3.         match [cell], operand
    4.         \{
    5.                 if cell > vm_tail-vm_base
    6.                    dw cell-vm_base
    7.                 else
    8.                    dw cell shl 2
    9.                 end if
    10.         \}
    11. }
    12.  
    13. macro csub op0, op1
    14. {
    15.         if op0 eq ip
    16.            db 110b
    17.            parse_operand op1
    18.         else if op1 eq ip
    19.            db 000b
    20.            parse_operand op0
    21.         else
    22.            db 010b
    23.            parse_operand op1
    24.            parse_operand op0
    25.         end if
    26. }
    27.  
    28. vm_execute:
    29.         push    ebx esi edi
    30.         mov     esi,[esp+10h]
    31.         mov     ebx,[esp+14h]
    32.         mov     edi,[esp+18h]
    33.         xor     eax,eax
    34. process_instrux:
    35.         lods    byte [esi]
    36.         shr     eax,1
    37.         lods    word [esi]
    38.         jo      clear_flag
    39.         mov     edx,esi
    40.         jz      reg_to_mem
    41.         mov     edx,[ebx+eax]
    42.         jp      mem_to_reg
    43. mem_to_mem:
    44.         lods    word [esi]
    45. reg_to_mem:
    46.         sub     [ebx+eax],edx
    47.         jmp     finalize
    48. mem_to_reg:
    49.         sub     esi,edx
    50.         jmp     finalize
    51. clear_flag:
    52.         jnp     finalize
    53.         lods    word [esi]
    54. finalize:
    55.         sbb     eax,eax
    56.         cmp     edi,esi
    57.         ja      process_instrux
    58.         pop     edi esi ebx
    59.         ret
    А вот маленький пример использования:
    Код (Text):
    1. start:
    2.         ccall   vm_execute, vm_entry, vm_base, vm_tail
    3.         invoke  MessageBox, HWND_DESKTOP, vm_base, NULL, MB_OK
    4.         ret
    5.  
    6. vm_base:
    7. a       dd      ?
    8. b       dd      ?
    9. t       dd      ?
    10.  
    11. vm_entry:
    12.  
    13. macro zero op0
    14. {
    15.         csub    op0,op0
    16.         csub    op0,op0
    17. }
    18.  
    19. macro move op0, op1
    20. {
    21.         local   value
    22.         zero    op0
    23.         csub    op0,[value]
    24.         db      010b
    25. value   dd      -op1
    26. }
    27.  
    28. ; a = 0x41+0x20
    29.         move    [a],0x41
    30.         move    [b],0x20
    31.         csub    [t],[t]
    32.         csub    [t],[b]
    33.         csub    [t],[t]
    34.         csub    [a],[t]
    35. vm_tail: