Задачка от Axor'a #2 — ZXNet «code.zx»

Задачка от Axor'a #2

ZXNet echo conference «code.zx»



from: Vlad Sotnikov
to: All
date: 15 September 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

from: Kirill Frolov
to: Vlad Sotnikov
date: 15 September 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

from: Kirill Frolov
to: Kirill Frolov
date: 15 September 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

from: Kirill Frolov
to: Kirill Frolov
date: 15 September 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.