Сборник по задачам и примерам Assembler

     

Деление N-разрядного беззнакового



Деление N-разрядного беззнакового целого BCD-числа на одноразрядное BCD-число размером 1 байт (макрокоманда)

div_bcd_l_r macro u.N.v.w.r local ml

:div_bcd_l_r u.N.v.w.r - деление N-разрядного беззнакового целого BCD-числа

;на одноразрядное BCD-число размером 1 байт. :Вход: и - делимое; N - длина делимого, v - делитель. :Выход: w - частное, г - остаток. :Порядок следования байтов - старший байт по младшему адресу (не Intel) (!).

mov г.О

lea si.u ;j=0

хог di.di :j=0

mov cx.N

xor dx.dx

xor bx.bx

ml: mov ah,г

mov al.[si]

aaJ



div v сформировать результат:

mov w[di].al ;частное

mov r.ah .-остаток в г

inc si

inc di

loop ml

:если нужно - получим модуль (уберите знаки комментария)

: mov cx.N ;длина операнда

: lea bx.w

; call calc_abs_r

endm

Деление неупакованных BCD-чисел

:div_bcd_NM_r.asm - деление неупакованных BCD-чисел и и v размером n+m и п байт.

;Вход: и-и^гиз-.и,^,, - делимое: v=v1v2...vn - делитель. Ь=25б - основание системы счисления.

;Выход: q™q1q2-.qm - частное. r=rir2...rn - остаток,

:Порядок следования байт - старший байт по младшему адресу (не Intel) (!).

.data значения в и и v нужно внести

uO db 0 дополнительный байт для нормализации

u db 1,0.3.5,9,4,6 :делимое

m=$-u :длина в байтах значения и

vO db 0 :для сложения OvjV2..vn

v do 5.9.1 :делитель

n=$-v :длина в байтах значения v

ГПП1=П1-П

w db m+1 ctup (0) :для промежуточных вычислений q db mm dup (0) :частное qq db 0

г db n dup (0) :остаток

b dw 10 юснование системы счисления

d db 0

temp dw 0

temp_r db n dup (0)

borrow db 0 :факт заема на шаге D4

k db 0 ;перенос 0 =< k < 255

carry db 0

.code

:вставить описание макрокоманд calc_complement_r. mul_bcd_r. sub_bcd_r. add_bcd_r. :div_bcd_l_r

div_bcd_NM_r proc ;D1 - нормализация

xor ax.ax

mov dl.v

inc dl :vl+l

mov ax.b

div dl

mov d.al :d=b/(v1+l)

mul_bcd_r u.m.d.l.w

eld

push ds

pop es

lea si.w

lea di.uO

mov cx.m+1 rep movsb

mul_bcd_r v.n.d.l.w

eld

push ds

pop es

lea si.w+1

lea di.v

mov ex,n rep movsb :D2:


mov si.O ;n=0 :D3: @@m7: moval.uO[si]

emp v,al

jne @@ml

mov qq.9 :qq=b-l

jmp @@m2

(<t@ml: xor ax,ax

mov al.uO[si]

mul b

xor dx.dx

mov dl,uO[si+l]

add ax.dx

mov bl.v ;v->bx divbl

mov qq.al

@@m2: :проверим выполнение неравенства:

@@m4: mul v+1

mov temp. ax: taiip=v2*qq

xor ax.ax

mov al ,uO[si]

mul b

xor edx.edx

mov dl.uO[si+l] add dx.ax

mov al.qq

mul v :eax=qq*vl

sub dx,ax

xchg dx.ax

mul b

xor bx.bx

mov bl.uO[si+2]

add ax.bx

cmp temp,ax

jna (a@m3

dec qq

mov al.qq

jmp @@m4

@@m3: : D4

mul_bcd_r v.n.qq.l.w

mov bx.si

push si

sub_bcd_r uO[bx].<n+l>.w,<n+l>,uO[bx] ;v<->w

jnc @@m5 :переход, если нет заема (результат положительный)

mov borrow.1 ;запоминаем факт заема, получаем дополнение

pop si ;D5

@@m5: moval.qq

mov q[si].al

cmp borrow.1 : был заем на шаге D4 ??

jne @@m6 :D6 - компенсирующее сложение

mov borrow.0 :сбросин факт заема

dec q[si]

mov bx.si

push si

add_bcd_r uO[bx].<n+l>.vO,<n+l>,uO ;перенос не нужен :D7

@@m6: pop si

inc si

cmp si.mm

jle @@m7 :D8 - денормализация

mov bx.si

div_bcd_l_r uO[bx],N,d.r.temp_r

ret

div_bcd_NM_r endp *

main:

call div_bcd_NM_r end main

Упакованные BCD-числа

В отличие от неупакованных BCD-чисел, разработчики команд микропроцессора Intel весьма сдержанно отнеслись к проблеме обработки упакованных BCD-чисел. Существуют только две команды — DAA и DAS, которые поддерживают процесс сложения и вычитания упакованных BCD-чисел. Умножение и деление этих чисел не поддерживается вовсе. По этой причине при необходимости выполнения арифметических вычислений с упакованными BCD-числами есть смысл предварительно преобразовывать их в неупакованное представление, выполнять необходимые действия, результат которых конвертировать (если нужно) обратно в упакованный вид. Так как действия по преобразованию не являются основными в процессе вычислений, то желательно, чтобы они были максимально быстрыми. Можно предложить много вариантов подобного преобразования. Рассмотрим один из них.


Содержание раздела