Няшная / Говнокод #25399 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
// https://github.com/ghc/ghc/blob/e204431e5a5e2fd16da52b04bda2798f16c51344/rts/Interpreter.c#L1184

        case bci_PUSH8: {
            int off = BCO_NEXT;
            Sp_subB(1);
            *(StgWord8*)Sp = *(StgWord8*)(Sp_plusB(off+1));
            goto nextInsn;
        }

        case bci_PUSH16: {
            int off = BCO_NEXT;
            Sp_subB(2);
            *(StgWord16*)Sp = *(StgWord16*)(Sp_plusB(off+2));
            goto nextInsn;
        }

        case bci_PUSH32: {
            int off = BCO_NEXT;
            Sp_subB(4);
            *(StgWord32*)Sp = *(StgWord32*)(Sp_plusB(off+4));
            goto nextInsn;
        }

        case bci_PUSH8_W: {
            int off = BCO_NEXT;
            *(StgWord*)(Sp_minusW(1)) = *(StgWord8*)(Sp_plusB(off));
            Sp_subW(1);
            goto nextInsn;
        }

        case bci_PUSH16_W: {
            int off = BCO_NEXT;
            *(StgWord*)(Sp_minusW(1)) = *(StgWord16*)(Sp_plusB(off));
            Sp_subW(1);
            goto nextInsn;
        }

        case bci_PUSH32_W: {
            int off = BCO_NEXT;
            *(StgWord*)(Sp_minusW(1)) = *(StgWord32*)(Sp_plusB(off));
            Sp_subW(1);
            goto nextInsn;
        }

https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/Interpreter

> The linker lives in rts/Linker.c and is responsible for handling runtime loading of code into a Haskell process. This is something of a big blob of unpleasant code, and see DynamicGhcPrograms for information about efforts to reduce our dependence on this linker.

Итак, тут у нас стековая машина из хачкеля, которая вродекак отвечает за динамическую загрузку какого-то говна.

Запостил: j123123 j123123, (Updated )

