пусть число a - количество элементов в массиве b - отрицательное число, абсолютное значение которого означает сколько в массиве отрицательных чисел. Мы должны вернуть через a 0 если отрицательных и положительных чисел поровну 1 если больше отрицательных чисел 2 если больше положительных. Пример: 1) a = 21 b = -7 тогда отрицательных 7 и положительных 14 мы возвращаем a = 2 2) a = 10 b = -5 мы возвращаем а = 0 3) a = 15 b = -10 мы возвращаем 1 Оптимизация по размеру. Безбранчевый код. Операнды целочисленные 32х разрядные.
ну давайте я дам для затравки какой-нить простой вариант. например: Код (Text): ; a = eax ; b = ebx ;строим по флагам результата ? a - |2b| shl ebx,1 add eax,ebx lahf shr eax,14 add eax,3 and eax,3 shr eax,1 adc eax,0
Код (Text): ; a = eax ; b = ebx lea eax, [eax+ebx*2] xor ebx, ebx neg eax adc ebx, 0 shl eax, 1 adc ebx, 0 xchg eax, ebx на 3 байта короче, и вроде правильно
Если поменять {0, 1, 2} на {0, -1, 1}, то укладывается в 10 байт и не затирается ebx: Код (Text): add eax,ebx add eax,ebx cdq neg eax adc edx,edx xchg eax,edx Добавил: lea eax,[eax+ebx*2] на 1 байт короче 2х add.
eax<-a, ebx<-b, ecx<-0, в cl - результат. Я понимаю, что написано криво (нет практики), но просто надоело уже проходить мимо...мне итак это далось с большими мучениями Код (Text): add eax,ebx neg ebx cmp eax,ebx lahf mov ch,ah shr cx,14 xor cl,00000010b sub cl,2 lahf mov ch,ah shr cx,14
Если еще немножко дооптимизировать по размеру, ; a = eax ; b = ebx lea ebx, [eax+ebx*2] xor eax, eax neg ebx adc eax, eax shl ebx, 1 adc eax, 0 то можно сэкономить еще 2 байта. Один на adc, второй на xchg.
your_enemy Чушь. Пиши и не думай о такой фигне Чем больше материала почитать\понять\посчитать - тем лучше.
Та я знаю что автор специально подобрал такие коэффициенты, чтобы нельзя было просто решить, но мне тоже надоело проходить мимо А то потом придёт BlackMirror и постить что-либо после него смысла уже не будет ЗЫ: А что если сделать отдельную задачу: {0, 1, 2} преобразовать в {0, -1, 1} и/или обратно?
Вообще-то задачки я даю как кусочки из реальной практики. Т.е. можно быть уверенным что где-то именно нужно было получить 0,1,2 и изменение на 0,-1,1 привело бы к резкому ухудшению по всему связанному с этим значением коду. Другое дело, что в практике встречаются просто тысячи задач, я стараюсь выбирать то, что поинтересней и можно выделить не задумываясь об окружении. А насчёт Чёрного Зеркала, его боятся нечего - думаю, что он сам внимательно просматривает код и подмечает для себя интересные приёмы \ закономерности. Чего вобщем нам всем стоит придерживаться. Единственный смысл - разобраться в задачах повнимательней и поучится друг у друга. Я так думаю.
Мне почему-то кажется что из этих 12 байт как минимум один лишний, только я его еще не нашел. Код (Text): lea eax,[eax+ebx*2] neg eax cdq sbb edx,0 neg edx xchg eax,edx
На всякий случай выложу ещё один вариант. Попытался решить другим путём, но размер получился 14 байт: Код (Text): lea edx,[eax+ebx*2] xor eax,eax neg edx adc eax,eax shl edx,1 adc eax,0
Молодец,leo Я почему то думал, что этот приём (cdq,cmp edx,eax) будет использовать Black_mirror. В предыдущих задачах он использовался очень элегантно.
The Svin Тут наверное, дело не столько в cdq+cmp, т.к. это лишь способ установки CF при eax > 0 и использовать его можно по разному. Возможно мы просто увлеклись использованием adc\sbb и стали забывать о существовании rcr\rcl и lahf\pushfd (может и bt пригодились бы, только размерчик великоват . А в данном случае как раз rcr неплохо вписалась в сочетании с элегантным приемчиком c cdq+cmp. Где-то возможно и lahf\pushfd "впишутся"