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