Комментарии (101) RSS

  • Так блядь, хуйня типа Sp_subB(1); Sp_subB(2); и проч - она значит стекпоинтер декрементирует

    Что это за хуйня "*(StgWord8*)Sp" по-вашему? Типы StgWord8 StgWord16 StgWord32 определены в
    https://github.com/ghc/ghc/blob/1c2c2d3dfd4c36884b22163872feb87122b4528d/includes/stg/Types.h#L64


    Что мы видим? Обычные синонимы к херне из uint8_t int8_t uint16_t int16_t и так далее.

    А у нас тут есть херня такая, что для bci_PUSH8 мы делаем Sp_subB(1) т.е. уменьшаем стек на 1, потом кастуем: *(StgWord8*)Sp = *(StgWord8*)(Sp_plusB(off+1));

    Ну в общем какую-то херь в стек записываем из какого-то говна, но при этом стекпоинтер уменьшаем на 1. Т.е. стек у нас нихера не выровнен. И если потом будет хуйня bci_PUSH16: *(StgWord16*)Sp = *(StgWord16*)(Sp_plusB(off+2));

    Которая кастанет невыровненную хуйню в *uint16_t и потом разыменует даже. А это UB
    Ответить
    • https://github.com/ghc/ghc/blob/e204431e5a5e2fd16da52b04bda2798f16c51344/rts/Interpreter.c#L134


      #define Sp_plusB(n)  ((void *)(((StgWord8*)Sp) + (n)))
      #define Sp_minusB(n) ((void *)(((StgWord8*)Sp) - (n)))
      
      #define Sp_plusW(n)  (Sp_plusB((n) * sizeof(W_)))
      #define Sp_minusW(n) (Sp_minusB((n) * sizeof(W_)))
      
      #define Sp_addB(n)   (Sp = Sp_plusB(n))
      #define Sp_subB(n)   (Sp = Sp_minusB(n))
      #define Sp_addW(n)   (Sp = Sp_plusW(n))
      #define Sp_subW(n)   (Sp = Sp_minusW(n))
      
      #define SpW(n)       (*(StgWord*)(Sp_plusW(n)))
      #define SpB(n) (*(StgWord*)(Sp_plusB(n)))


      И кто вас блядь учил писать так макросы? Макросы принято писать КАПСОМ!
      Ответить
      • у яблока много макрософ не капсом

        да и у юнисков бывает так что есть функция foo и апнисано: "вронинг! эта функция может быть мокросом"
        Ответить
    • В S" Forth" всё в стеке занимает как минимум одну ячейку, даже символ. Именно поэтому я за S" Forth"
      Ответить
  • У нас было два пакетика GHC Core, семьдесят пять ампул C--, 5 пакетиков Spineless Tagless G-Machine или STG, солонка, наполовину наполненная LLVM, и целое море разноцветных бекендов, интерпретаторов, а так же пинта стекового языка, и 12 пузырьков ghci. Не то, чтобы всё это было категорически необходимо в языке программирования, но если уж начал обеспечивать студентов темами для masters theses, то к делу надо подходить серьёзно. Единственное, что вызывало у меня опасение — это стековые языки. Ничто в мире не бывает более беспомощным, безответственным и порочным, чем шитый код. Я знал, что рано или поздно мы перейдем и на эту дрянь.
    Ответить
    • в PHP ничего этого нет
      Именно потому я за "Haskell"
      Ответить
      • А я за «Ассемблер», потому что в нём нет ни кастов, ни UB. Можно просто изменять указатель на вершину стека и течь.
        Ответить
        • строго говоря и стек в нем не обязателен
          можно всю память выделить статически и там шарудить


          в няшной тоже можно, но надо убедица что кал-конвеншен там через регистры а не через

          я когда был мелким пиздюком и писал под tiny (когда вся мапять в одном сегменте 64К) а API биоса было на регистрах, и мне стек вообще не нужен был
          Ответить
          • Регистры иногда заканчиваются, надо где-то сохранять их содержимое. Да и в подпрограммах содержимое используемых регистров тоже надобно схоронить, а в конце восстановить. Так что без стека только совсем примитивные программы обходились.
            Ответить
            • > подпрограммах
              На фортране и бейсике отлично обходились без этих ваших автоматических переменных.
              Ответить
            • Недавно смотрел документацию по «Итаниуму» (помним, скорбим). У него была фишка, именуемая ротацией регистров. При упоминании в программе нумерных регистров PR16...PR63, GR32...GR127 и FR32...FR127 реальное обращение происходит не к регистру с указанным номером (N), а к регистру с номером N+RRB (по модулю количества регистров), где RRB –— специальный регистр, значение которого увеличивается на единицу после инструкции, передающей управление на начало цикла. Т. е. если на первой итерации цикла RRB=0, то при упоминании PR16 данные читаются из PR16, на второй итерации цикла RRB=1 и при упоминании PR16 данные читаются из PR17, на третьей итерации RRB=2 и при упоминании PR16 данные читаются из PR18 и так далее. Аппаратный кольцевой буфер!

              В «x86» вращаемых банков регистров нет, именно поэтому я за «x86».
              Ответить
              • > В «x86» вращаемых банков регистров нет, именно поэтому я за «x86».

                Зато в x86 можно циклически сдвигать какой-нибудь регистр, и брать от него кусочек поменьше. В x86-64 например 64-битный регистр rax и его 8-битные кусочки ah и al.
                Ответить
            • я же сказал -- статическая память.
              выделил сразу кусок и управляй ею

              хуже того: в асембреле у тебя не было никакой кучи ввиду аотстуствия ее менеджера
              вся пмять твоя
              Ответить
              • И это будет ёбаный пихдец из сотни глобалок, даже для временных переменных.

                > в асембреле у тебя не было никакой кучи
                В виндах и линупсах есть. И ничто не машало использовать билиботеку/написать свой для ДОЧ'а.
                Ответить
        • > А я за «Ассемблер», потому что в нём нет ни кастов, ни UB.

          В ассемблере есть (точнее, могут быть) недокументированные инструкции, которые хуй знает что делают. Вполне можно считать это UB-ом. А еще, если взять процессор версии X, в котором инструкция A (т.е. некоторая некорректная последовательность байт, которая не может быть декодирована как инструкция) не поддерживается (при попытке ее исполнения будет брошено исключение), то в каком-то более новом процессоре версии X+1 могут додуматься в такой способ кодировать некоторые инструкции, и тогда это уже не будет приводить к броску исключения.
          Ответить
          • Но ведь это не ассемблер, а машинные коды. Разве ассемблер (программа) может скомпилировать какой-то исходный код в бинарник с невалидными инструкциями (если погромист не додумался напрямую байтики писать через db, конечно)?
            Ответить
              • ну то-есть я могу скомпилироваться под прос с MMX наример и на 286 словить инвалид опкод?
                Ответить
                • Ты даже в 32-битный защищенный режим перейти не сможешь, потому что 286 в 32-бит не умеет
                  Ответить
                  • в смысле я не смогу загрузить в регистр десккриптор сегмента у кторого тип указн как 32?
                    то да

                    а так же не смогу писнуть с CR3 таблу страниц бо их тоже не было в 286 (хотя протектед мод там и был)_
                    Ответить
              • Ну нет. Это implementation-defined - я могу предсказать результат прочитав даташит на конкретный проц.

                З.Ы. Хотя... вызов недокументированной инструкции на старом проце всё-таки UB. Хуй знает что она там делала. Вроде не гарантируется, что все неизвестные инструкции должны кидать исключение?
                Ответить
                • > Ну нет. Это implementation-defined - я могу предсказать результат прочитав даташит на конкретный проц.

                  В даташите может быть ничего не написано по поводу этой инструкции. Может даже так оказаться, что при попытке выполнения этой инструкции, процессор сгорает нахрен.
                  Ответить
                  • а я не согласен

                    невалидная инсрукция это INVALID OPCODE.
                    Ответить
                    • Можно пруф из спеки, что каждая не описанная в ней инструкция кидает это исключение?

                      Вроде на интеле находили недокументированные опкоды которые что-то делают и не кидают.
                      Ответить
                      • кажется что в volume 3 написано только что UD2 явно вызовет UD#.
                        Впрочем, про UB тоже не написано.
                        Ответить
                        • Он документирован, оказывается.

                          The opcodes D6 and F1 are undefined opcodes reserved by the Intel 64 and IA-32 architectures.
                          Ответить
                          • иными словами возможна ситуация при которой интел зарезервирует опкод, но не привяжет к нему #UD?
                            Ответить
                            • Я думаю, что они больше так не делают.

                              Но надо ещё поискать как обстоят дела с недокументированными сочетаниями префиксов.
                              Ответить
                              • Other use of branch hint prefixes and/or other undefined opcodes with Intel 64 or IA-32 instructions is reserved; such use may cause unpredictable behavior.

                                Other use of the 66H prefix is reserved; such use may cause unpredictable behavior.

                                The address-size override prefix (67H) allows programs to switch between 16- and 32-bit addressing. <...> Using this prefix and/or other undefined opcodes when operands for the instruction do not reside in memory is reserved; such use may cause unpredictable behavior.
                                Ответить
                                • > unpredictable behavior.
                                  изобрел процессор который при использовании недокументированного префикса подымает напряжение на VRM до 12 вольт и самоуничтожается

                                  ни один копилятор или асемблер такую инструкцуию не генерит, так что вирус-убийцу процов пришлось писать на машинных колдах
                                  Ответить
                                  • На «x86» можно выполнить JMP в середину инструкции или вообще в секцию данных (если нет защиты от выполнения). Именно поэтому я за «x86».
                                    Ответить
                                    • Когда-то я тоже кодил на ассёмблере, но потом стал рекитиром.
                                      Ответить
                                        • Ххех. У меня ещё и писюк был, с пузатым таким, голубым экраном и жужжалка для плёнки.
                                          Ответить
                                  • > изобрел процессор который при использовании недокументированного префикса подымает напряжение на VRM до 12 вольт и самоуничтожается

                                    Интел кажется что-то такое тоже изобрел
                                    https://www.opennet.ru/opennews/art.shtml?num=52011

                                    > Суть метода заключается в создании условий для возникновения непредвиденных искажений данных при вычислениях в SGX, от которых не защищает применение шифрования и аутентификации памяти в анклаве. Для внесения искажений, оказалось, можно использовать штатные программные интерфейсы для управления частотой и напряжением, обычно применяемые для снижения энергопотребления во время простоя системы и активации максимальной производительности при выполнении интенсивных работ. Характеристики частоты и напряжения охватывают весь чип, в том числе влияют на выполнение вычислений в изолированном анклаве.

                                    > Изменяя напряжение, можно добиться возникновения условий, при которых заряда оказывается недостаточно для регенерации ячейки памяти внутри CPU, и её значение меняется. Ключевым отличием от атаки RowHammer является то, что RowHammer позволяет изменить содержимое отдельных битов в памяти DRAM, путём цикличного чтения данных из соседних ячеек, в то время как Plundervolt позволяет добиться изменения битов внутри CPU, когда данные уже загружены из памяти для выполнения вычислений. Подобная особенность позволяет обойти применяемые в SGX механизмы контроля целостности и шифрования данных в памяти, так как значения в памяти остаются корректными, но могут исказиться при операциях с ними до того, как результат будет записан в память.
                                    Ответить
                                    • Интересно, можно ли там что-то так зарегулировать, чтоб спалить процессор нахрен?
                                      Ответить
                                  • >изобрел процессор который при использовании недокументированного префикса подымает напряжение на VRM до 12 вольт и самоуничтожается

                                    Новая уязвимость у Интел процессоров позволяет управлять напряжением на камне +/- 0.5В, что легко может привести к его выходу из строя
                                    https://www.linux.org.ru/forum/talks/15845897
                                    Компания «Intel» пиздит идеи с говнокода.
                                    Ответить
                  • Программы с «классическим» — сишко-крестовым — UB использовать нельзя: их поведение не определено где угодно (оно может «правильно» работать на каких-то платформах, но рассчитывать на это категорически нельзя).
                    Чтобы поведение какой-то конструкции было implementation-defined, оно должно быть задокументировано для всех платформ:
                    implementation-defined behavior
                    behavior, for a well-formed program construct and correct data, that depends on the implementation and
                    that each implementation documents

                    §3.12, [defns.impl.defined]

                    В результате имеем, что неподдерживаемые инструкции ассемблера — это и не UB, и не ID: с одной стороны, на платформах без поддержки данной инструкции поведение в принципе не определено (т. е. уже не ID), а с другой — на «хороших» платформах — точно задокументировано (не UB).
                    Ответить
                    • 22.15 Undefined opcodes
                      All new instructions defined for IA-32 processors use binary encodings that were reserved on earlier-generation processors. Attempting to execute a reserved opcode always results in an invalid-opcode (#UD) exception being generated.

                      6.15 Exception and interrupt reference
                      Interrupt 6 - Invalid Opcode Exception (#UD)
                      <...> The opcodes D6 and F1 are undefined opcodes reserved by the Intel 64 and IA-32 architectures. These opcodes, even through undefined, do not generate an invalid opcode exception.

                      Интел сам себе противоречит... Все опкоды равны, но некоторые равнее других.
                      Ответить
          • Это не касты, а просто хинты для выбора инструкции. Можно с тем же успехом писать movb или movl. Или вообще не писать, если по регистру и так понятно.

            На касты там больше похожи movzx и movsx.
            Ответить
            • В "fasm" нет никакого movl. Вот например:
              n dq 4
              ; ...
              mov eax, dword [n]
              n имеет тип qword, без каста в dword он будет ругатся.
              Ответить
                • Не понял с чего вжрукк 32? В асамблерах же смещение никогда не умножается на размер элемента, там всё в батах считается же.
                  Ответить
                    • В "TASM" такаж хуня была, если N объявлено как DD, то чтобы считать слово надо было написать WORD PTR.
                      Ответить
                  • На ГК нужен какой-нибудь валидатор русского языка. Стоит выдавать сообщение "ошибка компиляции комментария", если комментарий претендует на информативность, но написан в стиле вореций.
                    Хм, или тупо скриптом Vindicar'а скрывать всех петухов, чтобы невалидное говно вида "вжрукк" не читать.
                    Ответить
              • ебать вы открыли для себя разницу AT&Tщниго и Intelовского синтаксиса

                праздравляю
                Ответить
                • Ахаха, на tio.run у "as" вот такой хеловелд;
                  .print "Hello, World!"
                  Почему тогда они у фасма они написали асамблерную программу, а не сделали так же директивой
                  display "Hello, World!"
                  ?
                  Ответить
    • Стековые языки не обязательно реализуются в шитом коде, например S" SP-FORTH" компилицца в нативный код, а 'RETRO_FORTH в байткод, просто шитый код легче декомпилить.
      Ответить
      • Ещё доебись что и регистровые ВМ могут быть на шитом коде. Я писатель, я так вижу.
        Ответить
      • давайте пиздеть про шитый код VS байткод
        Ответить
        • Давай. Чур я зашитого кода.

          Шитый код компактный, быстрый, а его интерпретатор реализуется парой инструкций. Вот минимальный адресный интерпретатор прямого шитого кода с примерами подпрограмм:
          ; esi -- указатель инструкций
          ; ebp -- стек развраьов
          ; esp -- стек банных
          
          macro next { ; сам адресный интерпретатор, этим макросом должны заканчиватся низкоуровневые определения
              lodsd
              jmp eax
          }
          
          macro rpush x { ; запушить x в стек развратов
              sub ebp, 4
              mov dword [ebp], x
          }
          macro rpop x { ; попнуть из стека развратов в x
              mov dword x, [ebp]
              add ebp, 4
          }
          
          ; примеры низкоуровневых определений:
          false:
              push 0
              next
          
          state:
              push var_state
              next
          
          var_state dd ?
          
          store_: ; x addr !
              pop ebx
              pop dword [ebx]
              next
          
          forth_call: ; помещается в начале "высокоуровневых" определений
              rpush esi
              pop esi
              next
          
          exit: ; возврат в вызывающую подпрограмму
              rpop esi
              next
          
          left_bracket: ; пример "высокоуровневого" определения
              call forth_call
              dd false, state, store_, exit

          А в косвенном шитом коде в высокоуровневых определениях только адреса, и они могут хранится в секции с данными, а само ядро маленькое и может целиком поместиться в кешу. А вот пример адресного интерпретатора косвенного шитого кода, он не сложнее и не больше чем у прямого:
          macro next {
              lodsd
              jmp [eax]
          }
          
          forth_call: ; адресс помещается в начале "высокоуровневых" определений
              rpush esi
              mov esi, eax
              add esi, 4
              next
          
          ; пример низкоуровневого определения
          exit dd @f
          @@:
              rpop esi
              next
          
          ; пример "высокоуровневого" определения:
          left_bracket dd forth_call, false, state_, store, exit
          А в подпрограмном шитом коде адресный интерпретатор не нужен, программа состоит из цепочки call'ов, и не сложно перейти от него к обычному нативному коду.

          Теперь ваш ход.
          Ответить
          • я тогда за байткода

            каждый оп в таком коде занимает один байт. Мало того что это сильно упрощает декодер, так еще и создает компактный код.

            Возьмем стековую машину где надо сложить 2 и 2

            push 2
            push 2
            add

            всё.
            Ответить
            • Хуёвый ты оппонент, тогда я пока временно за баткод:

              В байкоде только КОП занимает один байт, но у него ещё могут быть аргументы, как в твоём примере у push (и в шитом коде тоже могут быть оргументы). Сам код получается компактный, но для его декодирования нужна как минимум одна таблица как минимум на 256 адресов (можно и меньше, но придётся добавлять условия в интерпретаторе байткола), вот примитивный интерпретатор бацкода:
              ; esi -- укахатель инструкций
              ; ebx -- адрес таблицы
              ; esp -- стек банных
              ; ebp -- стек развратов
              
              next equ jmp next_
              
              next_:
                  xor eax, eax
                  lodsb
                  jmp dword [ebx + eax * 4] ; у джумпа же так можно?
              
              ; пример реализации самих команд:
              call_:
                  rpush esi
                  pop esi
                  next
              
              exit:
                  rpop esi
                  next
              
              push_:
                  lodsd
                  push eax
                  next
              
              add_:
                  pop eax
                  add [esp], eax
                  next
              
              ; пример пожпрограссы в бакоде (PUSH_, ADD_, EXIT это сами байткоды
              my_sub:
                  db PUSH_
                  dd 2
                  db PUSH_
                  dd 2
                  db ADD_, EXIT
              Как видно интерпретатор байткода сложнее чем у прямого или косвенного шитого кода, ему требуется дополнительная память для таблицы. Но его главное преимущество в том, что сам сконпелированный ьайткод лучше переносим чем шитый код.

              У меня усё.
              Ответить
              • Интересная как у вас беседа, правда кажется что твой собеседник ничерта не понимает.

                А я так понял из твоего объяснения что шитый код довольно сильно привязан к рахитектуре и нихуя не переносим. Чем же он тогда лучше чем обычная компиляция?

                Только тем что "генерацию" шитого кода (кстати, а почему он так назван?) можно отвязать его "интерпретатора" (который на самом деле постамбула)
                Ответить
                • Он проще компиляции. И не требует RWX памяти для генерации на лету. Ебашишь адреса функций в массив да и всё.
                  Ответить
                  • А ещё шитый код легко декомпилировать, почти один в один получается ( так, кстати обычно работает ' SEE в S" Forth" )
                    Ответить
                  • Кстати, только косвенный не требует RWX памяти, в остальных видах присутствуют машкоды.
                    Ответить
                • Косвеный шитый код можно переносить, но это сложнее чем переносить баткод, надо генерить объектный файл, а потом с ним линковатся. А форт язык простой и компилица быстро, в нём обычно всё в исходниках хранится/переносица и объектные файлы не нужны.
                  Ответить
                  • а если я написал проприетраный софт на форте ине хочу отдавать его исходник?
                    Ответить
                    • Там обычно всё в исходниках, даже части самой системы могут в исходниках хранится.
                      Если сильно хочеца генерь образ для gforth или просто бинарник. Вот только деконпелируется он просто, надо брать систему которая умеет в нативный код и оптимизации (типа SP-FORTH).
                      Ответить
                • А ещё на декодирование одной инструкции шитого кода нужно меньше операций чем на один байткод.
                  Ответить
                • Вот кстати годная статья по шитому коду:
                  http://www.complang.tuwien.ac.at/forth/threaded-code.html
                  там есть примеры переносимых реализаций интерпретаторов, по ним кстати видно какая сишка убогая при своей-то низкоуровневости.

                  А вот бенчмарк разных техник интерпретации шитого кода:
                  http://www.complang.tuwien.ac.at/forth/threading/Во многих случаях обычно быстрее прямой. Баткода там, к сожалению нет, но наверное за него можно считать switch threading.
                  Ответить
              • питух, я все равно не понимаю как шитокод может быть переносимым.

                Даже если там не
                call 123 а просто 123: у одного проца адреса выравниваются так, у дргого этак.

                шитокод надо гегенинирить под каждую платхорму отдельно.

                или это ок? или это как .pyc для питона: генерится чисто для скорости, а переносица все равно сырцы?

                то-есть как у джавоклассов: compile once, test run everywhere не полу?
                Ответить
                • > как шитокод может быть переносимым.
                  Токены можно легко переносить, а чтоб перенести косвенный шиткод надо генерить объектные файлы, и при загрузке просто подправить нужные адреса. Из форт-систем я знаю, что только GForth умеет делать переносимые образы:
                  http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Fully-Relocatable-Image-Files.html#Fully-Relocatable-Image-Files
                  На счёт других языков конпилирующихся в шиткоды я не знаю.

                  Кстати, прямой шиткод тоже можно переносить как косвенный, надо просто в начале всех определений ещё вставить платформо-специфичный кусочек.

                  > генерится чисто для скорости, а переносица все равно сырцы?
                  Тип того, в стандарте нет ничего про перенос сконпелированых программ, в каждой системе может быть по своему, а миожет и вообще не быть. А ещё шиткод может выигрывать по размеру у нативного, в какои-нибудь зачуханом контроллере это может оч важно.

                  > compile once, run everywhere не полу?
                  Token threading
                  Ответить
                  • а мне понравился подход когда парсер сохраняет AST дерево в удобном формате.
                    много времени тратится на парсинг, и его результаты жалко терять.

                    Это конечно не так быстро работаит, но можно джытнуть. Но джиту же нужно сначала сипать в страницу а потом выключать ей w и включать x, да?
                    Ответить
                  • > шиткод может выигрывать по размеру у нативного, в какои-нибудь зачуханом

                    это когда вместо

                    call pituh
                    call pituh
                    call pituh

                    у меня просто
                    pituh
                    pituh
                    pituh
                    ?

                    я пока не очень понимаю как тут работает префетчер и декодер у cpu.. кажется что плохо работает.

                    в обычном коде пока вызыввают первого петуха, второй уже может с другой стнацуей вычисляться (привет мельтдаун)
                    а как быть с шитокодом? что же это, никакого спекулятивного выполнения, никакого мельдауна?
                    Ответить
                    • Ну там же есть кеш косвенных вызовов. Вспомнит, куда обычно с этой строки прыгали. Так что небольшие горячие циклы не должны прям сильно тупить. А для остального кода и пофиг.

                      З.Ы. Кстати поэтому косвенный jmp обычно в конце каждой примитивной команды накопипащен. А не один на всех.
                      Ответить
                • разговор действительно интересный, сразу видно, что нидлес умный
                  Ответить
          • lodsd это, конечно, быстро и коротко, но есть и минус: пропадает возможность юзать eax для вершины стека.
            Ответить

Добавить комментарий

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8