Вывод символьной строки на экран - Assembler

Узнай цену своей работы

Формулировка задачи:

Добрый вечер, реализовал программу, условие её такого что нужно из текстового файла прочитать 20 символов начиная с 10-байта в файле. Показать строчку на экране( что у меня не получается!!!!) и записать в новый файл по 4 символа в каждой строчке. Все условие программы у меня реализовано и работает прекрасно, но при выводе строк на экран выдает полнейшую чушь Помогите разобраться
.386
 
stak segment
  db 100 dup (0)
stak ends
 
;сегмент данных 
dseg segment
   txt1 db 'File Name Read: ',0dh,0ah,'$'          ;текст перед запросом на имя файла
   txt2 db 'Not Enter FileName!',0dh,0ah,'$'       ;неуказано ничего в командной строке, например нажали Enter просто
   txt3 db 'Open File Error!',0dh,0ah,'$'          ;ошибка открытия файла
   txt4 db 'Error Create File!',0dh,0ah,'$'        ;ошибка создания файла
   txt5 db 'File Name Write: ',0dh,0ah,'$'         ;текст перед запросом на имя файла
   txt6 db 'Stroka simvolov v file: ',0dh,0ah,'$'  ;символы записываемые в файл
   perehod db 0dh,0ah,'$'                          ;перевод строки и возврат коретки 
 
    buf_ db 0    ;буфер для чтения 4 байт
    des1 dw ?          ;хэндл файла который читаем
    des2 dw ?          ;хэндл файла который создается (tmp.tmp)
    kol  dw 0
    stroch  dw 0
                       ;буфер для файл чтения
     max db 254        ;максимально допустимая
     len db 0          ;действительная длина данных
     buf db 254 dup (0);буфер содержит ввод, заканчивающийся символом CR (ASCII 0dH)
 
                       ;буфер для файл записи
    max2 db 254        ;максимально допустимая
    len2 db 0          ;действительная длина данных
    buf2 db 254 dup (0);буфер содержит ввод, заканчивающийся символом CR (ASCII 0dH)
    
dseg ends
cseg segment
assume cs:cseg, ds:dseg, ss:stak
 
.386
start:
                 ;настройка DS на сегмент данных
 mov ax,dseg
 mov ds,ax
 
                ;выводим приглашение 
 lea dx,txt1    ;текст txt1
 call t1        ;процедура вывода текста 
 
                ;запрос на ввод строки имя файла
 mov ah,0ah
 lea dx,max
 int 21h
 jc exit_1

 cmp [len],0  ;если len = 0 значит не вводили в строке а нажали Enter
 jne d1       ;если len <> 0 то d1
 jmp exit_1   ;если 0 то мы ничего ни ввели в командной строке, выход

d1: 
 lea dx,perehod      ;строка perehod
 call t1             ;вывод текста
 
                     ;что то ввели в строке, проверим мож файл?
                     ;для это поместим в конец строки символ с кодом 0
 lea si,buf          ;в SI адрес буфера buf
 xor bx,bx           ;обнулим BX
 mov bl,[len]        ;длину строки LEN в BL
 mov al,0            ;сделаем AL = 0
 mov ds:[si+bx],al   ;в строке которую мы ввели в конце есть символ 0Dh, адрес ее это буфер buf + дина LEN
                     ;положим туда AL, а это 0, для открытия файла   

                     ;AL = режим открытия, AL = 0 чтобы открыть для чтения
 mov ax,3d00h
 lea dx,buf          ;имя файлов, может включать и путь 
 int 21h
 jnc create_file     ;если не было ошибок при открытии

                   ;если файла нет или ошибка была при открытии,выводим текст txt3
 lea dx,txt3
 call t1
 jmp exit_dos      ;на метку, выход в дос

                   ;не было ошибок открытия, продолжаем 
create_file:
                   ;сохраним хэндл файла (описатель)
 mov [des1],ax
 
                   ;выводим приглашение 
 lea dx,txt5       ;текст txt5
 call t1           ;процедура вывода текста 
 
                   ;опрос на ввода имени для записи  
 mov ah,0ah
 lea dx,max2
 int 21h 
 jnc create2       ;если были ошибки, то закроем файл 1 и выходим      
 
 cmp [len2],0      ;если len2 <> 0 то d1
 je close2

