Вывод символьной строки на экран - 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 выполняет следующие действия:
- Запрос на ввод строки имени файла.
- Если введено что-то, код проверяет, является ли это именем файла. Если да, то в конце строки добавляется символ 0Dh.
- Код открывает файл для чтения и записи, используя введенное имя файла.
- Если файл не может быть открыт, код выводит сообщение об ошибке и закрывает файл.
- Если файл успешно открыт, код начинает цикл чтения и записи данных из файла в буфер.
- В цикле, каждый символ из файла выводится на экран и записывается обратно в файл.
- Когда достигается конец строки, код выводит сообщение об успешном завершении операции.
- Если в процессе чтения или записи возникают ошибки, код закрывает файлы и выводит сообщение об ошибке.
- В конце работы программы, код закрывает оба файла и завершает работу.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д