Консультация № 159263
31.01.2009, 14:49
0.00 руб.
0 7 1
Здравствуйте. Учусь по книге Калашникова. Сейчас пытаюсь выполнить программу из листинга 8.5 - работа с файлами. Программа не доходит до прерывания выхода и повторяет чтение много-много раз. В конце текста еще добавляется всякий мусор.

Как это можно исправить?

Сейчас проверил свой код, исправил грамматическую ошибку, и теперь он полностью соответствует коду из листинга. Теперь содержимое файла вовсе не выводиться. Под AFD отладчиком после вызова 21 прерывания сегмент кода меняется. В чем может быть причина?

И еще вопрос по кирилице в досе. У меня она не отображается. Как заставить машину отображать кирилицу корректно? На старом компе я для этого биос прошивал, но сейчас карточка другая, там наверное это не прокатит. Какие есть способы?

Приложение:
листинг 8.5

CSEG segment

assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG

org 100h

;начало

Begin: mov ax,3D00h

mov dx,offset File_name

int 21h

jc Error_file

mov Handle,ax

mov bx,ax

mov ah,3Fh

mov cx,0FF00h

mov dx,offset Buffer

int 21h

mov ah,3Eh

mov bx,Handle

int 21h

mov dx,offset Mess_ok

Out_prog:

mov ah,9

int 21h

int 20h

Error_file:

mov dx,offset Mess_error

jmp Out_prog

;конец

Handle dw 0

Mess_ok db 'Файл загружен в память! Смотрите в отладчике!$'

Mess_error db 'Не удалось открыть (найти) файл '

File_name db 'c:\msdos.sys',0,'!$' ;здесь у меня была ошибка. для чего нужен нуль после имени файла и в связи с чем используется такой тип записи?

Buffer equ $

CSEG ends

end Begin

Обсуждение

давно
Посетитель
7438
7205
31.01.2009, 16:08
общий
это ответ
Здравствуйте, Kronos!
Не самый удачный файл выбран для чтения... Под XP длина файла msdos.sys равна 0!
0 после имени требуется для функции открытия файла.
А $ для 9 функции вывода строки на экран.
Чтобы отображать кирилицу, надо писать в кодировке ДОС-а (или перекодировать)
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
31.01.2009, 16:14
общий
Адрес файла поменял на другой, теперь код выглядит так:

Код:
CSEG segment

assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG

org 100h

;начало

Begin: mov ax,3D00h

mov dx,offset File_name

int 21h

jc Error_file

mov Handle,ax

mov bx,ax

mov ah,3Fh

mov cx,0FF00h

mov dx,offset Buffer

int 21h

mov ah,3Eh

mov bx,Handle

int 21h

mov dx,offset Mess_ok

Out_prog:

mov ah,9

int 21h

int 20h

Error_file:

mov dx,offset Mess_error

jmp Out_prog

;конец

Handle dw 0

Mess_ok db 'Файл загружен в память! Смотрите в отладчике!$'

Mess_error db 'Не удалось открыть (найти) файл '

File_name db 'd:\doc.txt',0,'!$'

Buffer equ $

CSEG ends

end Begin


но все-равно ничего.


Можно подробнее про кодировку ДОС и перекодировку?
Неизвестный
31.01.2009, 16:15
общий
содержимое дока:

Код:
Experience faster, easier, and safer browsing today
Download the latest version of Windows Internet Explorer 8 today
Download free trials today
Explore and evaluate great Microsoft products for your company
Windows Live Photo Gallery
Manage and edit your photos,then publish them online to share or print
Get free online chat support
Sign up for Small Business+ and receive free online support on Microsoft products
Experience Zune 3.0: Download a free Zune Pass trial and find musical connections, latest releases, and personalized recommendations
Microsoft .NET Framework 3.5 SP1: Get more controls, improved start-up performance, AJAX support, and more
давно
Посетитель
7438
7205
31.01.2009, 21:02
общий
Так программа только читает файл.
Если надо вывести на экран, так это надо реализовать.
Можно по разному, например, так

Код:
mov ah,3Fh
mov cx,0F800h ;вообще говоря, 0ff00h - много
mov dx,offset Buffer
int 21h ;читаем файл
mov cx,ax ; длина файла
mov ah,3Eh
mov bx,Handle
int 21h ;закрываем

mov ah,40h
lea dx,Buffer ;буфер, в cx - длина буфера
mov bx,1 ;стандартное выходное устройство - экран
int 21h ;выводим на экран

mov dx,offset Mess_ok


Насчет кодировки...
В Windows используеся кодировка ANSI, в ДОС-е и в консоли Windows (по-умолчанию) - ASCII
Поэтому надо, чтобы русский текст был в кодировке ASCII
Можно либо сразу писать в ASCII (в ДОС-овском редакторе либо некоторых Windows-редакторах, которые тоже это умеют)
Либо перекодировать ANSI-текст (в тех же Windows-редакторах, которые понимают ASCII-код)
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
01.02.2009, 02:28
общий
С кодировками разобрался - спасибо большое :)

Еще можно по-подробнее остановиться на коде?

не совсем ясно зачем после функции 3F, 21-го прерывания вставлять mov cx,ax и mov dx,offset Buffer ?

и как вычеслять нужное количество читаемых байт? я смотрел размер текстового файла, он был 666 байт - 29Ah, это я потом заносил в cx, правильно ли это?

Спрошу еще на всякий случай, если нужно будет загрузить файл больше 64кб, это можно будет реализовать уже в exe-шных файлах и видимо по книге будет дальше?
давно
Посетитель
7438
7205
01.02.2009, 22:02
общий
Функция чтения 3fh возвращает в AX количество реально прочитанных байт
А функция записи 40h требует в CX длину буфера, а в DX - адрес буфера.
Поэтому и пишем mov cx,ax и mov dx,offset Buffer, хотя вторая команда, фактически, не нужна:
DX и так указывает на Buffer после чтения файла.

С файлами большой длины можно работать в любых программах, формат (COM/EXE) не важен.
А вообще, с большим файлом можно работать по-разному:
1) Если файл больше 64к, но меньше всей доступной памяти, то, в принципе,
можно последовательно прочитать в память, меняя сегмент буфера.
Причем, не надо забывать, что в программный сегмент нельзя читать ровно 64к, иначе затрется и стек, и PSP, и сама программа
2) Можно последовательно читать кусками, например, по 32к, в один и тот же буфер.
Так можно читать файл любой длины.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
03.02.2009, 01:24
общий
Ясно! Спасибо большое за помощь! :)
Форма ответа