Мелкие задачки для крупных мозгов №18

Тема в разделе "WASM.A&O", создана пользователем The Svin, 2 май 2006.

  1. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Задачка под №16 расширяется одним любопытным условием:

    eax должен на выходе содержать своё абсолютное значение.

    Остальные условия те же. Безбранчевый код. Оптимизация по размеру.

    Специфика задачи (её что ли академический смысл) в том чтобы увязать промежуточные результаты которые получаются в при алгоритме в №16 для решения дополнительной задачи, а не вставка просто дополнительного кода.

    Например -a в одном из вариантов может быть представлена как not(a)+1. При этом известно что xor a,1...1 = not(a)

    а xor a,0...0 = a

    так что если к примеру в edx 1..1 или 0..0

    то соответсвенно

    xor eax,edx

    sar edx,1

    adc eax,0

    приведёт к neg eax в случае edx=1..1 и не изменит eax если edx = 0..0

    Это просто пример. Решений может быть очень много.

    Главное увязать дополнительную задачу с тем что уже "под рукой" не испортив эффективность решения основной задачи.

    Так как -а может быть получено десятками способов

    Например not(a-1) и т.п
     
  2. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Возможно не до конца понятна задача.

    Вот есть например замечательный код Чёрного Зеркала
    Код (Text):
    1.  
    2. cdq;-1,0
    3. cmp edx,eax     ;eax=0 CF=0,eax<0 CF=0 ,eax > 0 CF=1
    4. adc edx,edx;eax=0 edx=0, eax < 0 edx=-2, eax > 0 edx=1
    5. lea ecx,[edx*8+$2D2B2008] ;eax=0 cl=8+0=8, eax < 0 8+-16= -8 =11000 = 24;eax>0 cl=8+8=16
    6. shr ecx,cl
    7.  


    Можно дополнить его не самым коротким вариантом из трёх инструкций 8 байт чтобы получить модуль eax
    Код (Text):
    1.  
    2. cdq;-1,0
    3. cmp edx,eax     ;eax=0 CF=0,eax<0 CF=0 ,eax > 0 CF=1
    4. adc edx,edx;eax=0 edx=0, eax < 0 edx=-2, eax > 0 edx=1
    5. lea ecx,[edx*8+$2D2B2008] ;eax=0 cl=8+0=8, eax < 0 8+-16= -8 =11000 = 24;eax>0 cl=8+8=16
    6. shr ecx,cl
    7.  
    8. sar edx,2 ;eax < 0 edx=1...1 CF=1 ;eax >= 0 edx = 0 CF = 0
    9. sbb eax,0 ;eax < 0 eax -1 ;eax >= 0 eax = eax
    10. xor eax,edx ;eax < 0 not(eax -1) ; eax > 0 eax = eax
    11.  


    можно другой вариант окончания.

    sar edx,1 ;edx = -1 eax < 0 ; edx = 0 eax >= 0

    add eax,edx ;eax -1 eax < 0 ;eax = eax eax >=0

    xor eax,edx ;eax = not(eax-1) eax<0; eax=eax eax>=0

    он будет на два байта покороче

    Но вероятно возможны варианты и с двумя инструкциями ;)

    Жду ваших предложений.
     
  3. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035


    Достаточно добавить 1.5 инструкции:
    Код (Text):
    1.     cdq
    2.     cmp edx,eax    
    3.     adc edx,0
    4.     lea ecx,[edx*8+$2B202D10]
    5.     shr ecx,cl
    6.     imul edx
     
  4. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Убил наповал! Есть идеи без imul?
     
  5. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    The Svin

    > "а не вставка просто дополнительного кода"

    > "вероятно возможны варианты и с двумя инструкциями"

    Не знаю, что ты имел ввиду под дополнительным кодом, но в 2 инструкции задачка просто решается вставкой
    Код (Text):
    1.   xor eax,edx
    2.   sub eax,edx
    сразу после cdq, т.к. изменение знака eax не влияет на CF при cmp edx,eax
     
  6. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia


    Контексто-независимый код. Ну снипет что-ли, код который не привязан к особенностям\состояниям окружения вне его(значениям регистров, состоянию флагов и т.п.)leo Молоток! Замечательно "увязанное" решение.