Что такое эмуляция ?

Тема в разделе "WASM.RESEARCH", создана пользователем Entropy, 15 фев 2026.

  1. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    291
    Мне как человеку который начал занимается относительно недавно,вообще не понятно что такое эмуляция,почитал википедию,как написано в википедии это копирование вычислительной системы,то есть если я напишу программу которая исполняет ассемблерную команду MOV EAX,700 ,это будет эмуляцией ?
     
  2. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    802
    Эмулятор(вирт машина) реализует состояние(task state) с изоляцией эмулируемого состояния.

    Куда сложнее дать определение интерпретации(байткод вм), тащит taint.
     
  3. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    291
    цитата из википедии https://ru.wikipedia.org/wiki/Эмуляция
    если исходить из этого определения,программа содержащая алгоритм,который эквивалентен ассемблерной инструкции MOV EAX,700 это будет эмуляция,так что всё правильно
     
  4. MaKsIm

    MaKsIm Active Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    223
    Не совсем. Чтобы это стало эмуляцией программе нужен еще и код нахождения необходимости исполнения этой инструкции. И вот тогда это будет уже частичной эмуляцией. А чтобы полностью что-то эмулировать надо создавать код для всего набора переменных состояний всей эмулируемой системы. Это значит, что надо делать не только регистр EAX, а весь набор RIP,RAX-R15,EFL,ST0-ST7,FCW,FSW,MM0-MM7,XMM0-XMM31 и т.д. и всех команд. Но это только процессор. Надо еще эмулировать работу GPU, клавиатуры, мыши, сетевой карты и портов ВВ.
     
  5. Application

    Application Moderator Команда форума

    Публикаций:
    1
    Регистрация:
    8 дек 2007
    Сообщения:
    991
    Возможно бред собачий:
    Код (C):
    1. // Это  "виртуальный процессор"
    2. struct CPU {
    3.     int EAX; // Регистр EAX
    4.     int EBX;
    5.     int ECX;
    6.     // ... и все остальные регистры
    7. };
    8.  
    9. struct CPU my_emulated_cpu;
    10.  
    11. // Функция, которая "эмулирует" одну команду
    12. void emulate_command(int command_code) {
    13.     if (command_code == COMMAND_MOV_EAX_700) {
    14.         my_emulated_cpu.EAX = 700; // эмуляция
    15.         printf("Эмуляция: MOV EAX, 700 выполнена. EAX = %d\n", my_emulated_cpu.EAX);
    16.     }
    17. }
    --- Сообщение объединено, 15 фев 2026 ---
    https://wiki.qemu.org/Documentation/TCG/frontend-ops
     
  6. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    802
    Не поленился заскринил.
     

    Вложения:

    • vm.png
      vm.png
      Размер файла:
      953,7 КБ
      Просмотров:
      685
  7. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    291
    то есть алгоритм должен установить зачем вообще в регистр помещать непосредственное значение ?
     
  8. MaKsIm

    MaKsIm Active Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    223
    Не должен. Он должен найти код соответствующей инструкции в потоке команд перед тем как выполнить подобную операцию (MOV EAX, 700 только когда в потоке команд встретится B8 BC 02 00 00).

    ADD: После выполнения этой операции поток команд должен быть пропущен ровно на количество байт в коде этой инструкции, чтобы перейти к следующей. Точно так же и после инструкции JMP не надо пропускать инструкцию т.к. новый адрес инструкции уже готов в указателе команды после этой операции.

    ADD2: По сути эмуляции это программный цикл, который исполняет оборудование. Т.е. ЦП точно так же выбирает инструкцию за инструкцией и выполняет их. Вот именно это и будет подразумевать эмуляция в первом приближении. Дальше надо будет сделать еще математику преобразования адресов эмулируемого ЦП на хост память и т.д. для всей эмулируемой системы.
    --- Сообщение объединено, 21 фев 2026 ---
    Вообще полный код будет примерно такой:
    Код (Text):
    1. NextOpcode:
    2. MOV EAX, [CPU.REGS.EIP]
    3. CMP BYTE [EAX], 0B8h
    4. JNZ UnderConstructionOpcodes
    5. MOV EDX, DWORD [EAX + 1]
    6. ADD EAX, 5
    7. MOV [CPU.REGS.EAX], EDX
    8. MOV [CPU.REGS.EIP], EAX
    9. JMP NextOpcode
    10. UnderConstructionOpcodes:
    11. HLT
    12. JMP UnderConstructionOpcodes
     
    Последнее редактирование: 21 фев 2026
  9. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    536
    MaKsIm, не обижайтесь, если что, но хотел полюбопытствовать. Это ваши мысли или вы их у ИИ одолжили? Я почему спрашиваю? С ИИ ведь, это как игра в рулетку - иногда очень точно попадает в цель, а чаще может с умным видом академика, нести полный бред и утверждать, что в его ответе нет ошибки. :)
     
  10. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    291
    MaKsIm, получается что нужно декодировать инструкцию
    --- Сообщение объединено, 22 фев 2026 ---
    MaKsIm, то есть по опкоду инструкции понять что нужно делать,например помещать значение а регистр
     
  11. Application

    Application Moderator Команда форума

    Публикаций:
    1
    Регистрация:
    8 дек 2007
    Сообщения:
    991
    Entropy, я так же както задавалса этим вопросом на васме
     
  12. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    802
    CaptainObvious

    Быстрый табличный эмуль, на целевом ISA(eg: div -> vm(div), как у аверов, bdshemu сырое-кривое). Тогда можно не использовать rX-память, меньше палева :preved:
     
  13. Application

    Application Moderator Команда форума

    Публикаций:
    1
    Регистрация:
    8 дек 2007
    Сообщения:
    991
    Как-то же такие эмуляторы работают. Сделать в виде набора вкладок.
    --- Сообщение объединено, 22 фев 2026 ---
    2026-02-22_17-48-49.png
     

    Вложения:

    • Tracing.rar
      Размер файла:
      194 КБ
      Просмотров:
      620
  14. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    536
    Ahimov, спасибо за ссылку на bddisasm. Штука любопытная, но сложноватая зараза. :) А в чужом коде - то ещё удовольствие разбираться. Что в эмуляторе, что в дизассемблере - где 5000 строк кода, где 3500. Ну в принципе разобраться можно. В Visual Studio все прекрасно компилируется. Я только ещё не до конца понял, как там код Питона запускать и главное с чем?

    Нужно, правда, как там выше предлагали, что-нибудь своё, учебное разработать на базе, скажем, пяти инструкций. Так потихоньку, помаленьку - глядишь и свой WASM'кий визор разработаем. :)
     
    Последнее редактирование: 23 фев 2026
  15. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    802
    GRAFik

    Код (Text):
    1. ViJCC:
    2.     mov eax,D[eax][2]   ; disp32
    3.     add eax,[esi].Control.rEip
    4.     add eax,6   ; flow
    5.     mov edx,[ebx].Ia.Opcode
    6.     sub edx,80H   : CC
    7. ViCC:
    8.     push eax
    9.     invoke DiIsCC, Edx, [Esi].Control.rEFlags   ; CC & state{}.EFlags
    10.     pop eax
    11.     .if Zero?
    12.         mov eax,[ebx].Ia.S1ze   ; skip
    13.         add eax,[esi].Control.rEip   ; state{}.Eip
    14.     .endif
    15.     ret
     
  16. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    291
    так всё же мои догадки по поводу эмуляции верны ?
     
  17. MaKsIm

    MaKsIm Active Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    223
    Вообще эмуляция это комплексный процесс. Декодирование опкодов инструкций и выполнение подобных им команд только часть связанная с ЦП. Сама по себе эмуляция подразумевает, что будет воспроизводиться не только работа ЦП, но и всех остальных сопутствующих устройств. Таким образом программа попавшая в эмулятор не должна отличать свое исполнение от исполнения на реальном железе.
     
  18. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    291
    MaKsIm, то есть получается так,эмуляция это программное воспроизведение принципов работы физического устройства,с максимальной точностью
     
  19. MaKsIm

    MaKsIm Active Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    223
    Так точно. Именно это и было написано еще в ответе #2 у Ahimov, Я лишь вам попытался донести тоже, но без специальной терминологии. Некоторые старички пользуются краткими определениями, которые зачастую не понятны по смыслу для новичков.
    --- Сообщение объединено, 24 фев 2026 ---
    Вообще, скажем, у вас есть PS1/SNES/NES или другая консоль. Вы можете запустить эмулятор этой консоли на ПК и игры к ним (может со скрипом), но запустятся. При этом ЦП этой консоли может отличаться от ЦП на ПК. Вот эмуляция дешифрует поток команд игры для консоли и создает на ПК среду для исполнения программы. Таким образом программа думает, что работает на PS1, а вместо этого вы играете в игру на ПК. Получается что от программы изолирована реальная среда и создана подходящая для её работы программно.
     
    Последнее редактирование: 24 фев 2026
  20. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    536
    Набросал небольшой прототип учебного эмулятора на 4 регистра. Память выделил, но для упрощения понимания принципа работы, пока не задействовал. Критика и замечания приветствуются.
    Код (C):
    1. #include <stdio.h>
    2. #include <stdint.h>
    3.  
    4. #define MEMORY_SIZE 0x1000  // 4 Кб памяти
    5. #define NUM_REGS 4          // Количество регистров
    6.  
    7. typedef struct {
    8.     uint8_t memory[MEMORY_SIZE];  // Память
    9.     uint32_t regs[NUM_REGS];      // Регистры
    10. } bdshemu_context;
    11.  
    12. void print_registers(bdshemu_context* ctx) {
    13.     printf("Registers:\n");
    14.     for (int i = 0; i < NUM_REGS; i++) {
    15.         printf("R%d = 0x%08X\n", i, ctx->regs[i]);
    16.     }
    17. }
    18.  
    19. void process_instructions(bdshemu_context* ctx, uint8_t* code, size_t code_size) {
    20.     size_t ip = 0;  // Instruction pointer
    21.  
    22.     while (ip < code_size) {
    23.         uint8_t opcode = code[ip++];
    24.  
    25.         switch (opcode) {
    26.         case 0x01:  // MOV
    27.             // MOV <reg>, <value>
    28.         {
    29.             uint8_t reg = code[ip++];
    30.             uint8_t value = code[ip++];
    31.             ctx->regs[reg] = value;
    32.             printf("MOV R%d, 0x%02X\n", reg, value);
    33.         }
    34.         break;
    35.  
    36.         case 0x02:  // ADD
    37.             // ADD <reg>, <value>
    38.         {
    39.             uint8_t reg = code[ip++];
    40.             uint8_t value = code[ip++];
    41.             ctx->regs[reg] += value;
    42.             printf("ADD R%d, 0x%02X\n", reg, value);
    43.         }
    44.         break;
    45.  
    46.         case 0x03:  // SUB
    47.             // SUB <reg>, <value>
    48.         {
    49.             uint8_t reg = code[ip++];
    50.             uint8_t value = code[ip++];
    51.             ctx->regs[reg] -= value;
    52.             printf("SUB R%d, 0x%02X\n", reg, value);
    53.         }
    54.         break;
    55.  
    56.         case 0x90:  // NOP
    57.             // No operation
    58.             printf("NOP\n");
    59.             break;
    60.  
    61.         case 0x04:  // JMP
    62.             // JMP <address>
    63.         {
    64.             uint8_t low = code[ip++];
    65.             uint8_t high = code[ip++];
    66.             uint16_t address = (high << 8) | low;
    67.             printf("JMP to address: 0x%04X\n", address);
    68.         }
    69.         break;
    70.  
    71.         default:
    72.             // Unknown byte
    73.             printf("Unknown byte encountered: 0x%02X\n", opcode);
    74.             break;
    75.         }
    76.     }
    77.  
    78.     // Print all registers after execution
    79.     print_registers(ctx);
    80. }
    81.  
    82. int main() {
    83.     bdshemu_context ctx = { 0 };  // Initialize context, all registers are 0
    84.  
    85.     // Example machine code to run on the emulator
    86.     uint8_t code[] = {
    87.         0x01, 0x00, 0x10,  // MOV R0, 0x10
    88.         0x66,              // Undefined instruction
    89.         0x02, 0x00, 0x05,  // ADD R0, 0x5
    90.         0x03, 0x00, 0x03,  // SUB R0, 0x3
    91.         0x90,              // NOP
    92.         0x04, 0x20, 0x00,  // JMP 0x20
    93.         0x01, 0x01, 0x28,  // MOV R1, 0x28
    94.         0x01, 0x02, 0x68,  // MOV R2, 0x68
    95.         0x77,              // Undefined instruction
    96.         0x03, 0x01, 0x03,  // SUB R1, 0x3
    97.         0x01, 0x03, 0x88  // MOV R3 0x88
    98.     };
    99.  
    100.     size_t code_size = sizeof(code) / sizeof(code[0]);
    101.  
    102.     // Process the instructions and print registers
    103.     process_instructions(&ctx, code, code_size);
    104.  
    105.     return 0;
    106. }
     
    Последнее редактирование: 24 фев 2026
    Tech и Application нравится это.