Есть вопросы - это замечательно
Итак:
1) Формат времени файла в функциях ДОСа следующий (побитно):
CX = hhhhhmmm mmmsssss, где
hhhhh - часы, старшие 5 бит слова (0-23),
mmmmmm - минуты, 6 бит внутри слова (0-59),
sssss - секунды пополам, младшие 5 бит, (счет с точностью до 2 секунд, значение от 0 до 29)
Чтобы получить часы, делаем сдвиг вправо на 11 бит и получим число в младших битах слова
Чтобы получить минуты, сначала выделяем нужные биты, накладаем маску 07e0h и сдвигаем вправо на 5 бит (можно и наоборот, сначала сдвинуть, потом наложить маску 003fh)
Чтобы получить секунды, накладываем маску 001fh и умножаем на 2 (сдвигом влево на 1 бит)
2) InData является частью буфера, который используется при вводе при помощи функции 0ah:
[code lang=asm]InBuffer db 128 ;длина буфера
InCount db ? ;длина реально введенный данных
InData db 128 dup (?) ;сами введенные данные[/code]
Дату програма ждет в виде DD.MM.YYYY, т.е.
день, как два байта в начаче буфера InData,
месяц, как два байта, начиная с адреса InData+3,
года, как четыре байта, начиная с адреса InData+6
Аналогично и время ждем в виде ЧЧ:ММ:СС
Поэтому перед вызовом функций GetNum2 и GetNum4 указываем адрес, где лежат введенные числа в виде ASCII символов цифр
3) Функция GetNum2 читает два десятичных разряда числа (предворительно превращая из символов в число) по адресу в SI и формирует из них число, умножая старший разряд на 10 и складывая с младшим
Функция GetNum4 вызывает два раза GetNum2, дабы получить столетие и год, затем столетие умножается на 100 и складывается с годом.
Небольшое замечание, касаемое года. В формате даты год считается от 1980 года (т.е. нулевой год - это год 1980). Поэтому при преобразования туда/сюда отнимается/добавляется 1980.
3) Перед подсчетом размера программы необходимо понимать следующее:
- для модели tiny данные размещаются за кодом, т.е. последний использованный адрес будет в конце сегмента данных
- сегменты выравниваются на границу слова. Т.е. сегмент данных будет с четного адреса. Другими словами, если длина сегмента кода нечетная, то будет добавлен один байт для выравнивания до четного адреса.
Итак, нам надо добавить две метки:[code lang=asm]InData db 128 dup (?)
FINISH label byte ;метка в конце сегмента данных[/code] и [code lang=asm]GetNum2 endp
FINISH_PRG: ;метка в конце сегмента кода
END BEGIN[/code]Тогда длина программы получается, как:[code lang=asm]mov ax, ((FINISH_PRG-BEGIN+1) and 0fffeh)+FINISH-filename[/code]Т.е. считаем длину сегмента кода (с учетом выранивания!) и длину сегмента данных.
Может возникнуть вопрос: почему нельзя mov ax, FINISH-BEGIN? Нельзя, т.к. в разных сегментах.
И еще вопрос: как вывести полученную длину? Или как hex, либо как десятичное число. Оставляю на самостоятельную работу
Есть еще вариант: разместить данные в сегменте кода за кодом (для модели tiny так делается весьма часто).
Тогда, поставив метку за данными, получим длину, как разность между этой меткой и BEGIN