[abs(x)] Люди добрые подскажите плиз

Тема в разделе "WASM.BEGINNERS", создана пользователем devillsd, 5 янв 2009.

  1. devillsd

    devillsd New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2008
    Сообщения:
    131
    Собственно из темы видно, что нужно получить абсолютное значение числа на асме=)
    Заранее благодарен!
     
  2. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    1)
    fabs st(0)
    2)
    test eax,eax \ jns @f \ neg eax \ @@:
    3)
    ???
     
  3. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Очистить бит знака :)
     
  4. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    только для вещественных чисел
     
  5. devillsd

    devillsd New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2008
    Сообщения:
    131
    GoldFinch
    test eax,eax \ jns @f \ neg eax \ @@:
    Огромное спасибо, помогло....
    Сам пытался через макро средства .IF eax<NULL
    Поэтому ничего не выходило...
    А вот с проверкой флажка знака, всё вышло... спасибо ещё раз!!!
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Классика получения abs(eax) без усл.перехода:
    Код (Text):
    1. ;neg eax = (not eax)+1
    2. cdq
    3. xor eax,edx
    4. sub eax,edx
     
  7. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Вот ещё два примера из AMD мануал (Но IMHO код leo с использованием cdq лучше)
    Код (Text):
    1. MOV ECX, [X] ;load value
    2. MOV EBX, ECX ;save value
    3. NEG ECX ;–value
    4. CMOVS ECX, EBX ;if –value is negative, select value
    5. MOV [X], ECX
    А этот код совместим со старыми процессорами
    Код (Text):
    1. MOV    ECX, [X]    ;load value
    2. MOV    EBX, ECX    ;save value
    3. SAR    ECX, 31 ;x < 0 ? 0xffffffff : 0
    4. XOR    EBX, ECX    ;x < 0 ? ~x : x
    5. SUB    EBX, ECX    ;x < 0 ? (~x)+1 : x
    6. MOV    [X], EBX    ;x < 0 ? -x : x
     
  8. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.898
    На ту же тему
    Код (Text):
    1. a1: neg reg
    2.    js a1
    почти как у leo:)
    Код (Text):
    1. cdq
    2. add eax,edx
    3. xor eax,edx
     
  9. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
  10. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Mikl___
    Код (Text):
    1. a1: neg reg
    2. js a1
    Изящно.
     
  11. meduza

    meduza New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    212
    Код (Text):
    1. a1: neg reg
    2. js a1
    Старый приём, он приводится еще в Зубковсом учебнике. Это самый короткий способ получить abs, но к сожалению, далеко не самый быстрый.
     
  12. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.898
    Та же тема :)
    Код (Text):
    1. ; 1-ый вариант
    2. cdq
    3. mov ebx,eax
    4. add ebx,ebx
    5. and ebx,edx
    6. sub eax,ebx
    7. ; 2-ой вариант
    8. cdq
    9. or edx,1
    10. imul edx
     
  13. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.898
    Небольшой подводный камень, который нужно учитывать при получении модуля -- если при работе с байтами/ словами/ двойными словами вам по­падет число 80h/ 8000h/ 80000000h -- тогда все вышеперечисленные варианты получения модуля, кроме варианта с умножением, где произойдет знако­вое расширение числа на два регистра (al-->ax, ax-->dx:ax, eax-->edx:eax), приведут к появлению в качестве модуля числа 80h/ 8000h/ 80000000h с установкой фла­гов SF=1 и OF=1, что в варианте с neg/js приведет к зацик­ливанию, а остальные вари­анты выдадут неправильный модуль. Отсюда мораль -- либо перед вы­числением модуля делать проверку на наличие такого числа, либо предварительно делать знаковое расширение, либо об­рабатывть появ­ление флага OF, либо, если точность вычисления позволя­ет, а знаковое расширение сделать не­льзя -- увеличить число 80h/ 8000h/ 80000000h на единицу. Если проверка не делается, тогда замените сочета­ние neg/js на neg/jl -- ко­манда jl осуще­ствит переход только при SF=1 и OF=0. Хотя команда jl может сработать при сочетании SF=0 и OF=1, но после neg такой комби­нации флагов не бывает.
     
  14. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    поскольку +-2147483648 это предел дипазона знаковых вычислений, то такое поведение алгоритма и есть обычное переполнение ;) а произойдёт оно на 1 раньше или позже имхо филетово :) а зацикливание варианта с jcc это хорошо ;) не нужен тут условный переход раз есть красивая альтернатива.
     
  15. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.898
    Y_Mur
    Я же как лучше хотел :)
     
  16. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    Mikl___
    Вариант, приведеный leo выдает правильный модуль, если результат рассматривать как unsigned.
     
  17. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.898
    Шутите? |-2147483648|=-2147483648 правильно?
    Ну тогда и остальные выдают правильный модуль, только о каком модуле можно говорить, если число рассматривается как unsigned?
     
  18. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Mikl_
    Для перевода 80..0 в 7F..F можно добавить к варианту с cdq еще пару строчек:
    Код (Text):
    1. cdq
    2. xor eax,edx
    3. sub eax,edx
    4. cdq
    5. xor eax,edx ;или add eax,edx
     
  19. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    Mikl___
    не все.

    а чем по-вашему signed отличается от unsigned?

    leo
    А по-моему еще хуже будет. |-2147483648| = 2147483647 ?
     
  20. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.898
    Тем, что в signed старший бит рассматривается как знак (0="+", 1="-"), и если число положительное -- тогда оно в прямом, а если отрицательное -- в дополнительном коде. А unsigned -- это всегда положительное число в прямом коде, старший бит в unsigned не знак, а старший бит числа