nasm и mmx . как сравнить числа?

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

  1. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Подскажите пожалуйста =)
    как работать с mmx в компиляторе nasm ..
    загружать числа вот так
    movq mm0, number_1 ; загружаем в mm number (а может и не намбер..просто байты)
    movq mm1, number_2 ; в регистр mmx(1) записали number_2 размерности в 64 разряда
    (оба числа, 64 битные )
    Как сравнить эти два числа? пожалуйста пример кода ))))
    и как воспользоваться в ЦП результатом этого сравнения....
    (команды сравнения не оказывают воздействия на флаги ЦП)
    результат формируется в регистре приёмнике...если верно..то биты взводятся в 111111111.... если ложь то в 00000.....
     
  2. meduza

    meduza New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    212
    stellaco
    Работа с mmx в nasm мало чем отличается от работой с mmx в других ассемблерах. Не забывай про прекрасную официальную документацию (nasmdoc).
    pcmpXXX
    Лучше не таскай по кускам знания, а почитай какой-нибудь учебник по mmx. В Зубкове есть глава, посвещенная mmx. Еще Intel както выпустила учебник mmx для самых маленьких (а-ля для чайников), называется "Введение в технологию mmx", в гугле, я думаю, найти можно.
     
  3. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
  4. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Да литературы у меня полно... да и знаний в теории...
    вот практикуюсь..и как что-то не понимаю..задаю вопрос на форуме =) (а то на мелкие проблемы...уходят дни)

    вот тут
    movq mm0, [number_1] ; загружаем в mm введённое число
    movq mm1, [number_2]
    pcmpeqd mm0, mm1 ; сравниваем на больше ( n1 > n2 ?? )
    movq qword[res_mmx], mm0 ; записываем либо.. 111... либо 00.... в res_mmx (если 1111111 то верно...если 000 то не верно)
    ; если истина, то в mm0 то младшие байты ffh если не равны то 00h
    cmp dword[res_mmx],0xffffffff
    je ravno

    Что тут не верно??....
     
  5. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Тут не верна сама идея.
    Тебе же говорят почитай мануалы.
    Ты таким сравнением убиваеш весь выигрыш от использования MMX, т.к. векторные операции в конце концов сводиш к скалярным.
    Если хочеш увидеть о чём я - напиши функцию ABS(), а я потом свой вариант покажу.
    Дано - в MM0 два упакованных DWORD'а.
    Требуется - в любом MMX регистре вернуть модуль каждого дворда.
    Т.е. было
    MM0: DWORD_2 DWORD_1
    требуется
    MMX: ABS(DWORD_2) ABS(DWORD_1)
    Поехали :)
     
  6. Maratyszcza

    Maratyszcza New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    32
    Если ты пишешь алгоритм под MMX/SSE/AVX, следует использовать эти команды для всего алгоритма. Команды PCMPxx устанавливают биты первого операнда в 0 либо 1 в зависимости от результата сравнения. Затем ты можешь воспользоваться командой PAND, чтобы, если сравнение прошло успешно, получить в регистре вместо всех единиц любое нужно тебе число:
    Код (Text):
    1. C++:
    2. Int32 doz( Int32 a, Int32 b ) {
    3.     if( a > b ) return a - b;
    4.     else return 0;
    5. }
    6.  
    7. MMX Asm (реализация неоптимальна, но принцип показывает):
    8.     MOVQ mm0, a
    9.     MOVQ mm1, b
    10.     MOVQ mm2, mm0 ; mm2 = mm0 = a
    11.     PSUBD mm2, mm1 ; mm2 = a - b
    12.     PCMPGTD mm0, mm1 ; mm0 = a > b ? 0xFFFFFFFFFFFFFFFF : 0x0000000000000000;
    13.     PAND mm2, mm0 ; mm2 = a > b ? a - b : 0;
     
  7. meduza

    meduza New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    212
    stellaco
    Ты хочешь сравнить 2 qword'a? Тогда последние команды у тебя надо заменить:
    Код (Text):
    1. cmp byte [res_mmx],0
    2. jz not_equal
    3. cmp byte [res_mmx+4],0
    4. jz not_equal
    т.к. pcmpeqd сравнивает отдельно младшие и старшие половинки mmx-регистров.
    А вообще, для этой цели (сравнить 2 qword в памяти) лучше не лезть в mmx:
    Код (Text):
    1. mov eax,[number_1]
    2. cmp [number_2],eax
    3. jnz not_equal
    4. mov eax,[number_1+4]
    5. cmp [number_2+4],eax
    6. jnz not_equal
    п.с. прислушайся к cppasm:
     
  8. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    мои познания к сожалению весьма слабы, чтоб соревноваться)

    meduza
    Мне надо сделать сравнение не на равно..а на большее.
    узнать... первое 64 битное число..больше второго 64 битного..или нет...
    я второй день с этим сижу..всё никак ((
     
  9. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    stellaco
    если устраивает раздельное сравнение, то сначала старшие dword, если больше или меньше, то младшие не трогаешь, а если равны тогда сравниваешь младшие и всё ;)
     
  10. meduza

    meduza New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    212
    pcmpgtd, но опять же, в mmx лучше не лезть, а сделать простой проверкой по dword'ам.
     
  11. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Y_Mur
    meduza
    Спасибо.
     
  12. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Ну тогда просто так моё решение :)
    Основано на том что -X = Инверсия(X)+1

    Код (Text):
    1. ; mm0 - input data
    2. pxor    mm1,mm1   ; mm1 = 00000000 000000000
    3. pcmpgtd mm1,mm0   ; mm1 = FFFFFFFF для dword в mm0 < 0, 00000000 для положительных
    4. pxor    mm0,mm1   ; инверсия отрицательных
    5. psubd   mm0,mm1   ; прибавление единицы к бывшим отрицательным
    Суть в том что вместо ветвлений тебе надо придумать некоторую логическую функцию дающую аналогичный результат.
     
  13. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
  14. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    murder наверное хотел сказать что paddd надо? :)
     
  15. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    cppasm
    Нет просто ты меня опередил с abs

    stellaco
    Может PMAXSW mm, mm/m подойдёт?
     
  16. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    murder
    Тут подойдёт практически всё .
    Буду делать через сравнения dd.. у меня куча вопросов было, по mmx и сравнения ..так как, код...который мне казался правильным..не работал......
    (как оказалось...и не удивительно =))... я сравнивал ascii число с двоичным...)
     
  17. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Опять проблема (((
    не могу никак перевести 64 битное ASCII число в двоичный вид (((
    number_acsii_64bit (его нужно в двоичный вид перевести...)

    (не надо направлять на чтение книг))......сижу сейчас с двумя. в которых показан пример, перевода ascii числа в бинарный вид.....да вот беда.... все примеры на 32 разрядные числа (((((((((.)
     
  18. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    stellaco
    Мне бы твои проблемы.
    Переводишь символьный десятичный знак в десятичное число =- 48.
    Переводишь из десятичной систему в двоичную. n*(10^(номер символа начиная от нуля))
    Если числа большие, то наш родимый столбик.
    Вобщем вначале реализуй алгебру больших чисел, а далее всё будет просто.
    Но думаю для твоего случая проще было-бы mmx, sse.
     
  19. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    stellaco
    Я тебе уже говорил о fbld/fistp.

    Ну ладно - сейчас попробую написать что-нибудь вменяемое.
     
  20. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Код (Text):
    1. org 100h
    2. mov  si,number+9          ;указатель на завершающий ноль
    3. mov  di,pbcd
    4. fldz
    5. fstp tbyte[ds:di]         ;обнуляем буфер
    6. mov  ecx,4                ;длина числа / 2
    7. pack:sub si,2
    8.      mov ax,[ds:si]       ;загружаем две цифры
    9.      sub ax,3030h         ;переводим в десятичный вид
    10.      shl al,4
    11.      or  al,ah            ;упаковываем 2 числа в 1 байт
    12.      mov [ds:di],al       ;записываем в буфер
    13.      inc di
    14. loop pack
    15.  
    16. fbld  [pbcd]              ;загружаем упакованое двоично-десятичное
    17. fistp [value]             ;сохраняем в виде целого
    18.  
    19. @@:
    20. cmp dword[value],12345678 ;проверка на правильность преобразования
    21. je @b
    22. ret
    23. number db '0','12345678',0;число должно начинаться с "0"
    24. pbcd   rt 1
    25. value  rq 1