create2: 
 lea dx,perehod    ;строка perehod
 call t1           ;вывод текста
 
                   ;подготовка к созданию файла
                   ;что то ввели в строке, проверим мож файл?
                   ;для это поместим в конец строки символ с кодом 0
 lea si,buf2       ;в SI адрес буфера buf2
 xor bx,bx            ;обнулим BX
 mov bl,[len2]        ;длину строки LEN в BL
 mov al,0             ;сделаем AL = 0
 mov ds:[si+bx],al    ;в строке которую мы ввели в конце есть символ 0Dh, адрес ее это буфер buf + дина LEN
                      ;положим туда AL, а это 0, для открытия файла   
                                     
                      ;создадим файл указанный в строке buf2
                      ;Вход AH = 3cH
                      ;DS:DX = адрес строки ASCIIZ с именем файла
                      ;CX = атрибут файла
 mov ah,3ch 
 mov cx,20h
 lea dx,buf2
 int 21h
 jnc vse_ok           ;не было ошибок при создании файла
 
                      ;если ошибки при создании файл 
 lea dx,txt4
 call t1 
 jmp close2  ;на метку закрытия первого файла

vse_ok:
                      ;сохраним хэндл файла (описатель) (tmp.tmp)
 mov [des2],ax

                      ;организуем цикл для чтения и записи
 lea dx,txt6
 call t1
 
 mov ah,42h
 mov bx,[des1]
 mov al,0
 mov cx,0
 mov dx,10
 int 21h
 
cikl: 
 
 mov ah,3fh
 mov bx,[des1]
 lea dx,buf_
 push dx
 mov cx,1
 int 21h  
 jc close1 ;если при чтении файла была ошибка то на метку close1
 
                     ;при чтении в AX возсращается реальное считанное кол-во байт
                     ;если 0 то закрываем файлы 
 cmp ax,0
 je close1
 
                     ;если встретили не конец строки 
 cmp [buf_],0Dh
 jne write1
 
                     ;если встретили конец строки 
 jmp close1 

write1:
; Здесь вывод символа на экран но он не работает!!! точнее работает не коректно!  
  pop dx
  push ax
  mov ax,dx  
  add ax,41h                
  int 29h
  pop ax
; запись в файл ... (работает)
 mov cx,ax 
 mov ah,40h
 mov bx,[des2]
 lea dx,buf_
 int 21h
 
 mov bp,[kol]
 cmp bp,19
 jz short close1
 inc bp
 mov [kol],bp
 
 mov bp,[stroch]
 cmp bp,3
 jz short otv
 inc bp
 mov [stroch],bp
                      ;прыгаем на метку cikl 
 jmp cikl
 
otv:
 mov ah,40h
 mov bx,[des2] 
 lea dx,perehod
 mov cx,2
 int 21h
 
 mov bp,0
 mov [stroch],bp
 jmp cikl  
 
;закрываем файл (временный файл tmp.tmp) 
close1:
;Вход AH = 3eH
;BX = описатель файла
 mov ah,3eh
 mov bx,[des2]
 int 21h 
   
;закрываем файл (который указан в командной строке)  
close2:
;Вход AH = 3eH
;BX = описатель файла
 mov ah,3eh
 mov bx,[des1]
 int 21h 
 jmp exit_dos ;на метку выход

exit_1:
   lea dx,txt2      ;не ввели что либо в строке при опросе, выводим текст txt2
   call t1

exit_dos:           ;выход в дос 
   mov ax,4c00h
   int 21h

t1 proc             ;процедура вывода текста, в DX уже есть строка
   mov ah,09h
   int 21h
   ret 
t1 endp 
 
cseg ends 

end start

Решение задачи: «Вывод символьной строки на экран»

textual
Листинг программы
model small
 stack 256
