Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.
Внимание! Некоторое время письма не доходят до аккаунтов MAIL RU GROUP, не доходят на все почтовые ящики mail.ru, inbox.ru, bk.ru. Пишите им жалобы, чтобы быстрее восстановили получение писем, регистрируйтесь через яндекс почту и gmail, туда письма с активизацией доходят.

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler
Регистрация

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

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

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

Цитата:
Сообщение от 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, 10:31   #3
R71MT
Профессионал
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,230
Репутация: 1048
По умолчанию

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

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

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

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, 17:31   #6
R71MT
Профессионал
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,230
Репутация: 1048
По умолчанию

Цитата:
Сообщение от 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, 17:10   #7
Vlad2891
Пользователь
 
Регистрация: 22.02.2015
Сообщений: 18
Репутация: 27
По умолчанию

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

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

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

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

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


01:53.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru