проверка размера числа(больше dd) + умножение

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

  1. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Столкнулся с такой проблемой.
    В моём приложении, пользователь вводит определённое число которое должно быть не выше чем 8796093022208 (это максимальное количество мегабайт, способных влезть в размер DQ(8 байт)... всмысле, мне нужно будет вписать в DQ количество байт (переведя введённые мегабайты пользователя в байты) )
    Это число не влезает в DD (размер 2147483648) и я решил просто выделить буфер размером в RESD 2 ... Под это число, а затем записать его через movsb
    Получилось 8 байт данных. И теперь мне нужно сделать проверку.. подходит ли число в этих самых 8-ми байтах по диапозону. (нужно узнать, меньше ли оно чем 8796093022208)
    и если оно меньше, то нужно его умножить на 1024*1024 (чтоб узнать количество байт) и записать в теже 8-мь байт..........

    Как это сделать? =)
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    stellaco
    Вспоминаем школу, умножение в столбик. А проверка тем более элементарна.
    Кстати SSE может помочь.
     
  3. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Booster
    умножение в столбик......
    вобщем, занёс старшие 4 байта в EAX , оставшиейся в ECX
    делаю adc eax, ecx ... и куда сумма 32-битных значений сохранится?....
    чтоб потом проверку по диапазону сделать..
    это видимо через вычитание 64 битного числа...и проверку......... > 0 ?....
    Да вот тут проблема)) ну не понимаю я как сложить...как вычесть 32-х битные числа..... куда результат будет записываться?

    хех..точно... SSE....щас попробую) спасибо
     
  4. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Смотри в сторону fbld/fistp. Двоично-десятичные числа могут иметь до 18 десятичных разрядов.
     
  5. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Зачем вычитать? Сравнивай вначале старшие половины, затем младшие.
    А умножать элементарно: перемножаешь младшие половины, если есть переполнение, то добавляешь единицу к старшей половине одного из чисел, и множишь младшую со старшей. Потом снова для старшей половины. Всё по школьному, очень просто.
     
  6. murder

    murder Member

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

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Booster Спасибо
    murder Спасибо
     
  8. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Всё, кажется разобрался))
     
  9. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Хотя нет, не разобрался...
    вот код..
    Код (Text):
    1. movd mm0, [то_что_нам_передали+4] ; загружаем старшую часть размера БД в арифметический сопроцессор MMX
    2. movd mm1, [то_с_чем_сравниваю+4] ; загружаем старшую часть mbyte_size_bd_max в арифметический сопроцессор MMX
    3. pcmpgtd mmo, mm1 ; проверка на больше...
    Это я делаю проверку введённого числа..
    а дальше что нужно делать?
    fnstsw ax ; копируем флаги сопроцессора в ax
    sahf ; передать ah в регистр флагов центрального процессора
    а потом просто jg ?..чтоб осуществить переход...
    не понимаю)....
     
  10. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    pcmpgtd сравнивает DWORD`ы и помещает в выходной регистр маску. При этом флаги не меняются.

    чтобы работать с флагами делай так
    Код (Text):
    1. sub [lo],eax ;сравниваем eax:edx с [lo]:[hi].
    2. sbb [hi],edx
    3. jnae error
    4. shld edx,eax,20 ;если меньше - умножаем на 1024*1024
    5. shl  eax,20
    6. error:
    Либо как я уже писАл преобразовать строку в число при помощи fbld а затем fcom
     
  11. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    что-то никак (
    Код (Text):
    1. finit ; инициализация сопроцессора
    2. fild qword[mbyte_size_max] ; загружаем максимально допустимый размер числа в арифметический сопроцессор
    3. fild qword[byte_size_buf] ; загружаем размер введённого числа в арифметический сопроцессор
    4. ficom  ; сравнить st(0) с максимально возможным числом st(1)
    5. fnstsw ax ; копируем флаги сопроцессора в ax
    6. sahf ; передать ah в регистр флагов центрального процессора
    7. ja label_error_attributes_txt ;  не меньше и не равно......ВЫХОД
    8. fimul 1048576 ; умножаем st(0) на 1024*1024=1048576
    9. fbstp byte_size_buf; сохраняем st(0) в памяти
    10. emms ; очитка состояния сопроцессора
    fbld тоже самое,что и fild?
    fbstp тоже самое, что и fistp ?

    Не компилируется...выдаёт следующие ошибки.
    create_db:181: error: invalid combination of opcode and operands
    create_db:185: error: invalid combination of opcode and operands
    create_db:186: error: invalid combination of opcode and operands

    181) ficom
    185) fimul 1048576
    186) fbstp byte_size_buf

    что не так?
     
  12. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    1) читай CH26-XX.txt - поможет насчёт fbld
    2)ficom, fimul и другие целочисленные инструкции только с памятью работают.
    3) fbstp требует 10-байтового операнда, тут надо fistp qword[byte_size_buf].

    НЕ ИСПОЛЬЗУЙ FPU ДЛЯ УМНОЖЕНИЯ - БУДЕТ ПОГРЕШНОСТЬ. Делай сдвигами shld, shl.

    Повторяю
    Код (Text):
    1. mov eax,[byte_size_buf]
    2. mov edx,[byte_size_buf+4]
    3. sub [mbyte_size_max],eax ;сравниваем eax:edx с [mbyte_size_max].
    4. sbb [mbyte_size_max+4],edx
    5. jnae error
    6. shld edx,eax,20 ;если меньше - умножаем на 1024*1024
    7. shl  eax,20
    8. mov [byte_size_buf],eax
    9. mov [byte_size_buf+4],edx
    10. error:
    Добавлено:
    Не путай FPU и MMX.
     
  13. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Спасибо =)..
    и ещё один вопрос...чтоб развеять сомнения насчёт fpu и mmx
    FPU это 8 регистров , 80 разрядных..для расчёта чисел с плавающей точкой.. (выполняющийся параллельно с центральным процессором)
    а MMX это теже 8 регистров, что и у FPU толлько с разрядностью 60 ? и тоже выполняется параллельно с цп...
    верно?
     
  14. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    stellaco
    yes

    64=8*8
     
  15. meduza

    meduza New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    212
    stellaco
    Физически регистры FPU (r0..r7 (st0..st7 - это абстракции над этими регистрами, с которыми можно работать как с стеком)) и регистры MMX (mm0..mm7) - одно и то же. Именно поэтому одновременно нельзя использовать сразу и FPU и MMX, иначе будет каша. Регистры эти (r0..r7) 80-битные, при работе с MMX используються только 64 младшие бита, остальные заполняются еденицами.
     
  16. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    meduza
    странное у тебя название "каша" - екзепта фпу при не очишенном контексте MMX.
    после комманд MMX, до комманд FPU, нужно очишать контекст коммандой EMMS и всё :)
     
  17. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Спасибо за помощь =)..
    с fpu и mmx буду разбираться по мере поступления проблем.. а сейчас...пойду ошибки в коде отлавливать... =)
     
  18. stellaco

    stellaco New Member

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

    выводит текст на экран (через системный вызов)
    считывает введённую информацию с клавиатуры.
    выводит снова текст..
    и тут он должен снова через системный вызов read прочесть введённую инфу с клавиатуры..
    а программа это действие пропускает..и исполняет код дальше.. (завершается)
    с чем это может быть связано? как поправить?
     
  19. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    int 21h? Параметры правильно передаёшь?
     
  20. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    murder
    Я программирую только для *NIX =)

    Последний вызов ;Системный вызов #3 read: пропускается ( и не выполняется.....завершается...(без ошибок)