Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





С консольным типом Windows-приложений мы уже встречались в предыдущих
главах. Приложения консоли используются, как правило, тогда, когда
для выполнения каких-либо действий не требуется графический интерфейс.
Очень часто с помощью консольных приложений выполняют функции перемещения и копирования данных. Многие системные службы спроектированы как консольные приложения.

Мне хотелось бы привести в качестве примера простейшую программу на
ассемблере, выполняющую копирование данных из одного файла в другой.
В ЭТОМ Примере ИСПОЛЬЗУЮТСЯ функции WIN API CreateFile, ReadFile И
writeFiie для работы с файлами. В общем случае копирование файлов выполняется
в несколько этапов. Вначале открывается исходный файл для
считывания данных в буфер памяти. Затем создается файл, куда будут записаны
данные. После этого выполняется собственно копирование данных.

Наконец, по завершению операции копирования файлы должны быть закрыты.
Рассмотрим синтаксис функций файлового ввода-вывода. Начнем с CreateFile.
Функция объявляется следующим образом:
HANDLE CreateFile(LPCTSTR lpFileName,
DWORD dwAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES
DWORD
DWORD
HANDLE
// имя файла
// тип доступа к файлу
// способ совместного
// доступа к файлу
IpSecurityAttributes, // указатель на структуру
// SECURITY_ATTRIBUTES
dwCreationDisposition, // способ создания файла
dwFlagsAndAttributes, // аттрибуты создания
// файла
TemplateFile // дескриптор шаблона файла
Функция CreateFile в случае успешного завершения возвращает дескриптор
вновь созданного объекта. Функция ReadFile считывает данные из
файла, начиная с позиции, обозначенной указателем файла. После считывания
данных указатель файла сдвигается на число считанных байтов. Синтаксис
этой функции:
BOOL ReadFile(HANDLE hFile,
LPVOID lpBuffer,
// дескриптор файла
// буфер данных
DWORD nNumberOfBytesToRead, // количество байт,
// которое необходимо считать
LPDWORD lpNumberOfBytesRead, // количество прочитанных байт
LPOVERLAPPED lpOverlapped // указатель на
// структуру OVERLAPPED
);

Для записи данных в файл используется функция writeFile. Она имеет
синтаксис: ,
BOOL WriteFile(HANDLE hFile, // дескриптор файла
LPCVOID lpBuffer, // буфер данных
DWORD nNumberOfBytesToWrite, // количество байт,
// которые необходимо записать
LPDWORD lpNumberOfBytesWritten, // количество фактически
// записанных байт
LPOVERLAPPED lpOverlapped // указатель на
// структуру OVERLAPPED
) ;

Исходный текст приложения (назовем его CPFILE) приведен в листинге 5.28.
Листинг 5.28. Консольное приложение, копирующее данные одного файла
другой
CPFILE.ASM
.386
.model flat, stdcaii
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
src
dst
DB "src.txt", 0
DB "dst.txt", 0
BUF_SIZE EQU 512
buf DB 102
BytesRead DD 0
BytesWritten DD 0
sHandle DD 0
dHandle DD 0
. code
start:

попытка открыть файл с именем в src для чтения
push 0
push FILE_ATTRIBUTE_NORMAL
push OPEN_EXISTING
push 0
push 0
push GENERIC_READ
push offset src 1
call CreateFile
; если удалось открыть файл, сохраняем полученный дескриптор
; в переменной sHandle, иначе выходим из программы
cmp ЕАХ, INVALID_HANDLE_VALUE
je ex
mov sHandle, EAX
; попытка создания файла с именем в dst для записи
push 0
push FILE_ATTRIBUTE_NORMAL
push CREATE_ALWAYS
push 0
push 0
push GENERIC_WRITE
push offset dst
call CreateFile
push sHandle
cmp ЕАХ, INVALID_HANDLE_VALUE
; если файл удалось создать, сохраняем его дескриптор
; в переменной dHandle, иначе выходим из программы
je ex
mov dHandle, EAX
; цикл, в котором выполняется копирование файлов
сру_1оор:
push О
push offset BytesRead
push BUF_SIZE
push offset buf
push sHandle
; чтение данных файла-источника в буфер памяти
call ReadFile
; Если все прочитано, то выходим из цикла
; Иначе записываем прочитанные данные в файл-приемник
cmp BytesRead, О
j е end_cpy
push О
push offset BytesWritten
push BytesRead
push offset buf
push dHandle
call WriteFile
jmp cpy_loop
end_cpy:
; после копирования закрываем файлы с помощью функции CloseHandle
420 Гпава 5
call CloseHandle
push dHandle
call CloseHandle
ex:
push 0
call ExitProcess
end start


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru