Adventurer
#08
31 августа 1998 |
|
Обмен опытом - о том как оперировать в ассемблере с длинными числами типа Long.
(C) Maximum/INTEGER LONG ??? Что это такое ? ───────────────────────────── Так обозначаются длинные числа на PC и на AMIGA . Т. е это числа, лежащие в диапазоне от 0 до 4294967295, для предс- тавления которых отводится 4 (четыре) байта в памяти. В данной статье я научу вас опери- ровать с такими числами. И для чего это надо? например, вы пишете игру, в которой есть такие параметры,как деньги, золото и т. д. Как водится, денег в таких играх бывает намного больше, чем 65535. Вот здесь-то как раз и пригодятся LONG цифер- ки... Итак, у нас есть число 12. 000. 00. В Long оно выглядит так: #00B71B00 В ассемблере же стоит набирать так: long_num DW #00B7, #1B00 Формат задания любого Long числа: ... LD HL,#00B7 EXX LD HL,#1B00 ... Т.е в HL старшая часть числа, а в HL' его младшая часть. Сложение двух Long чисел ──────────────────────────── Надо просто сложить младшие части, а потом с учетом флага C сложить и стар- шие: L_ADD ADD HL,DE EXX ADC HL,DE EXX RET На входе у процедуры: HL и HL' - первое число, в DE и DE' - второе число. На выходе: HL и HL' сумма двух чи- сел. Разность двух Long чисел ──────────────────────────── Здесь примерно то же самое: L_SUB AND A SBC HL,DE EXX SBC HL,DE RET Параметры такие же, как у L_ADD. Печать Long чисел ───────────────────── Для печати числа нам нужно его пе- рекодировать из Long в ASCII коды, что и делает следующая процедура: L_PR LD IX,L_TAB; см.ниже LD A,10 ; число из 10 знаков L_PR0 EX AF,AF' EXX LD E,(IX+0); ст.слово из табл. LD D,(IX+1) EXX LD E,(IX+2); мл.слово из табл. LD D,(IX+3) LD A,'0'-1 L_PR1 CALL L_SUB ; отнимаем пока не INC A ; включится флаг C JR NC,L_PR1; CALL L_ADD ; востановим число LD (BC),A ; в буфер его INC BC INC IX INC IX INC IX INC IX EX AF,AF' DEC A JR NZ,L_PR0; все числа RET ; ... ;таблица чисел: L_TAB DW #3B9A,#CA00 ; 1000000000 DW #05F5,#E100 ; 100000000 DW #0098,#9680 ; 10000000 DW #000F,#4240 ; 1000000 DW #0001,#86A0 ; 100000 DW #0000,#2710 ; 10000 DW #0000,#03E8 ; 1000 DW #0000,#0064 ; 100 DW #0000,#000A ; 10 DW #0000,#0001 ; 1 Перед вызовом в HL и HL' число, а в BC адрес буфера для числа. Пример: ORG #6000 LD HL,#FFFF EXX LD HL,#FFFF LD BC,BUFF CALL L_PR CALL 3435 LD A,2 CALL 5633 LD HL,BUFF LD B,10 LOOP LD A,(HL) RST 16 INC HL DJNZ LOOP RET BUFF DS 10 Ввод Long числа. ─────────────────── Вернее не ввод, а преобразование числа из ASCII кодов в Long формат. Применить это можно так: ... LD HL,BUFF ... CALL INPUT ;Вводим число LD HL,BUFF CALL L_DC ... На входе у процедуры: HL-адрес буфера, где сидит число: BUFF DB "212042067" DB 0 ;Маркер конца т.е ;код <"0" и >"9" После вызова в HL и HL' будет число. L_DC PUSH HL LD B,0 L_DC1 LD A,(HL) ;Подсчитаем сколько CP "0" ;циферок у нашего JR C,L_DC2 ;числа CP "9"+1 JR NC,L_DC2 INC B INC HL JR L_DC1 L_DC2 EXX POP BC ;в BC его LD HL,0 ;Обнулим EXX ;новое LD HL,0 ;число EXX L_DC3 LD A,B ;все зделали ? LD DE,0-4 AND A RET Z ;нееет ! EXX DEC A ;используя таблицу LD IX,L_TAB+36 JR Z,L_DC4 ;найдем ADD IX,DE ;нужный DEC A ;нам JR Z,L_DC4 ;разряд ADD IX,DE ;числа DEC A JR Z,L_DC4 ADD IX,DE DEC A JR Z,L_DC4 ADD IX,DE DEC A JR Z,L_DC4 ADD IX,DE DEC A JR Z,L_DC4 ADD IX,DE DEC A JR Z,L_DC4 ADD IX,DE DEC A JR Z,L_DC4 ADD IX,DE DEC A JR Z,L_DC4 ADD IX,DE L_DC4 DEC B ;ага, нашли LD E,(IX) ;берем то что LD D,(IX+1) ;мы будем EXX ;прибавлять LD E,(IX+2) ;к LD D,(IX+3) ;новому числу LD A,(BC) ;какое у вас число ? INC BC L_DC5 CP "0" ;пока не "ноль" JR Z,L_DC3 CALL L_ADD ;прибавляем разряд DEC A JR L_DC5 Ну все, я дал уже достаточно много информации про Long, так что пользуйтесь на здоровье... Надеюсь, что данная статья кому-то поможет. Еще хочу напомнить, что такими числами уже успешно воспользовался всем известный Слава Медноногов в своей UFO. Больше я такого метода пока нигде не встречал. * * *
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября