Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
что-то мне говорит что у тебя там в коде реальное спагетти топов данных с результирующими неявными конвертациями - которые в асме становятся явными. и если это так, то я думаю что компилер сгенерил код подобающий тому что ты написал. например факт того что port был сконвертирован в 32бит число, наталкивает на мысли.
О да, "преждевременная оптимизация", как любят этот лозунг везде пихать.
Алё, автор работает с портами и хочет иметь компактный код, дрова походу пишет, какая нахрен преждевременная оптимизация?
Красава 🙂 Измерять размер кода в строках исходника - это новое слово в программировании.
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).
Вероятно, для хранения переменных половинки регистров он выделять не умеет, хотя для промежуточных вычислений — запросто. Может быть, просто страховка?
что-то мне говорит что у тебя там в коде реальное спагетти топов данных с результирующими неявными конвертациями - которые в асме становятся явными. и если это так, то я думаю что компилер сгенерил код подобающий тому что ты написал. например факт того что port был сконвертирован в 32бит число, наталкивает на мысли.
Что тебя смущает? Использование лишнего регистра АХ? Это не стоит того, чтобы постить такой код сюда.
Почти ровно в два раза короче и без тормозных префиксов.
> inc ebx
LOL`D
Попробуй вот так:
Минус две ненужных строки.
Алё, автор работает с портами и хочет иметь компактный код, дрова походу пишет, какая нахрен преждевременная оптимизация?
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 что угодно, только не адрес порта.
И это на пять строк кода. Страшно представить, что было бы, дай тебе задание написать код на десяток-другой тысченок строк 😀
Насчёт переходов и лишнего регистра полностью согласен, можно и сократить. А вот movzx ebx,... и push ebx нужно переставить, иначе в стеке будет не то, что ожидалось.
Push и movzx перепутал уже при копипасте, здесь окошко маленькое и плохо видно код.
Вероятно, для хранения переменных половинки регистров он выделять не умеет, хотя для промежуточных вычислений — запросто. Может быть, просто страховка?