dataseg
   txt1 db 'File Name Read: ',0dh,0ah,'$'          ;текст перед запросом на имя файла
   txt2 db 'Not Enter FileName!',0dh,0ah,'$'       ;неуказано ничего в командной строке, например нажали Enter просто
   txt3 db 'Open File Error!',0dh,0ah,'$'          ;ошибка открытия файла
   txt4 db 'Error Create File!',0dh,0ah,'$'        ;ошибка создания файла
   txt5 db 'File Name Write: ',0dh,0ah,'$'         ;текст перед запросом на имя файла
   txt6 db 'Stroka simvolov v file: ',0dh,0ah,'$'  ;символы записываемые в файл
   perehod db 0dh,0ah,'$'                          ;перевод строки и возврат коретки 
 
    buf_ db 0          ;буфер для чтения 4 байт
    des1 dw ?          ;хэндл файла который читаем
    des2 dw ?          ;хэндл файла который создается (tmp.tmp)
    kol  dw 0
    stroch  dw 0
                       ;буфер для файл чтения
     max db 254        ;максимально допустимая
     len db 0          ;действительная длина данных
     buf db 254 dup (0);буфер содержит ввод, заканчивающийся символом CR (ASCII 0dH)
 
                       ;буфер для файл записи
    max2 db 254        ;максимально допустимая
    len2 db 0          ;действительная длина данных
    buf2 db 254 dup (0);буфер содержит ввод, заканчивающийся символом CR (ASCII 0dH)
 
codeseg
 .386
start:
                 ;настройка DS на сегмент данных
 mov ax,@data
 mov ds,ax
 
                ;выводим приглашение 
 lea dx,txt1    ;текст txt1
 call t1        ;процедура вывода текста 
 
                ;запрос на ввод строки имя файла
 mov ah,0ah
 lea dx,max
 int 21h
 jc exit_1
 
 
 cmp [len],0  ;если len = 0 значит не вводили в строке а нажали Enter
 jne d1       ;если len <> 0 то d1
 jmp exit_1   ;если 0 то мы ничего ни ввели в командной строке, выход
 
 
d1: 
 lea dx,perehod      ;строка perehod
 call t1             ;вывод текста
 
                     ;что то ввели в строке, проверим мож файл?
                     ;для это поместим в конец строки символ с кодом 0
 lea si,buf          ;в SI адрес буфера buf
 xor bx,bx           ;обнулим BX
 mov bl,[len]        ;длину строки LEN в BL
 mov al,0            ;сделаем AL = 0
 mov ds:[si+bx],al   ;в строке которую мы ввели в конце есть символ 0Dh, адрес ее это буфер buf + дина LEN
                     ;положим туда AL, а это 0, для открытия файла   
                     
 
                     ;AL = режим открытия, AL = 0 чтобы открыть для чтения
 mov ax,3d00h
 lea dx,buf          ;имя файлов, может включать и путь 
 int 21h
 jnc create_file     ;если не было ошибок при открытии
 
 
                   ;если файла нет или ошибка была при открытии,выводим текст txt3
 lea dx,txt3
 call t1
 jmp exit_dos      ;на метку, выход в дос
 
 
                   ;не было ошибок открытия, продолжаем 
create_file:
                   ;сохраним хэндл файла (описатель)
 mov [des1],ax
 
                   ;выводим приглашение 
 lea dx,txt5       ;текст txt5
 call t1           ;процедура вывода текста 
 
                   ;опрос на ввода имени для записи  
 mov ah,0ah
 lea dx,max2
 int 21h 
 jnc create2       ;если были ошибки, то закроем файл 1 и выходим      
 
 cmp [len2],0      ;если len2 <> 0 то d1
 je close2
 
 
