Придумай инструкцию x86!

Тема в разделе "WASM.HEAP", создана пользователем alpet, 22 июн 2005.

  1. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Почeму у процессоров i8080/i8086/z80 имеется флаг AC индикации переноса из младшего ниббла в старший, чтобы корректно работали инструкции AAA/AAS/DAA, но отсутствуют команды ветвления, управляемые этим флагом?

    Инженеры некогда просто сцепили два 4-битных сумматора в один 8-битный, а перемычку переноса вывели в флаг. Это всё понятно…
    Однако, могли бы зарезервировать отдельный регистр с результатом побитового переноса. Авось, где-нибудь да пригодился для оптимизации кода…

    Об этом я давно думал.
    Если операции DIV/IDIV выдают двойной результат - частное и остаток, почему тогда ADC/ADD/SBB/SUB/CMP не могут вернуть промежуточный результат побитового переноса?
    Так как ADC/ADD/SBB/SUB/CMP являются комплексным сочетанием операций XOR/AND, можно было бы вывести промежуточные биты переносов между этими звеньями…

    В ЯВУ типа Паскаль и Си в комплект к операциям DIV и «/» имеются ещё MOD и «%» для возврата остатка.
    Хотя процессор одной операцией возвращает всегда частное с остатком, в ЯВУ это - разные операции…

    Для чего это нужно?
    По школьной программе язык Бейсика осваивается за 4 часа.
    Наверное не все знают, что Бейсик по книжкам я осваивал около года самостоятельно!
    Хотя, благодаря рубрике «Радио начинающим» журналов РАДИО я вполне разбирался в логических схемах к шестому классу. Но с трудом осваивал Бейсик!
    Всё произошло в один миг. В журнале изучал фрагмент на ассемблере от игры «Гонки» и сопоставлял с цветной таблицей команд К580ВМ80. И в один миг что-то щёлкнуло и я понял суть операции MOV…
    Так из электронщика я стал программистом, который стал бить голые дампы. А потом уже махом разобрался и с Бейсиком…

    И вот, как электронщик, я не мог понять, почему в схеме я всегда могу взять сигнал из любой точки, а в программе для этого нужно дублировать ход операций, маскировать и сдвигать…
    Особенно не понравилось, что при прямой работе с графикой в ZX-Spectrum мне приходилось производить кучу операций сдвига, так как буфер экрана там нелинейный.

    P.S.: Выбрось из процессора любую, казалось бы, ненужную инструкцию редкого использования, как большинство программ тут же не смогут работать!
    Тем самым, будь у процессоров не один/два флага переноса, а целый отдельный регистр, программы бы и его использовали и не могли без него…
    Файл таблицы промежуточных результатов переносов между звеньями сумматора
     

    Вложения:

    • carriers.pdf
      Размер файла:
      271,8 КБ
      Просмотров:
      620
  2. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    Paguo_86PK,
    и тем не менее, в x64 BOUND, DAS, DAA, AAA, AAS, AAM, AAD из списка команд удалены :)
     
  3. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Eсли мы эмулируем процессор, естественно, 40-летнего возраста, то без этих команд, с большей или меньшей вероятностью, программы могут словить глюк.
    (Бывали случаи, когда многочисленные игры работали нормально, а Бейсик спотыкался даже на PRINT с печатью константы)
    А при переходе между поколениями одной архитектуры, когда инженерами удаляются команды и это документируется, то, естественно, всё будет гладко :good3:
     
  4. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Интересныe ссылочки нашёл:
    lock cmpxchg8b eax
    NTAPI Undocumented Functions
    long nop
    (Эти nop'ы, например, можно эзотерически включать в свой код и организовать WhiteSpace-язык на уровне x86-инструкций…
    Интересно было бы написать программу, которая запускает и исполняет код из одних nop'ов, хотя сам по себе этот код самостоятельно при запуске ничего не делает и отладчиком одни лишь nop'ы трассируются…
    Практически, обфускация по-чёрному!)

    P.S.: Может, кому пригодятся…
    И мне, чтобы не потерять… :whistle2:
     
    q2e74 нравится это.
  5. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.995
    Ммм... зачем? Исходник по третьей ссылке умеет выравнивать метки либо вариациями на тему lea esi,[esi] (играясь с mod/rm и sib), либо разными вариантами NP 0F 1F /0, the multi-byte form of NOP, точно так же играясь с mod/rm и sib. В зависимости от того, поддерживает ли процессор такой ноп. The multi-byte NOP instruction does not alter the content of a register and will not issue a memory operation. То есть такой код ну совсем ничего не делает.

    ЗЫ: интеловский справочник потерять сложней, а в нем все то же самое изложено
    [​IMG]
     
    Последнее редактирование: 26 ноя 2019
  6. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Одни из первых реализаций по обходу ав(полиморфы) использовали не мод кода, а затирание его частей нопами. Добро пожаловать в 90-е года.
     
  7. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    A я их и не покидал! :boast:
    A я и написал, что WhiteSpace-язык в Блокноте тоже ничего не делает: Нужен интерпретатор-транслятор.
    Так и с nop'ами: Запустил программу - ничего не происходит и дебаггер не помогает.
    Но, с помощью nop-конвертора, эти nop'ы парсятся и сохраняются в другой файл, в котором вместо длиннющих nop'ов - какие-то реальные операции.

    P.S.: Очень быстро читали текст, скорее всего, и не вникли в мою мысль… :acute:
     
  8. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Paguo_86PK,

    > Запустил программу - ничего не происходит и дебаггер не помогает.

    Это только означает что ты не умеешь(тк не знаешь архитектуру) пользоваться отладчиком.

    > Но, с помощью nop-конвертора, эти nop'ы парсятся и сохраняются в другой файл

    Я об этом и говорю, полностью тебя понял. Это древние идеи полиморфизма, самые начала виксов. Это столь примитивные техники, не удивительно что ты немного отстал лет на 20.
     
  9. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.995
    Нет, про идею кодировать в этих нопах что-то свое я понял, но упоминание об исполнении этого кода в отладчике как бы подразумевает прямое исполнение.
     
  10. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Простo, пока возился с своей тематикой портово-/эскейпного API, наткнулся ещё на эти nop'ы, которые никаким образом исключения не генерируют и поломали мне мозг.
    И вдруг подумалось, что если Escape-инструкции я изыму из-под FPU, то как раз эти nop'ы можно было бы подставить для FPU-команд.

    Прежде, чем что-то сейчас писать мне в ответ …
    P.S.: Вспомните про мой принцип с гвоздями! :lol:
    Или мы уже забыли друг друга? :dirol:
     
  11. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Paguo_86PK,

    Помню хорошо, дело не в этом. Вы чётко описали очень старую реализацию, где сигнатуры удаляются путём добавления фиксированного мусора(именно нопы). Сигнатуры или криптофункции вычисляются не от кода, а от его кодирующих данных. Эта простота и дала работу аверам.

    > которые никаким образом исключения не генерируют

    Какого рода исключения ?
    Кодировка эффективного адреса хоть в инструкции имеется, но нет выборки - есть есчо инструкция LEA.
     
  12. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Этo я знаю. Особенно, если «LEA R,R1», а не «LEA R,M», так как она любит только векторы вычислять…
    Итого, через LEA имеем 64 комбинации, ведущие к исключению. :beach:
     
  13. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Paguo_86PK,

    А что вы понимаете по исключением, что это значит ?
     
  14. q2e74

    q2e74 Active Member

    Публикаций:
    0
    Регистрация:
    18 окт 2018
    Сообщения:
    999
    а можно на примере?
     
  15. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    80386 Programmer's Reference Manual -- Opcode LEA
     
  16. q2e74

    q2e74 Active Member

    Публикаций:
    0
    Регистрация:
    18 окт 2018
    Сообщения:
    999
    Paguo_86PK,
    а число - 64 комбинации - этот результат как получили?
     
  17. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    K гадалке сходил :lol:
    x86-rmod.png
     
    Последнее редактирование: 27 ноя 2019
    q2e74 нравится это.
  18. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Paguo_86PK,

    Я думал про невозможность фаулта, подразумевалось что инструкция закодирована корректно :good3:
     
  19. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    600
    Вопрос?
    Код (ASM):
    1.  
    2. nop2 MACRO
    3. mov ecx, ecx
    4. ENDM
    5. nop3 MACRO
    6. lea ecx, [ecx+12h]
    7. org $-1
    8. db 0
    9. ENDM
    10. nop4 MACRO
    11. lea esp, [esp+12h]
    12. org $-1
    13. db 0
    14. ENDM
    15. nop5 MACRO
    16. mov edx, edx
    17. lea ecx, [ecx+12h]
    18. org $-1
    19. db 0
    20. ENDM
    21. nop6 MACRO
    22. lea ecx, [ecx+12345678h]
    23. org $-4
    24. dd 0
    25. ENDM
    26. nop7 MACRO
    27. lea esp, [esp+12345678h]
    28. org $-4
    29. dd 0
    30. ENDM
    31.  
    Есть ли более длинные NOP'ы? Использую х86 MASM, UASM.
     
    Последнее редактирование: 29 ноя 2019
  20. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.995
    Выше ссылка была на стандартные последовательности
    Код (C):
    1.   /* Various efficient no-op patterns for aligning code labels.
    2.      Note: Don't try to assemble the instructions in the comments.
    3.      0L and 0w are not legal.  */
    4.   static const unsigned char f32_1[] =
    5.     {0x90};                    /* nop            */
    6.   static const unsigned char f32_2[] =
    7.     {0x66,0x90};                /* xchg %ax,%ax */
    8.   static const unsigned char f32_3[] =
    9.     {0x8d,0x76,0x00};                /* leal 0(%esi),%esi    */
    10.   static const unsigned char f32_4[] =
    11.     {0x8d,0x74,0x26,0x00};            /* leal 0(%esi,1),%esi    */
    12.   static const unsigned char f32_5[] =
    13.     {0x90,                    /* nop            */
    14.      0x8d,0x74,0x26,0x00};            /* leal 0(%esi,1),%esi    */
    15.   static const unsigned char f32_6[] =
    16.     {0x8d,0xb6,0x00,0x00,0x00,0x00};        /* leal 0L(%esi),%esi    */
    17.   static const unsigned char f32_7[] =
    18.     {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00};    /* leal 0L(%esi,1),%esi */
    19.   static const unsigned char f32_8[] =
    20.     {0x90,                    /* nop            */
    21.      0x8d,0xb4,0x26,0x00,0x00,0x00,0x00};    /* leal 0L(%esi,1),%esi */
    22.   static const unsigned char f32_9[] =
    23.     {0x89,0xf6,                    /* movl %esi,%esi    */
    24.      0x8d,0xbc,0x27,0x00,0x00,0x00,0x00};    /* leal 0L(%edi,1),%edi */
    25.   static const unsigned char f32_10[] =
    26.     {0x8d,0x76,0x00,                /* leal 0(%esi),%esi    */
    27.      0x8d,0xbc,0x27,0x00,0x00,0x00,0x00};    /* leal 0L(%edi,1),%edi */
    28.   static const unsigned char f32_11[] =
    29.     {0x8d,0x74,0x26,0x00,            /* leal 0(%esi,1),%esi    */
    30.      0x8d,0xbc,0x27,0x00,0x00,0x00,0x00};    /* leal 0L(%edi,1),%edi */
    31.   static const unsigned char f32_12[] =
    32.     {0x8d,0xb6,0x00,0x00,0x00,0x00,        /* leal 0L(%esi),%esi    */
    33.      0x8d,0xbf,0x00,0x00,0x00,0x00};        /* leal 0L(%edi),%edi    */
    34.   static const unsigned char f32_13[] =
    35.     {0x8d,0xb6,0x00,0x00,0x00,0x00,        /* leal 0L(%esi),%esi    */
    36.      0x8d,0xbc,0x27,0x00,0x00,0x00,0x00};    /* leal 0L(%edi,1),%edi */
    37.   static const unsigned char f32_14[] =
    38.     {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00,    /* leal 0L(%esi,1),%esi */
    39.      0x8d,0xbc,0x27,0x00,0x00,0x00,0x00};    /* leal 0L(%edi,1),%edi */
    40.   static const unsigned char f16_3[] =
    41.     {0x8d,0x74,0x00};                /* lea 0(%esi),%esi    */
    42.   static const unsigned char f16_4[] =
    43.     {0x8d,0xb4,0x00,0x00};            /* lea 0w(%si),%si    */
    44.   static const unsigned char f16_5[] =
    45.     {0x90,                    /* nop            */
    46.      0x8d,0xb4,0x00,0x00};            /* lea 0w(%si),%si    */
    47.   static const unsigned char f16_6[] =
    48.     {0x89,0xf6,                    /* mov %si,%si        */
    49.      0x8d,0xbd,0x00,0x00};            /* lea 0w(%di),%di    */
    50.   static const unsigned char f16_7[] =
    51.     {0x8d,0x74,0x00,                /* lea 0(%si),%si    */
    52.      0x8d,0xbd,0x00,0x00};            /* lea 0w(%di),%di    */
    53.   static const unsigned char f16_8[] =
    54.     {0x8d,0xb4,0x00,0x00,            /* lea 0w(%si),%si    */
    55.      0x8d,0xbd,0x00,0x00};            /* lea 0w(%di),%di    */
    56.   static const unsigned char jump_31[] =
    57.     {0xeb,0x1d,0x90,0x90,0x90,0x90,0x90,    /* jmp .+31; lotsa nops    */
    58.      0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
    59.      0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
    60.      0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
    61.   static const unsigned char *const f32_patt[] = {
    62.     f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8,
    63.     f32_9, f32_10, f32_11, f32_12, f32_13, f32_14
    64.   };
    65.   static const unsigned char *const f16_patt[] = {
    66.     f32_1, f32_2, f16_3, f16_4, f16_5, f16_6, f16_7, f16_8
    67.   };
    68.