Говнокод неизбежен
От: кт  
Дата: 27.01.18 15:11
Оценка: 1 (1) -3 :)
Потребовалось недавно проанализировать одну DLL. Нужно было найти какие биты устанавливаются/сбрасываются при управлении конкретным USB-устройством. Исходный текст (cpp) и документация были недоступны, но поскольку данная DLL была небольшая – дисассемблировали ее и довольно быстро все нашли.
Но какой же говкокод там во всех операторах!

Вот типичный пример:
PUSH   EBP
MOV    EBP,ESP
PUSH   ECX
MOV    [EBP]-4,ECX
MOV    ECX,[EBP]-4
ADD    ECX,0000000C
CALL   100188A0
MOV    ESP,EBP
POP    EBP
RET

И после этого утверждают, что трансляторы программируют лучше человека? Не задумываясь, программист написал бы весь этот фрагмент двумя командами:
ADD    ECX,0000000C
JMP    100188A0

Или вот картиночка, достойная пера:
…
FST32P [EBP]-0C
FLD32  [EBP]-0C
MOV    ESP,EBP
POP    EBP
RET

Здесь извлекается из FPU результат в локальную переменную, которая двумя строками ниже уничтожается. Но ничего страшного, командой FLD, следующей сразу за FST, статус-кво восстанавливается и в FPU опять загружается только что выгруженное значение. После такой толчеи воды в ступе состояние системы остается прежним. Прекрасно с точки зрения производительности!

Ну и наконец, вишенка на тортике.
Вот тот самый найденный фрагмент, устанавливающий и сбрасывающий биты в управляющем слове:
…
MOV    EDX,[EBP]+FFFFFFEC
OR     EDX,00000001
MOV    [EBP]+FFFFFFEC,EDX
MOV    EAX,[EBP]+FFFFFFEC
AND    EAX,FFFFFFFD
MOV    [EBP]+FFFFFFEC,EAX
MOV    ECX,[EBP]+FFFFFFEC
AND    ECX,FFFFFFFB
MOV    [EBP]+FFFFFFEC,ECX
MOV    EDX,[EBP]+FFFFFFEC
AND    EDX,FFFFFFF7
MOV    [EBP]+FFFFFFEC,EDX
MOV    EAX,[EBP]+FFFFFFEC
AND    EAX,FFFFFFCF
MOV    [EBP]+FFFFFFEC,EAX
MOV    ECX,[EBP]+FFFFFFEC
AND    ECX,FFFFFFBF
MOV    [EBP]+FFFFFFEC,ECX
MOV    EDX,[EBP]+FFFFFFEC
AND    EDX,FFFFFF7F
MOV    [EBP]+FFFFFFEC,EDX
MOV    EAX,[EBP]+FFFFFFEC
AND    EAX,FFFFFBFF
MOV    [EBP]+FFFFFFEC,EAX
MOV    ECX,[EBP]+FFFFFFEC
AND    ECX,FFFFF7FF
MOV    [EBP]+FFFFFFEC,ECX
MOV    EDX,[EBP]+FFFFFFEC
AND    EDX,FFFFCFFF
MOV    [EBP]+FFFFFFEC,EDX
MOV    EAX,[EBP]+FFFFFFEC
AND    EAX,FFFFBFFF
MOV    [EBP]+FFFFFFEC,EAX
MOV    ECX,[EBP]+FFFFFFEC
AND    ECX,FFFFFDFF
MOV    [EBP]+FFFFFFEC,ECX
MOV    EDX,[EBP]+FFFFFFEC
AND    EDX,FFFFFEFF
MOV    [EBP]+FFFFFFEC,EDX
…

Шикарный код! Напоминает работу машины Тьюринга, не правда ли?
Не то, что жалкий код типа,
AND D PTR [EBP]+FFFFFFEC,1111 1111 1111 1111 1000 0000 0000 0001
OR D PTR [EBP]+FFFFFFEC,1

Который, правда, делает то же самое. Здесь, уже не только транслятор виноват, но и отсутствие нормальных битовых строк. В некоторых языках (не будем указывать пальцем в каких) это делается не операторами сдвига, а напрямую:
X=X &’1111 1111 1111 1111 1000 0000 0000 0001’B ! ’1’B;

И подобных мест полно в обычной программе, оттранслированной обычными средствами.
Так что, что бы вы ни делали, в ваших программах всегда полно говнокода.
А где же оптимизатор? Сразу на ум приходит Герцог из к/ф «Тот самый Мюнхгаузен» со своим вопросом: «А где же командующий?». Ответ, помнится, был – «командует». Так и здесь ответ: «оптимизирует»
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.