ZXNet эхоконференция «code.zx»
тема: Задачка от Axor'a #2
от: Vlad Sotnikov
кому: All
дата: 15 Sep 2003
Пpивет, All!
Вот еще одна задачка:
Сyществyет число HL, есть некая часть от этого числа DE, вычислить пpоцент
в A этой части.
Ждy ваши ваpианты данной пpоцедypы.
Vega/ex-Style Group.
<филфак-СПбГУ>
FIDO: 2:5030/1512 ZXNET: 500:812/19 E-mail: vega56@mail.ru
от: Kirill Frolov
кому: Vlad Sotnikov
дата: 15 Sep 2003
Hемедленно нажми на RESET, Vlad Sotnikov!
On Sun, 14 Sep 03 23:14:17 +0400, Vlad Sotnikov wrote:
VS> Вот еще одна задачка:
VS> Сyществyет число HL, есть некая часть от этого числа DE, вычислить
VS> пpоцент в A этой части. Ждy ваши ваpианты данной пpоцедypы.
Иначе говоря, A = 100 * DE / HL. Hо, встаёт вопрос о точности
результата и допустимом диапазоне представления чисел. Допустим,
что A -- целое число, а HL и DE -- беззнаковые 16-разрядные целые.
Тогда решение будет иметь следующий вид (процент округляется до
ближайшего целого числа):
push hl
ld hl, 200
exx
ld hl, 0
push hl
ld e, l
ld d, h
exx
call lmul
pop de
call ldiv
ld a, l
srl a
В данном случае были использованы две библиотечные функции ldiv и
lmul описание которых и текст на языке ассемблера приводится ниже:
lmul
=====
(DE
от: Kirill Frolov
кому: Kirill Frolov
дата: 15 Sep 2003
Hемедленно нажми на RESET, Kirill Frolov!
On Mon, 15 Sep 2003 18:09:36 +0000 (UTC), Kirill Frolov wrote:
KF> Тогда решение будет иметь следующий вид (процент округляется до
KF> ближайшего целого числа):
KF> push hl
KF> ld hl, 200
KF> exx
KF> ld hl, 0
KF> push hl
^^^^^^^^^^^^^^^^^
эту инструкцю следует исключить...
KF> ld e, l
KF> ld d, h
KF> exx
KF> call lmul
KF> pop de
KF> call ldiv
KF> ld a, l
KF> srl a
от: Kirill Frolov
кому: Kirill Frolov
дата: 15 Sep 2003
Hемедленно нажми на RESET, Kirill Frolov!
On Mon, 15 Sep 2003 18:22:37 +0000 (UTC), Kirill Frolov wrote:
KF>> Тогда решение будет иметь следующий вид (процент округляется до
KF>> ближайшего целого числа):
KF>> push hl
KF>> ld hl, 200
KF>> exx
KF>> ld hl, 0
KF>> push hl
KF> ^^^^^^^^^^^^^^^^^
KF> эту инструкцю следует исключить...
KF>> ld e, l
KF>> ld d, h
KF>> exx
KF>> call lmul
KF>> pop de
KF>> call ldiv
KF>> ld a, l
KF>> srl a
Обязательное условие -- DE <= HL, если я правильно понял условие
задачи.
Вообще-то можно использовать функцию mul перемножающую 16-разрядные
числа, тогда решение будет иметь такой вид:
push hl
ld bc, 200
call mul
push de
exx
pop hl
ld de, 0
exx
pop de
call ldiv
xor a
ld a, l
rra
mul
====
(DE,HL) = DE * BC
Функция перемножает беззнаковые 16-разрядные числа заданные в
регистрах DE и BC, и помещает результат в регистры DE и HL. В
регистре DE хранятся старшие биты результата. Функция
выполняется примерно за 800 тактов процессора. Смотри также
описание функции amul.
EXPORT global mul ; long (DE,HL) = DE*BC ~730t.
; функция беззнакового умножения 16-разрядных чисел
; (C) Kirill Frolov
; idea by Vasil Ivanov
; dehl=de*bc ~730t.
psect text
mul:
ld hl, 0
ld a, c
ld c, l ; 18
add a, a
jr nc, $+4
add hl, de
adc a, c ; 29
; REPEAT 7
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c ; 40*7 309
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
; ENDR
ld c, a
push hl ; 0chl
ld hl, 0
ld a, b
ld b, l ; 33
add a, a
jr nc, $+4
add hl, de
add a, b ; 29
; REPEAT 7
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b ; 40*7 309
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b
; ENDR
; ahl0 + 0cde = hlde
pop de
ld b, l
ld l, h
ld h, a
ld a, d
add a, b
ld d, a
ld b, 0
adc hl, bc
ex de, hl ; 60
ret ; 729t.
|