create2: 
 lea dx,perehod    ;строка perehod
 call t1           ;вывод текста
 
                   ;подготовка к созданию файла
                   ;что то ввели в строке, проверим мож файл?
                   ;для это поместим в конец строки символ с кодом 0
 lea si,buf2       ;в SI адрес буфера buf2
 xor bx,bx            ;обнулим BX
 mov bl,[len2]        ;длину строки LEN в BL
 mov al,0             ;сделаем AL = 0
 mov ds:[si+bx],al    ;в строке которую мы ввели в конце есть символ 0Dh, адрес ее это буфер buf + дина LEN
                      ;положим туда AL, а это 0, для открытия файла   
                                     
                      ;создадим файл указанный в строке buf2
                      ;Вход AH = 3cH
                      ;DS:DX = адрес строки ASCIIZ с именем файла
                      ;CX = атрибут файла
 mov ah,3ch 
 mov cx,20h
 lea dx,buf2
 int 21h
 jnc vse_ok           ;не было ошибок при создании файла
 
                      ;если ошибки при создании файл 
 lea dx,txt4
 call t1 
 jmp close2  ;на метку закрытия первого файла
 
 
vse_ok:
                      ;сохраним хэндл файла (описатель) (tmp.tmp)
 mov [des2],ax
 
 
 
 
 
                      ;организуем цикл для чтения и записи
 lea dx,txt6
 call t1
 
 mov ah,42h
 mov bx,[des1]
 mov al,0
 mov cx,0
 mov dx,10
 int 21h
 
cikl: 
 
 mov ah,3fh
 mov bx,[des1]
 lea dx,buf_
; push dx
 mov cx,1
 int 21h  
 jc close1 ;если при чтении файла была ошибка то на метку close1
 
                     ;при чтении в AX возсращается реальное считанное кол-во байт
                     ;если 0 то закрываем файлы 
 cmp ax,0
 je close1
 
                     ;если встретили не конец строки 
 cmp [buf_],0Dh
 jne write1
 
                     ;если встретили конец строки 
 jmp close1 
 
 
                
write1:
; Здесь вывод символа на экран но он не работает!!! точнее работает не коректно!  
;pop dx
  push ax
; mov ax,dx  
  mov al,[buf_]
;add ax,41h                
  int 29h
  pop ax
 
;запись в файл ... (работает)
 mov cx,ax 
 mov ah,40h
 mov bx,[des2]
 lea dx,buf_
 int 21h
 
 mov bp,[kol]
 cmp bp,19
 jz short close1
 inc bp
 mov [kol],bp
 
 mov bp,[stroch]
 cmp bp,3
 jz short otv
 inc bp
 mov [stroch],bp
                      ;прыгаем на метку cikl 
 jmp cikl
 
otv:
 mov ah,40h
 mov bx,[des2] 
 lea dx,perehod
 mov cx,2
 int 21h
 
 mov bp,0
 mov [stroch],bp
 jmp cikl  
 
;закрываем файл (временный файл tmp.tmp) 
close1:
;Вход AH = 3eH
;BX = описатель файла
 mov ah,3eh
 mov bx,[des2]
 int 21h 
   
;закрываем файл (который указан в командной строке)  
close2:
;Вход AH = 3eH
;BX = описатель файла
 mov ah,3eh
 mov bx,[des1]
 int 21h 
 jmp exit_dos ;на метку выход
 
 
 
exit_1:
   lea dx,txt2      ;не ввели что либо в строке при опросе, выводим текст txt2
   call t1
 
 
exit_dos:           ;выход в дос 
   mov ax,4c00h
   int 21h
 
 
t1 proc             ;процедура вывода текста, в DX уже есть строка
   mov ah,09h
   int 21h
   ret 
t1 endp
 
end start

Объяснение кода листинга программы

Этот код на языке Assembler выполняет следующие действия:

  1. Запрос на ввод строки имени файла.
  2. Если введено что-то, код проверяет, является ли это именем файла. Если да, то в конце строки добавляется символ 0Dh.
  3. Код открывает файл для чтения и записи, используя введенное имя файла.
  4. Если файл не может быть открыт, код выводит сообщение об ошибке и закрывает файл.
  5. Если файл успешно открыт, код начинает цикл чтения и записи данных из файла в буфер.
  6. В цикле, каждый символ из файла выводится на экран и записывается обратно в файл.
  7. Когда достигается конец строки, код выводит сообщение об успешном завершении операции.
  8. Если в процессе чтения или записи возникают ошибки, код закрывает файлы и выводит сообщение об ошибке.
  9. В конце работы программы, код закрывает оба файла и завершает работу.

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


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

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

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