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

Discussion in 'WASM.BEGINNERS' started by xRom2, May 23, 2011.

  1. xRom2

    xRom2 New Member

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

    intel_x128 New Member

    Blog Posts:
    0
    Joined:
    May 17, 2009
    Messages:
    345
    Разложить делитель на множители?
     
  3. h0t

    h0t Member

    Blog Posts:
    0
    Joined:
    Apr 3, 2011
    Messages:
    735
    можно разделить на СX/K K раз))
    Кстати если можно поделить другими командами для большей точности.
     
  4. xRom2

    xRom2 New Member

    Blog Posts:
    0
    Joined:
    Apr 25, 2011
    Messages:
    63
    Я так и думал, но например в общем случае если у меня в dx:ax находится 0000:ffff, то есть +65535, и мне надо разделить его на 1, то при втором делении программа вылетает. Что-то не так? Вот код, на выходе в dx:ax знаковое число. Код, на входе в dx:ax знаковое 32битное число:
    Code (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

    Blog Posts:
    0
    Joined:
    Aug 4, 2004
    Messages:
    2,542
    Location:
    Russia
    А использовать 32-битное деление edx:eax на ecx - не позволяет религия, препод или что-то еще ?
     
  6. SII

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

    Blog Posts:
    0
    Joined:
    Oct 31, 2007
    Messages:
    1,483
    Location:
    Подмосковье
    Старшие 16 разрядов делимого (без учёта знака, т.е. биты 30:15) должны быть меньше, чем разряды делителя (опять-таки без знака). В случае делимого 0000:FFFF старшие 15 (без знака) разрядов равны 0001, то есть они равны делителю 0001, посему и происходит вылет.

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

    xRom2 New Member

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

    intel_x128 New Member

    Blog Posts:
    0
    Joined:
    May 17, 2009
    Messages:
    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

    Blog Posts:
    0
    Joined:
    May 17, 2009
    Messages:
    345
    Я думаю вам стоит взглянуть на длинную арифметику.
    И работать не только с регистрами, но и с памятью.