| [Назад] [Далее] | ![]() |
Теперь, когда мы знаем, как строятся программы с меню и диалогами, напишем одно настоящее полноценное приложение, включающее в себя все то, что требуется от программы, — меню, диалоги, комбинации клавиш для быстрого доступа к элементам меню и т.д. В качестве примера создадим простой текстовый редактор, аналогичный Notepad. В этом примере мы увидим, как получить параметры из командной строки, прочитать и записать файл, выделить и освободить память.
// winpad95.rc
// Файл ресурсов для программы winpad95.asm
// идентификаторы сообщений от пунктов меню
#define IDM_NEW 0x1001
#define IDM_OPEN 0x101L
#define IDM_SAVE 0x102L
#define IDM_SAVEAS 0x103L
#define IDM_EXIT 0x104L
#define IDM_ABOUT 0x105L
#define IDM_UNDO 0x106L
#define IDM_CUT 0x107L
#define IDM_COPY 0x108L
#define IDM_PASTE 0x109L
#define IDM_CLEAR 0x10AL
#define IDM_SETSEL 0x10BL
// идентификаторы основных ресурсов
#define IDJ1ENU 0x700L
#define ID_ACCEL 0x701L
#define ID_ABOUT 0x702L
// если есть иконка - можно раскомментировать эти две строки
// #define ID_ICON 0x703L
// ID_ICON ICON "winpad95.ico"
// основное меню
ID_MENU MENU DISCARDABLE {
POPUP "&File" {
MENUITEM "&New\tCtrl+N", IDM_NEW
MENUITEM "&Open...\tCtrl+O", IDM_OPEN
MENUITEM "&Save\tCtrl+S", IDM_SAVE
MENUITEM "Save &As...\tCtrl+Shift+S", IDM_SAVEAS
MENUITEM SEPARATOR
MENUITEM "E&xit\tCtrl+Q", IDM_EXIT
}
POPUP "&Edit" {
MENUITEM "&Undo\tCtrl-Z", IDM_UNDO
MENUITEM SEPARATOR
MENUITEM "Cu&t\tCtrl-X", IDM_CUT
MENUITEM "&Copy\tCtrl-C", IDM_COPY
MENUITEM "&Paste\tCtrl-V", IDM_PASTE
MENUITEM "&Delete\tDel", IDM_CLEAR
MENUITEM SEPARATOR
MENUITEM "Select &All\tCtrl-A", IDM_SETSEL
}
POPUP "&Help" {
MENUITEM "About", IDM_ABOUT
}
}
// комбинации клавиш
ID_ACCEL ACCELERATORS DISCARDABLE {
"N", IDM_NEW, CONTROL, VIRTKEY
"O", IDM_OPEN, CONTROL, VIRTKEY
"S", IDM_SAVE, CONTROL, VIRTKEY
"S", IDM_SAVEAS, CONTROL, SHIFT, VIRTKEY
"Q", IDM_EXIT, CONTROL, VIRTKEY
"Z", IDM_UNDO, CONTROL, VIRTKEY
"A", IDM_SETSEL, CONTROL, VIRTKEY
}
// все эти определения можно заменить на #include <winuser.h>
#define DS_MODALFRAME 0x80L
#define DS_3DLOOK 4
#define WS_POPUP 0x80000000L
#define WS_CAPTION 0xC00000L
#define WS_SYSMENU 0x80000L
#define IDOK 1
#define IDC_STATIC -1
#define IDI_APPLICATION 32512
#define WS_BORDER 0x800000L
// стандартный диалог "About"
ID_ABOUT DIALOG DISCARDABLE 0, 0, 125, 75
STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About Asmpad95"
{
ICON IDI_APPLICATION,IDC_STATIC,12,15,21,20
CTEXT "Asmpad95",IDC_STATIC,0,30,40,8
CTEXT "Prototype notepad-style editor for Windows 95
written entirely in assembly language",IDC_STATIC,45,10,70,45,WS_BORDER
DEFPUSHBUTTON "OK",IDOK,35,60,40,10
}
Теперь рассмотрим текст программы:
; winpad95.asm
; графическое win32-приложение - текстовый редактор
;
include def32.inc
include user32.inc
include kernel32.inc
include comdlg32.inc
ID_MENU equ 700h
ID_ACCEL equ 701h
ID_ABOUT equ 702h
MAXSIZE equ 260 ; максимальное имя файла
MEMSIZE equ 65535 ; максимальный размер временного буфера в памяти
EditID equ 1
.386
.model flat
.const
c_w_name db "Asmpad95",0 ; это и имя класса, и имя основного окна
edit_class db "edit",0 ; предопределенное имя класса для редактора
changes_msg db "Save changes?",0
filter_string db "All Files",0,'*.*',0 ; маски для Get * FileName
db "Text Files",0, '*.txt',0,0
.data
; структура, использующаяся Get * FileName
ofn OPENFILENAME <SIZE ofn,?,?,offset filter_string,?,?,?,offset buffer,\
MAXSIZE,0,?,?,?,?,?,?,0,?,?,?>
; структура, описывающая наш основной класс
wc WNDCLASSEX <SIZE WNDCLASSEX,CS_HREDRAW or CS_VREDRAW,offset win_proc,0,\
0,?,?,?,COLOR_WINDOW+1,ID_MENU,offset c_w_name,0>
flag_untitled db 1 ; = 1, если имя файла не определено (новый файл)
.data?
h_editwindow dd ? ; идентификатор окна редактора
h_accel dd ? ; идентификатор массива акселераторов
p_memory dd ? ; адрес буфера в памяти
SizeReadWrite dd ?
msg_ MSG <>
rec RECT <>
buffer db MAXSIZE dup(?) ; имя файла
window_title db MAXSIZE dup(?), 12 dup(?)
.code
_start:
call GetCommandLine ; получить нашу командную строку
mov edi,eax
mov al,' '
mov ecx,MAXSIZE
repne scasb ; найти конец имени нашей программы
cmp byte ptr [edi],0
je cmdline_empty
mov esi,edi
mov edi,offset buffer
rep movsb
mov flag_untitled,0
cmdline_empty:
; подготовить и зарегистрировать класс
xor ebx,ebx
call GetModuleHandle ; определить наш идентификатор
mov esi,eax
mov wc.hInstance,eax ; и сохранить его в wc.hInstance
mov ofn._hInstance,eax
push IDI_APPLICATION ; или IDI_ICON, если иконка есть в ресурсах,
push ebx ; или esi, если иконка есть в ресурсах
call LoadIcon
mov wc.hIcon,eax
push IDC_ARROW ; предопределенный курсор (стрелка)
push ebx
call LoadCursor
mov wc.hCursor,eax
push offset wc
call RegisterClassEx
; создать основное окно
push ebx
push esi
push ebx
push ebx
push 200
push 300
push CW_USEDEFAULT
push CW_USEDEFAULT
push WS_OVERLAPPEDWINDOW
push offset c_w_name
push offset c_w_name
push WS_EX_CLIENTEDGE
call СreateWindowEx
push eax ; для pop esi перед message_loop
push eax
push SW_SHOWNORMAL
push eax
call ShowWindow
call UpdateWindow
; инициализировать акселераторы
push ID_ACCEL
push esi
call LoadAcceleratоrs
mov h_accel,eax
; цикл ожидания сообщения
pop esi ; ESI - идентификатор основного окна
mov edi,offset msg_ ; EDI - структура с сообщением от него
message_loop:
push ebx
push ebx
push ebx
push edi
call GetMessage ; получить сообщение,
test eax,eax ; если это WM_OUIT, -
jz exit_msg_loop ; выйти из цикла
push edi
push h_accel
push esi ; hWnd
call TranslateAccelerator ; преобразовать акселераторы в IDM*
test eax,eax
jnz message_loop
push edi
call TranslateMessage ; преобразовать сообщения от клавиш
push edi
call DispatchMessage ; и отослать обратно
jmp short message_loop
exit_msg_loop:
push msg_.wParam
call ExitProcess ; конец программы
; процедура win_proc
;
; процедура не должна изменять регистры EBP,EDI,ESI и ЕВХ!
win_proc proc near
; параметры (с учетом push ebp)
wp_hWnd equ dword ptr [ebp+08h]
wp_uMsg equ dword ptr [ebp+0Ch]
wp_wParam equ dword ptr [ebp+10h]
wp_lParam equ dword ptr [ebp+14h]
; инициализируем стековый кадр
push ebp
mov ebp,esp ; создать стековый кадр
pusha ; сохранить все регистры
xor ebx,ebx ; 0 для команд push 0
mov esi,wp_hWnd ; для команд push hWnd
mov eax,wp_uMsg
; обработать пришедшее сообщение
cmp eax,WM_CREATE
je h_wm_create
cmp eax,WM_SIZE
je h_wm_size
cmp eax,WM_DESTROY
je h_wm_destroy
cmp eax,WM_COMMAND
je h_wm_command
cmp eax,WM_ACTIVATE
je h_wm_activate
cmp eax,WM_CLOSE
je h_wm_close
def_proc:
popa
leave ; если это ненужное сообщение,
jmp DefWindowProc ; оставить его обработчику по умолчанию
; обработчик WM_CLOSE,
; если нужно, спрашивает, сохранить ли файл
h_wm_close:
call save_contents
jmp short def_proc
; обработчик WM_CREATE
;
h_wm_create:
; здесь также можно создать toolbar и statusbar
; создать окно редактора
push ebx
push wc.hInstance ; идентификатор основной программы
push EditID
push esi ; hWnd
push ebx ; 0
push ebx ; 0
push ebx ; 0
push ebx ; 0
push WS_VISIBLE or WS_CHILD or ES_LEFT or ES_MULTILINE or \
ES_AUTOHSCROLL or ES_AUTOVSCROLL
push ebx ; 0
push offset edit_class
push ebx ; 0
call CreateWindowEx
mov h_editwindow,eax
; передать ему фокус
push eax
call SetFocus
cmp flag_untitled,1
je continue_create
call skip_getopen ; открыть файл, указанный в командной строке
continue_create:
call set_title
jmp end_wm_check
; обработчик WM_COMMAND
;
h_wm_command:
mov eax,wp_wParam
cwde ; младшее слово содержит IDM_*
sub eax,100h
jb def_proc
; обработать сообщения от пунктов меню
call dword ptr menu_handlers[eax*4]
jmp end_wm_check
menu_handlers
dd offset h_idm_new,offset h_idm_open,offset h_idm_save
dd offset h_idm_saveas,offset h_idm_exit,offset h_idm_about
dd offset h_idm_undo, offset h_idm_cut, offset h_idm_copy
dd offset h_idm_paste, offset h_idm_clear, offset h_idm_setsel
; сообщения от пунктов меню должны быть описаны в win95pad.rc именно в таком
; порядке - от IDM_NEW 100h до IDM_CLEAR 10Ah
h_idm_setsel:
push -1 ; -1
push ebx ; 0
push EM_SETSEL ; выделить весь текст
push h_editwindow
call SendMessage
ret
; обработчики сообщений из меню EDIT:
h_idm_clear:
mov eax,WM_CLEAR
jmp short send_to_editor
h_idm_paste:
mov eax,WM_PASTE
jmp short send_to_editor
h_idm_copy:
mov eax,WM_COPY
jmp short send_to_editor
h_idm_cut:
mov eax,WM_CUT
jmp short send_to_editor
h_idm_undo:
mov eax,EM_UNDO
send_to_editor:
push ebx ; 0
push ebx ; 0
push eax
push h_editwindow
call SendMessage
ret
; обработчик IDM_NEW
h_idm_new:
call save_contents ; записать файл, если нужно
mov byte ptr flag_untitled,1
call set_title ; отметить, что файл не назван
push ebx
push ebx
push WM_SETTEXT
push h_editwindow
call SendMessage ; послать пустой WM_SETTEXT редактору
ret
; обработчик IDM_ABOUT
h_idm_about:
push ebx ; 0
push offset about_proc
push esi ; hWnd
push ID_ABOUT
push wc.hInstance
call DialogBoxParam
ret
; обработчик IDM_SAVEAS и IDM_SAVE
h_idm_save:
cmp flag_untitled, 1 ; если файл назван,
jne skip_getsave ; пропустить вызов GetSaveFileName
h_idm_saveas:
; спросить имя файла
mov ofn.Flags,OFN_EXPLORER or OFN_OVERWRITEPROMPT
push offset ofn
call GetSaveFileName
test eax,eax
jz file_save_failed
skip_getsave:
; создать его
push ebx
push FILE_ATTRIBUTE_ARCHIVE
push CREATE_ALWAYS
push ebx
push FILE_SHARE_READ or FILE_SHARE_WRITE
push GENERIC_READ or GENERIC_WRITE
push offset buffer
call CreateFile
mov edi,eax
; выделить память
push MEMSIZE
push GMEM_MOVEABLE or GMEM_ZEROINIT
call GlobalAlloc
push eax ; hMemory для GlobalFree
push eax ; hMemory для GlobalLock
call GlobalLock
mov esi,eax ; адрес буфера в ESI
; забрать текст из редактора
push esi
push MEMSIZE-1
push WM_GETTEXT
push h_editwindow
call SendMessage
; записать в файл
push esi ; pMemory
call lstrlen
push ebx
push offset SizeReadWrite
push eax ; размер буфера
push esi ; адрес буфера
push edi ; идентификатор файла
call WriteFile
push esi ; pMemory
call GlobalUnlock
call GlobalFree ; hMemory уже в стеке
push edi ; идентификатор файла
call CloseHandle
; сбросить флаг модификации в редакторе
push ebx
push ebx
push EM_SETMODIFY
push h_editwindow
call SendMessage
mov byte ptr flag_untitled,0
call set_title
file_save_failed:
push h_editwindow
call SetFocus
ret
; обработчик IDM_OPEN
h_idm_open:
call save_contents
; вызвать стандартный диалог выбора имени файла
mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or \
OFN_EXPLORER
push offset ofn
call GetOpenFileName
test eax,eax
jz file_open_failed
skip_getopen:
; открыть выбранный файл
push ebx
push FILE_ATTRIBUTE_ARCHIVE
push OPEN_EXISTING
push ebx
push FILE_SHARE_READ or FILE_SHARE_WRITE
push GENERIC_READ or GENERIC_WRITE
push offset buffer
call CreateFile
mov edi,eax ; идентификатор для ReadFile
; выделить память
push MEMSIZE
push GMEM_MOVEABLE or GMEM_ZEROINIT
call GlobalAlloc
push eax ; hMemory для GlobalFree
push eax ; hMemory для GlobalLock
call GlobalLock ; получить адрес выделенной памяти
push eax ; pMemory для GlobalUnlock
push eax ; pMemory для SendMessage
; прочитать файл
push ebx
push offset SizeReadWrite
push MEMSIZE-1
push eax ; pMemory для ReadFile
push edi
call ReadFile
; послать окну редактора сообщение wm_settext, чтобы он забрал текст из буфера
push ebx ; pMemory уже в стеке
push WM_SETTEXT
push h_editwindow
call SendMessage
; а теперь можно закрыть файл и освободить память
call GlobalUnlock ; pMemory уже в стеке
call GlobalFree ; hMemory уже в стеке
push edi ; hFile
call CloseHandle
mov byte ptr flag_untitled,0
call set_title
file_open_failed:
push h_editwindow
call SetFocus
ret
; обработчик IDM_EXIT
h_idm_exit:
call save_contents
push esi ; hWnd
call DestroyWindow ; уничтожить наше окно
ret
; обработчик WM_SIZE
h_wm_size:
; здесь также надо послать WM_SIZE окнам toolbar и statusbar,
; изменить размер окна редактора так, чтобы оно по-прежнему было на все окно
push offset rec
push esi ; hWnd
call GetClientRect
push 1 ; true
push rec. bottom ; height
push rec. right ; width
push ebx ; у
push ebx ; x
push h_editwindow
call MoveWindow
jmp short end_wm_check
; обработчик WM_ACTIVATE
h_wm_activate:
push h_editwindow
call SetFocus
jmp short end_wm_check
; обработчик WM_DESTROY
h_wm_destroy:
push ebx
call PostQuitMessage ; послать WM_QUIT основной программе
; конец процедуры window_proc
end_wm_check:
рора
xor еах,еах ; вернуть 0
leave
ret 16
; процедура set_title
; устанавливает новый заголовок для основного окна
set_title:
push esi
push edi
mov edi, offset window_title
cmp byte ptr flag_untitled,1 ; если у файла нет имени,
je untitled ; использовать Untitled
mov esi,ofn.lpstrFile ; [ESI] - имя файла с путем
movzx eax,ofn.nFileOffset ; eax - начало имени файла
add esi,eax
copy_filename:
lodsb ; скопировать файл побайтно в название окна,
test al,al
jz add_progname ; пока не встретится ноль
stosb
jmp short copy_filename
add_progname:
mov dword ptr [edi],'-' ; приписать минус
add edi,3
mov esi,offset c_w_name
mov ecx,9 ; и название программы
rep movsb
pop edi
pop esi
push offset window_title
push esi ; идентификатор окна
call SetWindowText
ret
untitled:
mov dword ptr [edil'itnU' ; дописать "Unti"
mov dword ptr [edi+4],'delt' ; дописать "tled"
add edi,8
jmp short add_progname
; процедура save_contents
; EBX = 0, ESI = hWnd
save_contents:
; спросить редактор, изменялся ли текст
push ebx
push ebx
push EM_GETMODIFY
push h_editwindow
call SendMessage
test eax,eax
jz not_modified
; спросить пользователя, сохранять ли его
push MB_YESNO + MB_ICONWARNING
push offset c_w_name
push offset changes_msg
push esi
call MessageBox
cmp eax,IDYES
jne not_modified
; сохранить его
call h_idm_save
not_modified:
ret
win_proc endp
about_proc proc near
; параметры (с учетом push ebp)
ap_hDlg equ dword ptr [ebp+08h]
ap_uMsg equ dword ptr [ebp+0Ch]
ap_wParam equ dword ptr [ebp+10h]
ap_lParam equ dword ptr [ebp+14h]
push ebp
mov ebp,esp ; создать стековый кадр
cmp ap_uMsg,WM_COMMAND
jne dont_proceed
cmp ap_wParam,IDOK
jne dont_proceed
push 1
push ap_hDlg
call EndDialog
dont_proceed:
xor eax,eax ; не обрабатывается
leave
ret 16
about_proc endp
end _start
Размер этой программы — 6,5 Кб (скомпилированной ml/link), и даже версия, в которую добавлено все, что есть в Notepad (вывод файла на печать и поиск по тексту), все равно более чем в три раза меньше notepad.exe. Чем большее Windows-приложение создается, тем сильнее сказывается выигрыш в размерах при использовании ассемблера, даже несмотря на то, что мы только вызываем системные функции, практически не занимаясь программированием.
Прежде чем можно будет скомпилировать winpad95.asm, конечно, надо внести необходимые дополнения в наши включаемые файлы.
Добавления в файл def32.inc:
; из winuser.h
WM_CREATE equ 1
WM_ACTIVATE equ 6
WM_SETTEXT equ 0Ch
WM_GETTEXT equ 0Dh
WM_CUT equ 300h
WM_COPY equ 301h
WM_PASTE equ 302h
WM_CLEAR equ 303h
WM_UNDO equ 304h
WM_SIZE equ 5
WS_VISIBLE equ 10000000h
WS_CHILD equ 40000000h
WS_EX_CLIENTEDGE equ 200h
ES_LEFT equ 0
ES_MUITILINE equ 4
ES_AUTOHSCROLL equ 80h
ES_AUTOVSCROLL equ 40h
EM_GETHANDLE equ 0BDh
EM_GETMODIFY equ 0B8h
EM_SETMODIFY equ 0B9h
EM_UNDO equ 0C7h
EM_SETSEL equ 0B1h
MB_YESNO equ 4
MB_ICONWARNING equ 30h
IDOK equ 1
IDYES equ 6
; из winnt.h
GENERIC_READ equ 80000000h
GENERIC_WRITE equ 40000000h
FILE_SHARE_READ equ 1
FILE_SHARE_WRITE equ 2
FILE_ATTRIBUTE_ARCHIVE equ 20h
; из commdlg.h
OFN_PATHMUSTEXIST equ 800h
OFN_FILEMUSTEXIST equ 1000h
OFN_EXPLORER equ 80000h
OFN_OVERWRITEPROMPT equ 2
OPENFILENAME struc
IStructSize dd ?
hwndOwner dd ?
_hInstance dd ?
lpstrFilter dd ?
lpstrCustomFilter dd ?
nMaxCustFilter dd ?
nFilterlndex dd ?
lpstrFile dd ?
nMaxFile dd ?
lpstrFileTitle dd ?
nMaxFileTitle dd ?
lpstrInitialDir dd ?
lpstrTitle dd ?
Flags dd ?
nFileOffset dw ?
nFileExtension dw ?
lpstrDefExt dd ?
lCustData dd ?
lpfnHook dd ?
lpTemplateName dd ?
OPENFILENAME ends
; из windef.h
RECT struc
left dd ?
top dd ?
right dd ?
bottom dd ?
RECT ends
; из winbase.h
GMEM_MOVEABLE equ 2
GMEM_ZEROINIT equ 40h
OPEN_EXISTING equ 3
CREATE_ALWAYS equ 2
Добавления в файл kernel32.inc между ifdef _TASM_ и else:
extrn lstrlen:near
extrn GetCommandLineA:near
extrn CloseHandle:near
extrn GlobalAlloc:near
extrn GlobalLock:near
extrn GlobalFree:near
extrn CreateFileA:near
extrn ReadFile:near
extrn WriteFile:near
GetCommandLine equ GetCommandLineA
CreateFile equ CreateFileA
и между else и endif:
extrn __imp__lstrlen@4:dword
extrn __imp__GetCommandLineA@0:dword
extrn __imp__CloseHandle@4:dword
extrn __imp__GlobalAlloc@8:dword
extrn __imp__GlobalLock@4:dword
extrn __imp__GlobalFree@4:dword
extrn __imp__CreateFileA@28:dword
extrn __imp__ReadFile@20:dword
extrn __imp__WriteFile@20:dword
lstrlen equ __imp__lstrlen@4
GetCommandLine equ __imp__GetCommandLineA@0
CloseHandle equ __imp__CloseHandle@4
GlobalAlloc equ __imp__GlobalAlloc@8
GlobalLock equ __imp__GlobalLock@4
GlobalFree equ __imp__GlobalFree@4
CreateFile equ __imp__CreateFileA@28
ReadFile equ __imp__ReadFile@20
WriteFile equ __imp__WriteFile@20
Добавления в файл user32.inc:
extrn LoadAcceleratorsA:near
extrn TranslateAccelerator:near
extrn SendMessageA:near
extrn SetWindowTextA:near
extrn MoveWindow:near
extrn GetClientRect:near
extrn GlobalUnlock:near
LoadAccelerators equ LoadAcceleratorsA
SendMessage equ SendMessageA
SetWindowText equ SetWindowTextA
и между else и endif:
extrn __imp__LoadAcceleratorsA@8:dword
extrn __imp__ТranslateAccelerator@12:dword
extrn __imp__SendMessageA@16:dword
extrn __imp__SetWindowTextA@8:dword
extrn __imp__MoveWindow@24:dword
extrn __imp__GetClientRect@8:dword
extrn __imp__GlobalUnlock@4:dword
LoadAccelerators equ __imp__LoadAcceleratorsA@8
TranslateAccelerator equ __imp__TranslateAccelerator@12
SendMessage equ __imp__SendMessageA@16
SetWindowText equ __imp__SetWindowTextA@8
MoveWindow equ __imp__MoveWindow@24
GetClientRect equ __imp__GetClientRect@8
GlobalUnlock equ __imp__GlobalUnlock@4
Кроме того, нам потребуется новый включаемый файл, comdlg32.inc, описывающий функции, связанные с вызовами стандартных диалогов (выбор имени файла, печать документа, выбор шрифта и т.д.):
; comdlg32.inc
; включаемый файл с функциями из comdlg32.dll
ifdef _TASM_
includelib import32.lib
extrn GetOpenFileNameA:near
extrn GetSaveFileNameA:near
GetOpenFileName equ GetOpenFileNameA
GetSaveFileName equ GetSaveFileNameA
else
includelib comdlg32.lib
; истинные имена используемых функций
extrn __imp__GetOpenFileNameA@4:dword
extrn __imp__GetSaveFileNameA@4:dword
; присваивания для удобства использования
GetOpenFileName equ __imp__GetOpenFileNameA@4
GetSaveFileName equ __imp__GetSaveFileNameA@4
endif
Конечно, эту программу можно еще очень долго развивать — добавить toolbar и statusbar, написать документацию, можно сделать так, чтобы выделялось не фиксированное небольшое количество памяти для переноса файла в редактор, а равное его длине. Можно также воспользоваться функциями отображения части файла в память (CreateFileMapping, OpenFileMapping, MapViewOfFile, UnmapViewOfFile), позволив работать с неограниченно большими файлами. Win32 API настолько богат функциями, что можно довольно долго заниматься только их изучением, а это относится к теме программирования на ассемблере ровно настолько, насколько относится к программированию на любом другом языке.