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

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
__declspec (naked) INT16U getWordOfCPUFlags(void)
{
	_asm
	{
		pushf;
		xor eax, eax;
		pop ax;
		ret;
	}
}

void setWordOfCPUFlags(const INT16U WordOfCPUFlag)
{
	_asm
	{
		push WordOfCPUFlag;
		popf;
	}
}

bool getCPUTraceFlag(void)
{
	return 0 != (getWordOfCPUFlags() & 0x100);
}

void setCPUTraceFlag(const bool CPUTraceFlag)
{
	const INT16U MaskOfTraceFlag=((INT16U)CPUTraceFlag)<<8;
	//setWordOfCPUFlags( (getWordOfCPUFlags() and ~MaskOfTraceFlag) ^ MaskOfTraceFlag);
	if(CPUTraceFlag)
		setWordOfCPUFlags( getWordOfCPUFlags() | MaskOfTraceFlag);
	else
		setWordOfCPUFlags( getWordOfCPUFlags() & ~MaskOfTraceFlag);
}

Видимо автору кода строка 29 показалась слишком сложной.

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

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

  • Кстати, я в этом коде видел много:
    xor eax, eax;
    mov ax, ...
    Толк от этой первой строки вообще есть какой?
    Ответить
    • Есть. Должно оптимизировать исполнение команд процессором.

      xor eax, eax устранит зависимость eax от состояния, в котором он находился в предыдущих командах. Поэтому процессор сможет выполнить эти 2 команды, и ,возможно, следующую, не дожидаясь выполнения предыдущих команд, юзавших eax.
      Ответить
      • >xor eax, eax устранит зависимость eax от состояния
        mov eax, 0;
        mov ax, ...
        А так устраняется?
        Ответить
        • По идее да, но это 5 байт. xor короче.
          UPD: а зачем? Тогда уж лучше один mov eax, ... оставить.
          Ответить
      • >xor eax, eax устранит зависимость eax от состояния
        Откуда зависимость появляется в mov ax, ... ? После mov ax, ... старшая часть eax вроде же все равно обнуляется?
        Ответить
        • Пруф:
          $ cat 1.c
          #include <stdio.h>
          int result;
          int main() {
              asm("movl $0xDEADBEEF, %eax");
              asm("movw $0x1234, %ax");
              asm("movl %eax, result");
              printf("%08X\n", result);
              return 0;
          }
          $ gcc -Wall -Wextra 1.c
          $ ./a.out 
          DEAD1234
          Ответить
        • Для этой цели, ЕМНИП, есть милое семейство команд movz*. Z, кажется, означает "занулить неиспользуемое".
          Ответить
          • Z в movzx вроде как zero расширение. А еще есть знакововое расширение movsx. Вот не помню, почему тогда используют трюк с xor перед mov. Видимо для совместимости с древними процами...
            Ответить
  • Кстати, короче, чем от автора написать можно?
    void setCPUTraceFlag(const bool CPUTraceFlag)
    {
    	const INT16U MaskOfTraceFlag=((INT16U)CPUTraceFlag)<<8;
    	setWordOfCPUFlags( (getWordOfCPUFlags() & ~MaskOfTraceFlag) ^ MaskOfTraceFlag);	
    }
    Ответить
    • > const bool
      Фу.

      Походу нет. Смотри:
      Если CPUTraceFlag == 0, то получаем set(get() & ~0) ^ 0 - т.е. ничего не изменится.
      Если же CPUTraceFlag == 1, то получаем set(get() & ~(1 << 8)) ^ (1 << 8), что установит бит.
      Ответить
    • Как-то так:
      void setCPUTraceFlag(const bool CPUTraceFlag)
      {
      	const INT16U MaskOfTraceFlag = 1 << 8;
      	if (CPUTraceFlag)
      		setWordOfCPUFlags(getWordOfCPUFlags() | MaskOfTraceFlag);
      	else
      		setWordOfCPUFlags(getWordOfCPUFlags() & ~MaskOfTraceFlag);
      }
      Ответить
  • alternative primary | alternative primary | alternative primary
    --------------------+---------------------+--------------------
       <%          {    |    and         &&   |    and_eq      &= 
       %>          }    |    bitor       |    |    or_eq       |= 
       <:          [    |    or          ||   |    xor_eq      ^=
       :>          ]    |    xor         ^    |    not         !
       %:          #    |    compl       ~    |    not_eq      !=
       %:%:        ##   |    bitand      &    |

    Дельфины какие-то приняли это в стандарт. 🙁
    Ответить
  • Вообще, когда я увидел этот код первый раз, то первая же мысль была: Автор кода считает AssemberGovno, боится его как огня и поэтому пишет достаточно низкоуровневые конструкции, удобно и кратко выражающиеся на ассемблере, на языке высокого уровня. Хорошо, что хоть не в ООП оформил это...
    Ответить
    • На самом деле вынос только необходимого минимума в ассемблерные функции, и реализация более высокоуровневого функционала уже на С имеет смысл.

      Но т.к. я не думаю, что автор кода будет менять какие-то биты кроме трейс флага, то вполне можно было сделать что-то типа
      void setTraceFlag(bool flag) {
          if (flag) {
              _asm {
                  pushf
                  or word ptr [esp], 0x0100
                  popf
              }
          } else {
              _asm {
                  pushf
                  and word ptr [esp], 0xFEFF
                  popf
              }
          }
      }
      Ответить
  • - Руслан, у меня проблемы. Нас, похоже, нашли.
    Ответить

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

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

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


    8