Определить количество символов в последней строке текстового файла - 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                      ;

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 3.786 из 5
Похожие ответы