Определить количество символов в последней строке текстового файла - Assembler
Формулировка задачи:
Определить количество символов в последней строке текстового файла Результат и саму строку показать на экране. Записать строку в новый файл.
Вот что я написал в итоге. Чтобы узнать последнюю строку с конца файла я двигаюсь и проверяю на конец строки 0A.
Только проблема у меня в этом самом месте. В отладчике она бесконечно в цикле двигается и не выходит. А значит не проходит сравнение, а почему я не понимаю.
Вот сам код с комментариями TASM
Помогите пожалуйста разобраться.
.386
dseg segment use16
text1 db 14,11,'File Open: ',0Dh,0Ah,'$'
text2 db 13,10,'Result..: $'
text3 db 14,11,'Next file: $'
text4 db 13,10,'Error cr: $'
Buf db ? ;для изначального файла
Buf1 db ? ; для работы внутри файла
handle dw ?; буфер логического номера файла
handle2 dw ?; буфер 2 логического номера файла
pathname db 'myfile2.asm', 0 ; путь к файлу
fName db 'myfile.asm',0 ;путь ко 2 файлу ,новому
dseg ends
cseg segment use16
assume cs:cseg,ds:dseg
m1:
mov cx,dseg
mov ds,cx
;-------------------
;Происходит открытие файла
mov al,0
lea dx,fname
mov ah,3Dh
int 21h
jc error ; ошибка открытия файла (CF=1)
mov ah,09h
lea dx,text1
int 21h ;вывод сообщения что файл открылся
mov handle,ax
;--------------------
;Чтение байтов из файла
lea dx,buf
mov bx,handle
mov cx,0FFh
mov ah,3Fh
int 21h
;--------------------
;Смещаю указатель на конец файла
;Первый раз на -1
mov bx,handle
mov al,2
mov cx,0FFFFh
mov dx,0FFFFh
mov ah, 42h
int 21h
mov bx,handle
mov cx,1
lea dx,buf1
mov ah, 3Fh
int 21h
xor bh,bh ;счетчик сколько байтов в строке
inc bh
cmp buf1,0Ah
jne short m2 ;если сравнение не дало результата
jmp short m3
;-----------------------------
;Теперь указатель смещаю на два и буду считывать по 1 байту.
m2:
mov bx,handle
mov al,1
mov cx,0FFFFh
mov dx,0FFFEh
mov ah, 42h
int 21h
mov bx,handle
mov cx,1
lea dx,buf1
mov ah, 3Fh
int 21h
inc bh
cmp buf1,0Ah
jne short m2 ; повторяю пока сравнение не дало результата
;----------------------------------
;Сравнение прошло успешно, я нашел начало последней строки
;Считываю в буфер всю строку
m3:
mov bx,handle
mov cx,0FFFFh
lea dx,buf1
mov ah, 3Fh
int 21h
;-----------------------------------
;Вывожу на экран результат
;Сначала количество символов а потом строку
mov ah,0Ah
lea dx,text2
int 21h
mov ah,09h
movzx dx,bh
int 21h
mov ah,0Ah
lea dx,Buf1
int 21h
;-------------------------------------------------
;Создаю новый файл
mov ah,0Ah
lea dx, text3 ; сообщение то что началась работа с новым файлом
int 21h
mov ah,3ch
mov cx, 0 ; стандартные атрибуты файла
lea dx, pathname
mov ah, 3ch
int 21h
jc short error ; ошибка создания файла (CF=1)
;-------------------------------------------------------
;Запись в новый файл
mov handle2,ax ;сохраняю хэндл второго файла
mov bx,handle2
mov cx,0
lea dx,buf1
mov ah,40h
int 21h
;-------------------------------------------------------
;Закрываю файл
mov bx,handle2
mov ah, 3Eh
int 21h
jmp short m4
error:
mov ah,09h ; выводим на экран сообщение об ошибке
lea dx,text4
int 21h
m4:
mov ah, 4ch ; завершаем программу
mov al, 00h
int 21h
cseg ends
end m1Решение задачи: «Определить количество символов в последней строке текстового файла»
textual
Листинг программы
;== FASM code =======================
org 100h
jmp start
open db 13,10,' File Open: $' ; мессаги..
last db 13,10,'Last String: $' ;
size db 13,10,'String Size: $' ;
create db 13,10,'Create File: $' ;
ok db 'OK! $' ;
err db 'ERROR!',7,'$' ;
myData db 'myData.txt',0 ; файл с данными
myFile db 'myFile.txt',0 ; новый файл
buff db 2048 dup(0) ; буфер для данных
string db 80 dup('$') ; буфер для строки
fSize dw 0 ; размер файла
start:
; Файл с данными ==========================================
mov dx,open ;
call message ;
mov ax,3d00h ; Открыть!
mov dx,myData ;
int 21h ;
jc error ; ошибка?
xchg ax,bx ; отправляем хэндл в ВХ
mov dx,ok ; мессага OK
call message ;
mov ah,3fh ; Читать содержимое файла,
mov dx,buff ; ..в файловый буфер
mov cx,0ffffh ;
int 21h ;
mov [fSize],ax ; сохраняем размер файла
mov ah,3eh ; Закрываем его!
int 21h ;
; Поиск последней строки в буфере =========================
mov dx,last ;
call message ;
std ; DF=1 (читать справа-налево)
mov di,buff ; где искать
mov cx,[fSize] ; длина поиска
add di,cx ; перемещаемся в конец буфера
push cx ; запомним позицию для счётчика
mov al,0Ah ; что искать
repne scasb ; ПУСК!
cld ; нашли 0Аh (или СХ=0). сброс DF
pop bx ; расчитываем длину
sub bx,cx ; ..последней строки
xchg cx,bx ;
sub cx,2 ; (коррекция длины)
mov [fSize],cx ; запомним для вывода на экран
xchg si,di ; SI - источник для копирования
add si,2 ;
mov di,string ; DI - приёмник строки
rep movsb ; копируем СХ-байт из SI в DI
; Вывод последней строки и её размера на экран ============
mov dx,string ; выводим на экран строку
call message ;
mov dx,size ;
call message ;
mov ax,[fSize] ; выводим на экран длину строки
mov bx,10 ; ..в 10-тичном виде
call hex2asc ;
; Создаём файл и отправляем в него строку =================
mov dx,create ;
call message ;
mov ah,3ch ; Создать!
mov cx,20h ; ..c атрибутом R/W
mov dx,myFile ;
int 21h ;
xchg bx,ax ; дескриптор для записи
mov ah,40h ; Запись в файл!
mov cx,[fSize] ; ..байт для записи
mov dx,string ; что записывать
int 21h ;
mov ah,3eh ; Закрыть файл!
int 21h ;
mov dx,ok ; мессага ОК!
call message ;
jmp exit ;
; Обработчик ошибки и выход ===============================
error: ; (обработчик ошибки)
mov dx,err ;
call message ;
exit: ;
xor ax,ax ;
int 16h ;
int 20h ;
;ннннннннннннннннн П Р О Ц Е Д У Р Ы нннннннннннннннннннннннннннннннннннн
;------------------------------------------------------------------------
message: ;
mov ah,9 ; вывод строки на экран
int 21h ;
ret ;
;------------------------------------------------------------------------
hex2asc: ; Функция переводит числа в символы
pusha ; Вход: АХ = число, BX = система счисления
xor cx,cx ; Выход: на экране
isDiv: ;
xor dx,dx ;
div bx ;
push dx ;
inc cx ;
or ax,ax ;
jnz isDiv ;
isOut: ;
pop ax ;
cmp al,9 ;
jle noHex ;
add al,7 ;
noHex: ;
add al,30h ;
int 29h ;
loop isOut ;
popa ;
ret ;