Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.11.2018, 14:27   #1
Vlad2891
Пользователь
 
Регистрация: 22.02.2015
Сообщений: 24
По умолчанию Неупакованные числа

Доброго времени суток. Несколько дней пытаюсь разобраться в неупакованных числах, а точнее в их делении, но никак не могу понять как это работает.
В общем, имеется число, например "4159h".
Оно в неупакованном виде, т.е. "04010509h"
Чтобы его разделить, мне нужно поместить старшую часть (0401h) в DX, а младшую (0509h) в AX, тогда при делении на CX должен получиться какой нибудь результат. Есть операция aad которую нужно использовать перед делением для корректировки, но она работает только для регистра AX. А как быть с DX?
Я не понимаю как это работает, при попытке деления получаю "Divide Error". Объясните пожалуйста
Vlad2891 вне форума Ответить с цитированием
Старый 17.11.2018, 09:22   #2
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Цитата:
Сообщение от Vlad2891 Посмотреть сообщение
А как быть с DX?
в столбик нужно делить, как на бумажке..
но в данном примере, после 'aad' всё делимое вмещается у тебя в слово(АХ), поэтому можно обойтись малой кровью - например:
Код:
mov  ax,0401    ;
aad             ; AX = 0029
mov  bh,al      ; ..(запомнить ст.часть делимого в BH)

mov  ax,0509    ;
aad             ; AX = 003B
mov  bl,al      ; BX = 293B = делимое (BCD.04010509)

mov  ax,0702    ; 
aad             ; AX = 0048
xchg ax,bx      ; AX = 293B (делимое), BX = 0048 (делитель)
cwd             ; расширить AX до DX:AX (DX=0)
div  bx         ; AX = целое, DX = остаток
если числа больше, можно задействовать EAX по такому-же принципу.
только мов'ить в старшую часть EAX уже не получится, поэтому нужны сдвиги слов влево: shl eax,16
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 17.11.2018, 09:31   #3
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

вообще-то так не пойдёт.. тут только в столбик
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 17.11.2018, 13:11   #4
Vlad2891
Пользователь
 
Регистрация: 22.02.2015
Сообщений: 24
По умолчанию

Еще, наверно, можно число запаковать, тогда оно бы поместилось в регистр AX и его можно было бы спокойно разделить. Так как передо мной стоит задача обработать числа в неупакованном виде, а точнее найти их среднее арифметическое через подпрограмму, а как именно я это сделаю значения не имеет.
Vlad2891 вне форума Ответить с цитированием
Старый 17.11.2018, 13:51   #5
Vlad2891
Пользователь
 
Регистрация: 22.02.2015
Сообщений: 24
По умолчанию

Решение найдено

DX - старшая
AX - младшая
BX - делитель

Код:
        cmp     dx, bx          ; если старшая часть делимого меньше делителя,
        jb      one_div         ; то можно обойтись одним делением
        ; придется делить старшую и младшую части отдельно, поскольку
        ; в противном случае словим переполнение (результат превысит размер слова)
        mov     cx, ax          ; сохраняем младшую часть делимого
        mov     ax, dx
        xor     dx, dx
        div     bx              ; делим старшую часть
        xchg    ax, cx          ; ax - младшая часть делимого
one_div:
        div     bx              ; делим младшую часть
        mov     si, dx          ; si - младшая часть остатка
        mov     dx, cx          ; dx - старшая часть результата
        xor     di, di          ; di - старшая часть остатка
        ; DX:AX   - частное
        ; DI:SI   - остаток
Vlad2891 вне форума Ответить с цитированием
Старый 17.11.2018, 16:31   #6
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Цитата:
Сообщение от Vlad2891 Посмотреть сообщение
Решение найдено
..найдено - это хорошо, только причём здесь упомянутые BCD?
складывать и вычитать их можно в любом виде, а вот делить и умножать - только неупакованные! Вот пример деления распакованного, на его-же длинну в байтах:
Код:
; fasm-code
;--------------
org 100h
jmp start

A       db    04,01,05,09,07,02   ; распакованое 415972
len     =     $-A                 ; длинна (макс.9)

start:  mov   cx,len         ; итераций цикла для LOOP
        mov   bx,cx          ;   ..он-же делитель
        mov   si,A           ; источник данных
        mov   di,si          ;   ..он-же приёмник
        xor   ax,ax          ; АХ = 0
        push  cx si          ;   ..(запомнить для вывода)
@01:    lodsb                ; AL = очередной байт из SI
        aad                  ; bcd-коррекция перед делением
        div   bl             ; разделить AL на BL
        stosb                ; запомнить целое(AL) в DI (остаток в AH остался)
        loop  @01            ; цикл..

        mov   bl,ah          ; запомнить остаток в BL
        pop   si cx          ; восстановить данные из стека

@02:    lodsb                ; вывод результата на экран
        add   al,30h         ; число в символ
        int   29h            ;
        loop  @02            ;

        mov   al,'.'         ; выводим разделитель
        int   29h            ;
        mov   al,bl          ; и следом остаток из BL
        add   al,30h         ;
        int   29h            ;

        mov   ah,8           ; клава
        int   21h            ;
        ret                  ; Game ower!
Таким образом, при BCD-делении, AAD корректирует именно остаток в AH, который остаётся там от предыдущей операции DIV, а мы снимаем этот остаток в конце всего цикла. AAD его учитывает, и получаем делимое размером байт в AL.
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 21.11.2018, 16:10   #7
Vlad2891
Пользователь
 
Регистрация: 22.02.2015
Сообщений: 24
По умолчанию

Цитата:
Сообщение от R71MT Посмотреть сообщение
len = $-A ; длинна (макс.9)
А если длина будет больше 9?
Vlad2891 вне форума Ответить с цитированием
Старый 21.11.2018, 18:46   #8
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

..то в столбик, по принципу "деление-вычитанием"
лично мне это никогда не нужно было (и врядли пригодится), поэтому и не вникал. Но когда-то подымалась тут тема - поищи..
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 21.11.2018, 18:48   #9
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

однако если делитель 9 и меньше, то делимое может быть практически любой длинны
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
дан двумерный массив пользователь вводит натуральные числа,массив размером N на M .Все числа из которых можно извлечь корень извлекаются все числа меньше нуля заменяются их модулем qqq`` Паскаль, Turbo Pascal, PascalABC.NET 9 02.10.2017 17:11
Создать программу,имеющая процедуру,кторая в производном текстовом файле,которая имеет слова и числа,изменяющая все числа числа,ме Fingergod Паскаль, Turbo Pascal, PascalABC.NET 0 13.12.2012 20:08
Задачи в ТурбоПаскаль: найти числа Армстронга и просуммировать числа в последовательности номера которых простые числа Lena1808 Помощь студентам 1 17.05.2012 08:00
Задані цілі числа від 1 до 100.Надрукувати в порядку зростання усі числа що можна подати у вигляді 7*i*j+j+3, де i,j - цілі числа. Саша513 Паскаль, Turbo Pascal, PascalABC.NET 0 16.05.2012 18:45
Получить неупакованные данные Voody Работа с сетью в Delphi 4 08.09.2009 20:33