- 1
- 2
- 3
- 4
- 5
- 6
- 7
lea 0x0(%esi),%esi
sub $0x1,%eax
cmp $0xffffffff,%eax
je 0x8048e07
mov (%ecx,%eax,4),%esi
test %esi,%esi
je 0x8048df8
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+240
lea 0x0(%esi),%esi
sub $0x1,%eax
cmp $0xffffffff,%eax
je 0x8048e07
mov (%ecx,%eax,4),%esi
test %esi,%esi
je 0x8048df8
Чудеса оптимизации -О3 на gcc 4.4
(код в интелловской аннотации, сначала источник, потом назначение)
нет?
я писал на асме очень давно и в другом синтаксисе (это был масм кажется) и все уже забыл
http://www.codenet.ru/progr/asm/newbee/lesson8.php
"Ещё одна команда сравнения - test.Команда Test выполняет операцию AND (логическое И) с двумя операндами и в зависимости от результата устанавливает или сбрасывает соответствующие флаги. Результат не сохраняется. Test используется для проверки бит, например в регистре:
test eax, 100b
jnz смещение"
Короче, в данном случае сравнивает esi с нулём.
тогда логично)))
я с cmp грешным делом перепутал видимо
стыдно
что это? mov esi, esi?
> sub $0x1,%eax
> cmp $0xffffffff,%eax
какой понт сначала вычитать 1, а потом сравнивать с -1?
> sub $0x1,%eax
Мне одному кажется, что команда dec занимает меньше времени?
Да.
скорее всего по причине выравнивания команд перед условным переходом gcc решил выбрать sub.
По причине выравнивания же решено было выбрать пустой lea в качестве первой инструкции.
Если бы ты указал процессор не ниже i686, то получил бы многобайтный nop
Пусть у вас есть некий алгоритм, который следует по двум веткам. Ветка выбирается в зависимости от того, равен ли `eax` нулю. Но в начале каждой ветки вам, по стечению обстоятельств, надо вычесть единицу из `eax`. Тут сразу возникает два варианта:
Первый - реализовать все буквально: разбранчеваться по сравнению `eax` с нулем и начать каждую ветку с `dec eax`.
Второй - вынести декремент "за скобки": сначала сделать `dec eax`, затем разбранчеваться по сравнению `eax` с `-1`.
Какой вариант лучше - это уже вопрос логики, которой руководстуется компилятор и массы других факторов. В данном случае он, очевидно, решил пойти по второму пути. Вот и все.
Опять же, как я уже сказал выше, предварительный `dec` позволяет компилятору вынести эту операцию "за скобки", т.е. обойтись одной операцией на обе ветки, вместо того, чтобы писать отдельную операцию для каждой ветки.
и хватит уже засорять комментарии диакритическими символами, неудобно читать же.
А в остальном: все возможно. Я лишь привожу пример формальной логики, которой потенциально мог руководствоваться компилятор.
Она устанавливает ZF=1 если в результате отнимания получился 0.
это at&t, а не intel
>gcc 4.4
А минорную версию указывать не модно?
>Чудеса оптимизации -О3
-O3 воистину чудесно
gcc (GCC) 4.4.4 20100630 (Red Hat 4.4.4-10)
код сгененированый альфа пререлизом поинт-версии которую РедХат вытянул напрямую из сырцов GCC и послал своим пользователям без консультаций с GCC - не в счет. скажи спасибо что то что на твоей системе называется GCC вообще код генерирует.
Поэтому: Где, собственно, говнокод?