- 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
(код в интелловской аннотации, сначала источник, потом назначение)
Анонимус 17.03.2011 15:11 # 0
TarasB 17.03.2011 15:56 # 0
Анонимус 17.03.2011 16:18 # 0
нет?
я писал на асме очень давно и в другом синтаксисе (это был масм кажется) и все уже забыл
TarasB 17.03.2011 16:37 # +2
http://www.codenet.ru/progr/asm/newbee/lesson8.php
"Ещё одна команда сравнения - test.Команда Test выполняет операцию AND (логическое И) с двумя операндами и в зависимости от результата устанавливает или сбрасывает соответствующие флаги. Результат не сохраняется. Test используется для проверки бит, например в регистре:
test eax, 100b
jnz смещение"
Короче, в данном случае сравнивает esi с нулём.
Анонимус 17.03.2011 16:40 # 0
тогда логично)))
я с cmp грешным делом перепутал видимо
стыдно
TarasB 17.03.2011 15:55 # 0
что это? mov esi, esi?
> sub $0x1,%eax
> cmp $0xffffffff,%eax
какой понт сначала вычитать 1, а потом сравнивать с -1?
SIGSEGV 17.03.2011 17:33 # 0
> sub $0x1,%eax
Мне одному кажется, что команда dec занимает меньше времени?
TarasB 17.03.2011 17:43 # 0
Да.
wecanstoptrain 17.03.2011 18:40 # 0
скорее всего по причине выравнивания команд перед условным переходом gcc решил выбрать sub.
По причине выравнивания же решено было выбрать пустой lea в качестве первой инструкции.
Если бы ты указал процессор не ниже i686, то получил бы многобайтный nop
guest 26.04.2011 23:34 # 0
guest 26.04.2011 23:36 # 0
TheCalligrapher 19.03.2011 22:24 # +2
Пусть у вас есть некий алгоритм, который следует по двум веткам. Ветка выбирается в зависимости от того, равен ли `eax` нулю. Но в начале каждой ветки вам, по стечению обстоятельств, надо вычесть единицу из `eax`. Тут сразу возникает два варианта:
Первый - реализовать все буквально: разбранчеваться по сравнению `eax` с нулем и начать каждую ветку с `dec eax`.
Второй - вынести декремент "за скобки": сначала сделать `dec eax`, затем разбранчеваться по сравнению `eax` с `-1`.
Какой вариант лучше - это уже вопрос логики, которой руководстуется компилятор и массы других факторов. В данном случае он, очевидно, решил пойти по второму пути. Вот и все.
bugmenot 19.03.2011 22:38 # +1
TheCalligrapher 19.03.2011 22:52 # +1
Опять же, как я уже сказал выше, предварительный `dec` позволяет компилятору вынести эту операцию "за скобки", т.е. обойтись одной операцией на обе ветки, вместо того, чтобы писать отдельную операцию для каждой ветки.
bugmenot 20.03.2011 01:26 # 0
и хватит уже засорять комментарии диакритическими символами, неудобно читать же.
TheCalligrapher 20.03.2011 06:36 # 0
А в остальном: все возможно. Я лишь привожу пример формальной логики, которой потенциально мог руководствоваться компилятор.
SIGSEGV 30.03.2011 19:25 # +1
Она устанавливает ZF=1 если в результате отнимания получился 0.
guest 26.04.2011 23:43 # 0
rat4 17.03.2011 19:17 # +4
это at&t, а не intel
>gcc 4.4
А минорную версию указывать не модно?
>Чудеса оптимизации -О3
-O3 воистину чудесно
SIGSEGV 18.03.2011 12:38 # 0
gcc (GCC) 4.4.4 20100630 (Red Hat 4.4.4-10)
Dummy00001 18.03.2011 13:56 # 0
код сгененированый альфа пререлизом поинт-версии которую РедХат вытянул напрямую из сырцов GCC и послал своим пользователям без консультаций с GCC - не в счет. скажи спасибо что то что на твоей системе называется GCC вообще код генерирует.
Dummy00001 17.03.2011 23:54 # 0
rat4 18.03.2011 08:09 # 0
Dummy00001 18.03.2011 13:52 # +3
guest 26.04.2011 23:28 # 0
assa 15.04.2011 14:21 # 0
guest 26.04.2011 23:54 # 0
Поэтому: Где, собственно, говнокод?