Сборный / Говнокод #7313 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
cmp     DWORD PTR [esi+4], 0     ; if obj->curChip == 0
    push    ebx
    push    edi
    jne     SHORT <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0a2e4644324a626b786e6e6f7e6f697e">[email protected]</a>
    movzx   ebx, WORD PTR [esi+12]   ; ebx = obj->baseport;
    jmp     SHORT <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="20046c6e196048415244444554454354">[email protected]</a>
<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4b6f0705730b232a392f2f2e3f2e283f">[email protected]</a>:
    mov     ax, WORD PTR [esi+12]    ;\
    add     ax, 2                    ; шедевр!
    movzx   ebx, ax                  ;/
<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f8dcb4b6c1b890998a9c9c9d8c9d9b8c">[email protected]</a>:

Не понравился размер кода после компиляции. Полез посмотреть. Особо забавной показалась скомпилированная незатейливая конструкция:

unsigned short port = (curChip == 0 ? baseport : baseport + 2);

Компилятор VC++ 2005, с оптимизацией по размеру генерируемого кода. Наоптимизировал :D

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

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

  • > Наоптимизировал 😀

    что-то мне говорит что у тебя там в коде реальное спагетти топов данных с результирующими неявными конвертациями - которые в асме становятся явными. и если это так, то я думаю что компилер сгенерил код подобающий тому что ты написал. например факт того что port был сконвертирован в 32бит число, наталкивает на мысли.
    Ответить
    • Нет там никакой принудительной конвертации, все это самодеятельность компилятора.
      Ответить
      • присвоение переменной одного типа переменной другого типа == неявное преобразование типов. таже херня с выражениями.
        Ответить
  • DemonId7
    Что тебя смущает? Использование лишнего регистра АХ? Это не стоит того, чтобы постить такой код сюда.
    Ответить
    • Лишнего? Две лишние 16-ти битные команды, плюс два ненужных префикса изменения разрядности команд, плюс лишний джамп. И это на пару строк кода:
      movzx   ebx, WORD PTR [esi+12]
          cmp     DWORD PTR [esi+4], 0
          push    ebx
          push    edi
          je      SHORT $LN8@harddetect
          inc     ebx
          inc     ebx
      $LN8@harddetect:

      Почти ровно в два раза короче и без тормозных префиксов.
      Ответить
      • > inc ebx
        > inc ebx
        LOL`D
        Попробуй вот так:
        cmp     DWORD PTR [esi+4], 0
            push    WORD PTR [esi+12]
            push    edi
            je         SHORT $LN8@harddetect
           add WORD PTR [esi+12], 2
        $LN8@harddetect:

        Минус две ненужных строки.
        Ответить
        • Красава 🙂 Измерять размер кода в строках исходника - это новое слово в программировании.
          1) "push word ptr [esi+12]" - по размеру соответствует двум командам "push ebx \ movzx ebx, [esi+12]", а в дальнейшем использование ebx, вместо значения на стэке, куда как компактнее и шустрее.
          2) портить выравнивание стэка без крайней необходимости бывает иногда больно.
          3) "add word ptr [esi+12], 2" - занимает 4 байта + байт префикса. Итого 5 байт вместо 2-х ("inc ebx" - 1 байт).
          4) главное, изменяя непосредственно значение baseport (esi+12) после нескольких вызовов будешь иметь в baseport что угодно, только не адрес порта.
          И это на пять строк кода. Страшно представить, что было бы, дай тебе задание написать код на десяток-другой тысченок строк 😀
          Ответить
      • Этот код вовсе не экивалентен заявленному. Порт шестнадцатибитный, поэтому инкременировать нужно bx, а не ebx, иначе для входных значений 65535 и 65534 код будет работать неправильно.

        Насчёт переходов и лишнего регистра полностью согласен, можно и сократить. А вот movzx ebx,... и push ebx нужно переставить, иначе в стеке будет не то, что ожидалось.
        Ответить
        • Именно что порт 16-ти битный, потому в регистр DX запишутся лишь младшие 16-ть бит регистра EBX, отбросив ненужные старшие биты и получив корректное значение. Хотя согласен, компилятор мог этого и не учесть. А должен бы, ведь port явно записывается в DX.
          Push и movzx перепутал уже при копипасте, здесь окошко маленькое и плохо видно код.
          Ответить
          • Кстати, да. Если port имеет тип unsigned short, baseport того же типа, то непонятно, почему компилятор обнуляет старшую половину регистра ebx (не производя при этом таких же манипуляций с регистром eax, а просто используя ax).

            Вероятно, для хранения переменных половинки регистров он выделять не умеет, хотя для промежуточных вычислений — запросто. Может быть, просто страховка?
            Ответить
  • м,F.YH R I)O"YJ!Q G"DV$LA P H$O:QT"F(X(P:C.K$M:J)R"C)C(A.N?A,L$J)E!G)Q.V(O!H"P$C)R:V)K?E M.A L"A"JN O"G$IK.O)E.V?K"U?L"U.Q:G?Y"L,PF)X?Z?O)Q?H?ZO(Q"Z C,C$Q!M(Z.R(D,Z,J)Y:B(E S!E:E W(T"G"K?WH:Y.K(Q:A:A:K!P)MT"F!E?BL!N)K:N"G,XT:A)FZ?F"SS)Q.T(TЪNAQBXQCLHRPCWYXKFGSZUHBWEUQEXSSOFKLINBOTVSBAKJNYITNASCYEYIQUFMGELOODKZZLXEPORGLJDEYYOHRTLEUGQCOYFTUDPPHPYUXXWYTRQULVRJNJILXFNVYZCJFQYKAYOMTMDRPGLBSHXMRPGFRIRZEMNCWVSCH
    Ответить

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

Переведи на "PHP", guest!

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


    8