деление знаковых целых чисел

Тема в разделе "WASM.BEGINNERS", создана пользователем xRom2, 23 май 2011.

  1. xRom2

    xRom2 New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2011
    Сообщения:
    63
    знаковое число находится в dx:ax, надо разделить его на cx (тоже знаковое), но заранее известно что произойдет переполнение. Как разделить числа в два или более приемов чтобы получился корректный результат?
     
  2. intel_x128

    intel_x128 New Member

    Публикаций:
    0
    Регистрация:
    17 май 2009
    Сообщения:
    345
    Разложить делитель на множители?
     
  3. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    можно разделить на СX/K K раз))
    Кстати если можно поделить другими командами для большей точности.
     
  4. xRom2

    xRom2 New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2011
    Сообщения:
    63
    Я так и думал, но например в общем случае если у меня в dx:ax находится 0000:ffff, то есть +65535, и мне надо разделить его на 1, то при втором делении программа вылетает. Что-то не так? Вот код, на выходе в dx:ax знаковое число. Код, на входе в dx:ax знаковое 32битное число:
    Код (Text):
    1.          push       ax          ;сохраняем младшую часть делимого
    2.          mov        ax,dx     ;старшую помещаем в AX
    3.          cwd                      ;расширяем знаки в DX
    4.          idiv         cx          ;делим
    5.          mov        bx,ax     ;сохраняем в BX результат первого деления
    6.          pop        ax          ;восстанавливаем младшую часть делимого в AX
    7.          idiv         cx          ;остаток в DX, делим
    8.          mov        dx,bx
     
  5. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    А использовать 32-битное деление edx:eax на ecx - не позволяет религия, препод или что-то еще ?
     
  6. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Старшие 16 разрядов делимого (без учёта знака, т.е. биты 30:15) должны быть меньше, чем разряды делителя (опять-таки без знака). В случае делимого 0000:FFFF старшие 15 (без знака) разрядов равны 0001, то есть они равны делителю 0001, посему и происходит вылет.

    ИМХО, можно попробовать сначала разделить делимое на степень двойки (арифметическими сдвигами вправо), пока её старшие 16 разрядов (без знака) не станут меньше, чем 15 разрядов делителя. Потом полученное модифицированное делимое разделить с помощью IDIV, а затем уже, зная, на сколько разрядов оно было сдвинуто, откорректировать частное и остаток.
     
  7. xRom2

    xRom2 New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2011
    Сообщения:
    63
    Честно я сам для себя пишу, просто потом с 32битной арифметикой вылезет все равно точно такая же проблема: буду делить числа размещенные в eax:edx на ecx, и все равно вопрос вылезет. Так что если я сейчас разберусь, то и все проблемы даже не появятся.
     
  8. intel_x128

    intel_x128 New Member

    Публикаций:
    0
    Регистрация:
    17 май 2009
    Сообщения:
    345
    Что-то вы тут не то делаете
    Давайте по шагам разберем

    eax = 0x0000FFFF
    edx = 0x0
    ecx = 1

    push ax ;сохраняем младшую часть делимого
    mov ax,dx ;старшую помещаем в AX (eax = 0 !!!)
    cwd ;расширяем знаки в DX
    idiv cx ;делим ( 0/1 ??)
    mov bx,ax ;сохраняем в BX результат первого деления
    pop ax ;восстанавливаем младшую часть делимого в AX (ax = 0xFFFF)
    idiv cx ;остаток в DX, делим
    mov dx,bx


    Что говорит ваш отладчик? Что у вас в регистрах вначале выполнения кода? что в старшей части edx?
     
  9. intel_x128

    intel_x128 New Member

    Публикаций:
    0
    Регистрация:
    17 май 2009
    Сообщения:
    345
    Я думаю вам стоит взглянуть на длинную арифметику.
    И работать не только с регистрами, но и с памятью.