Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf

ВУЗ: Не указан

Категория: Книга

Дисциплина: Программирование

Добавлен: 16.02.2019

Просмотров: 29213

Скачиваний: 1689

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 

Часть II. Усложняем задачи 

82 

cx

 —  количество  читаемых  или  записываемых  байтов, 

ds:dx

 —  адрес  буфера  для 

чтения/записи. Пример чтения файла в память с использованием функции 

40h

 при-

веден в разд. 8.3.  

8.3. Программа для практики 

Чтобы  полностью  понять  приведенный  далее  пример,  придется  рассмотреть 

много нового. В данном случае мы поступим так же, как и в главе 1: о некоторых 
операторах (командах) скажем позже. 

Итак, в листинге 8.5 приведен образец чтения файла (до 65 000 (0FDE8h) байт)  

в память, а точнее, в наш сегмент (\008\prog08.asm). 

Листинг 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,0FDE8h 
       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 


background image

Глава 8. Учимся работать с файлами 

83 

       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 

Из  этого  примера  вы  узнаете  очень  много.  Чтобы  досконально  разобраться  

в  этой  программе,  необходимо,  как  обычно,  воспользоваться  отладчиком.  В  нем 
внимательно изучайте дамп (содержимое) памяти, на который указывает пара реги-
стров 

ds:dx

 


background image

 

 

 

Глава 9 

 

Работа с файлами 

 

9.1. Программа из прошлой главы 

В листинге 9.1 приведены выдержки программы из главы 8 с комментариями. 

Листинг 9.1. Программа из главы 8 

... 
;Опустим код CSEG и пр. 
(01) Begin: mov ax,3D00h    ;будем открывать файл для чтения 
;Обратите внимание, как мы записываем операторы (сразу за меткой). 
 
(02)    mov dx,offset File_name 

;ds:dx указывают на путь к файлу 

(03)    int 21h             ;открываем 
(04)    jc Error_file 
;Если произошла ошибка (нет такого файла, слишком много открытых файлов, 
;ошибка чтения), то переходим на метку Error_file 
 
;Запомним номер файла в переменной Handle. 
;Для того чтобы прочитать файл, нужно в bx указать его номер, полученный 
;после открытия, который находится в ax. Загрузка числа в один регистр из 
;другого (а тем более, если используется ax) происходит быстрее, чем 
;из памяти (переменной). Поэтому загружаем из ax, а не из переменной. Хотя 
;запись mov bx,Handle не будет ошибочной. 
(05)    mov Handle,ax       ;запомним номер файла в переменной Handle 
(06)    mov bx,ax 
(07)    mov ah,3Fh          ;функция 3Fh — чтение файла 
(08)    mov cx,0FDE8h       ;будем читать 0FDE8h = 65000 байт 
;ds:dx должен указывать на буфер в памяти для чтения 
(09)    mov dx,offset Buffer 
(10)    int 21h             ;все готово. Читаем... 
 
(11)    mov ah,3Eh          ;закрываем файл 


background image

Глава 9. Работа с файлами 

85 

;Номер файла должен находиться в bx. Но т. к. регистр bx менялся, то 

;загрузим его с нашей переменной (Handle) 

(12)    mov bx,Handle 

(13)    int 21h             ;закрываем файл 

 

;загрузим в dx строку с сообщением о том, что все в порядке. 

(14)    mov dx,offset Mess_ok 

 

(15)Out_prog: mov ah,9      ;функция 09h — вывод строки на экран 

(16)    int 21h             ;выводим строку 

 

(17)    int 20h             ;выходим из программы 

 

;Загрузим в dx строку с сообщением о том, что не смогли открыть файл... 

(18)Error_file: mov dx,offset Mess_error 

 

;...и пойдем на метку Out_prog (зачем нам дублировать код, если он уже есть?) 

(19)    jmp Out_prog 

 

;=== Данные === 

(20) Handle dw 0            ;резерв 2 байта для нашей переменной 

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

;Строки (22)—(23) рассмотрим ниже 

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

(23) File_name  db 'c:\msdos.sys',0,'!$' 

(24) Buffer equ $ 

... 

Запомните  оператор 

$

,  который нами впервые используется в строке (24). При 

ассемблировании нашей программы ассемблер заменит этот знак адресом, по кото-
рому он расположен (листинг 9.2). 

Листинг 9.2. Использование оператора $ 

(01) CSEG segment 

(02) assume cs:CSEG 

(03) org 100h 

 

(04) Begin: 

(05)        My_lab equ $ 

(06)        My_lab2 equ $+2 

(07)        mov bx,offset My_lab 


background image

 

Часть II. Усложняем задачи 

86 

(08)        mov dx,offset My_lab2 
(09)        int 20h 
 
(10) CSEG ends 
(11) end Begin 

Строки  (5)  и  (6)  места  в  памяти  не  занимают  (как  и  метки).  Ассемблер-

программа запомнит, что метка 

My_lab

 находится по адресу 

100h

 (

org 100h

), а мет-

ка 

My_lab2

 — 

102h

.  На  рис. 9.1  показан  фрагмент  приведенной  выше  программы, 

который иллюстрирует использование оператора 

$

 

Рис. 9.1. Использование оператора $ 

В программе из главы 8 мы размещаем метку 

Buffer

 в конце кода. Таким обра-

зом, команда 

mov dx,offset Buffer

 занесет в 

dx

 последний свободный байт в нашем 

сегменте 

CSEG

. По этому адресу мы и будем загружать программу в память. В от-

ладчике это хорошо видно. 

В строке (22) находится переменная с сообщением о том, что файл открыть не-

возможно. Однако она не заканчивается символом 

$

, как обычно. Это значит, что 

функция 

09h 

прерывания 

21h

 продолжит выводить символы до тех пор, пока в па-

мяти не встретится этот символ. Если мы посмотрим на строку (23), то увидим, что 
она как раз заканчивается знаком 

$

. Это значит, что при выводе символов из строки 

(22) функция выведет также и те символы, которые находятся в строке (23). 

(22) Mess_error db 'Не удалось открыть (найти) файл ' 
(23) File_name db 'c:\msdos.sys',0,'!$' 

Если файл не был найден, функция 

09h

 выведет на экран буквально следующее 

(рис. 9.2): 

Не удалось открыть (найти) файл c:\msdos.sys !