Y_Mur #193: Ваш вариант можно немного подправить, если использовать %~dpn1.asm, %~dpn1.obj и т.д. почитайте об этом в help к команде for. Это же действует и на параметры bat файлов
Незнаю как с остальными компиляторами ,) с фасм самое то что нужно , непонятный слишком синтаксис. только Авира антивирь ругается если не делать секцию .data и эвристическая проверка хотябы на среднем уровне включена. Если можно напишите пожалуйста самый простейший пример как может на fasm выглядеть Например в masm есть такой файл masm32\m32lib\readdisk.asm там функция Код (Text): read_disk_file proc lpfname:DWORD,lpMem:DWORD,lpLen:DWORD comment * ----------------------------------------------------- the return value is zero on error else non-zero lpMem has the memory address written to it lpLen has the file length written to it the memory address written to lpMem must be deallocated using GlobalFree() ----------------------------------------------------- * LOCAL hFile :DWORD LOCAL fl :DWORD LOCAL hMem :DWORD LOCAL bRead :DWORD mov hFile, FUNC(CreateFile,lpfname,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL) cmp hFile, INVALID_HANDLE_VALUE jne @F xor eax, eax ; return zero on error ret @@: mov fl, FUNC(GetFileSize,hFile,NULL) ; get the file length add fl, 32 ; add some spare bytes mov hMem, alloc(fl) ; allocate a buffer of that size invoke ReadFile,hFile,hMem,fl,ADDR bRead,NULL ; read file into buffer invoke CloseHandle,hFile ; close the handle mov eax, lpMem ; write memory address to mov ecx, hMem ; address of variable mov [eax], ecx ; passed on the stack mov eax, lpLen ; write byte count to mov ecx, bRead ; address of variable mov [eax], ecx ; passed on the stack mov eax, 1 ; non zero value returned on success ret read_disk_file endp Всё понятно до CloseHandle дальше вообще не пойму , для чего в masm квадратные скобки, и что происходит с параметрами например: mov [eax], ecx ;passed on the stack это как будет на fasm ?
heed как может на fasm выглядеть например такой файл masm32\m32lib\readdisk.asm Код (Text): format PE GUI include 'win32ax.inc' ; import data in the same section lpLen equ ebp+10h lpMem equ ebp+0Ch lpfname equ ebp+8 hFile equ ebp-4 fl equ ebp-8 hMem equ ebp-0Ch bRead equ ebp-10h ;--------------------------- push ebp mov ebp,esp add esp,-10h invoke CreateFile,dword[lpfname],GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0 mov [hFile], eax cmp dword[hFile], INVALID_HANDLE_VALUE jne @F xor eax, eax ; return zero on error leave retn 0Ch @@: invoke GetFileSize,dword[hFile],0 mov [fl],eax ; get the file length add dword[fl],32 ; add some spare bytes invoke GlobalAlloc,40h,dword[fl] mov [hMem],eax ; allocate a buffer of that size lea eax,[bRead] invoke ReadFile,dword[hFile],dword[hMem],dword[fl],eax,0 ; read file into buffer invoke CloseHandle,dword[hFile] ; close the handle mov eax,[lpMem] ; write memory address to mov ecx,[hMem] ; address of variable mov [eax], ecx ; passed on the stack mov eax,[lpLen] ; write byte count to mov ecx,[bRead] ; address of variable mov [eax],ecx ; passed on the stack mov eax, 1 ; non zero value returned on success leave retn 0Ch ;--------------------------------------------------------------------- data import library kernel32,'KERNEL32.DLL' import kernel32,\ CreateFile,'CreateFileA',\ GetFileSize,'GetFileSize',\ GlobalAlloc,'GlobalAlloc',\ ReadFile,'ReadFile',\ CloseHandle,'CloseHandle' end data
heed А это то же самое с оптимизацией Код (Text): push ebp mov ebp,esp add esp,-10h xor ebx,ebx invoke CreateFile,dword[lpfname],GENERIC_READ,FILE_SHARE_READ,ebx,OPEN_EXISTING,ebx,ebx inc eax; if eax==INVALID_HANDLE_VALUE then eax+1==0 je @F ; return zero in eax on error dec eax mov [hFile],eax invoke GetFileSize,eax,ebx add eax,32 ; add some spare bytes mov [fl],eax ; get the file length invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,eax mov [hMem],eax ; allocate a buffer of that size lea ecx,[bRead] invoke ReadFile,dword[hFile],eax,dword[fl],ecx,ebx ; read file into buffer invoke CloseHandle,dword[hFile] ; close the handle mov eax,[lpMem] ; write memory address to mov ecx,[hMem] ; address of variable mov [eax], ecx ; passed on the stack mov eax,[lpLen] ; write byte count to mov ecx,[bRead] ; address of variable mov [eax],ecx ; passed on the stack mov eax, 1 ; non zero value returned on success @@: leave retn 0Ch
Mikl___ - Все демонстрационные файлы не открываются. В процессах появляются названия , а окно не создаётся. Установил XP на VMware - всё работает на чистой системе. Что может мешать на основной? Антивирусы - Avast и Outpost. На виртуалке установил Outpost - всё работает значит дело не в нём. Где косяк?
Plis Писалось и проверялось под WinXP HomeEdition, SP1, SP2, SP3, вероятно не работает из-за экспериментов с PE-заголовком: align=4 и массив директорий (IMAGE_OPTIONAL_HEADER.DataDirectory) состоит из не 16 элементов, а из 4 или 2 хотя есть уроки Iczeliona написанные на FASM, GoAsm и NASM (с #110 по #118) и там с заголовками не эксперименировал, попробуй их
Mikl___ На эмуляторе XP SP2, на основной системе XP SP3 - устанавливались с одного диска. На эмуляторе работают все примеры и с экспериментами, и без экспериментов над PE-заголовком. На основной работает только первый урок, с MessageBox. Остальные - окно не рисуется.
Plis Возможно из за смешения кода и данных link /MERGE:.data=.text Если начиная с 3 урока там везде WNDCLASSA вместо WNDCLASSEXA и предварительное заполнение WNDCLASS Код (Text): style dd CS_HREDRAW or CS_VREDRAW; Стиль нашего окна lpfnWndProc dd OFFSET WndProc;Адрес процедуры обработки событий cbClsExtra dd 0 ;это нам пока не нужно cbWndExtra dd 0 ;и это тоже hInstance dd 400000h ;Адрес нашей проги в памяти (Windows всегда её грузит по этому адресу) hIcon dd 10003h ;Иконка окна по умолчанию hCursor dd 10011h ;Курсор окна по умолчанию (здесь указан ID обычной стрелки) hbrBackground dd COLOR_WINDOW ;Фон нашего окна lpszMenuName dd 0 ;Меню у нас отсутствует lpszClassName dd OFFSET szWinClass; Указатель на имя нашего класса возможно основной системе с XP SP3 (хотя у меня тоже SP3) не нравится 400000h, 10003h, 10011h? Может быть при старте приложения в EAX не ноль? Тогда замените xchg ebx,eax на xor ebx,ebx Возможно что для CreateWindow название класса окна не нравится - я использую под название класса заголовок окна Возможно не нравится отсутствие ShowWindow и UpdateWindow но, добавление к стилю окна стиля WS_VISIBLE делало ненужным у меня и ShowWindow, и UpdateWindow
Mikl___ Взгляни, я просто скопировал ( заменил из твоего примера Iczelion-овские строки ), или так не пойдёт, нужно всё заменять? 2.imp файл создал с помощью программы scan, которую посоветовал kero.
Код (Text): .386 .model flat,stdcall option casemap:none include H:\masm32\include\windows.inc ;nclude H:\masm32\include\user32.inc includelib H:\masm32\lib\user32.lib ; calls to functions in user32.lib and kernel32.lib ;include H:\masm32\include\kernel32.inc includelib H:\masm32\lib\kernel32.lib include 2.imp WinMain proto :DWORD,:DWORD,:DWORD,:DWORD ;extern _imp__DefWindowProcA@16:dword;стандартная обработка сообщения / ;extern _imp__DispatchMessageA@4:dword;отправка сообщения / ;extern _imp__GetMessageA@16:dword;получение сообщения / ;extern _imp__LoadCursorA@8:dword;получить указатель на ресурс курсора / ;extern _imp__PostQuitMessage@4:dword;выход из программы / extern _imp__RegisterClassA@4:dword;регистрация класса окна / ;extern _imp__MessageBoxA@16:dword ;extern _imp__IsDialogMessageA@8:dword ;extern _imp__SetDlgItemTextA@12:dword ;extern _imp__TranslateMessage@4:dword ;extern _imp__CreateDialogParamA@20:dword ;extern _imp__SendMessageA@16:dword ;extern _imp__GetDlgItemTextA@16:dword ;extern _imp__CreateWindowExA@48:dword .DATA ; initialized data ClassName db "SimpleWinClass",0 ; Имя нашего класса окна AppName db "Our First Window",0 ; Имя нашего окна cbSize dd SIZEOF WNDCLASSA style dd CS_HREDRAW or CS_VREDRAW; Стиль нашего окна lpfnWndProc dd offset WndProc;Адрес процедуры обработки событий cbClsExtra dd 0 ;Эта хрень нам не нужна cbWndExtra dd 0 ;и эта тоже hInstance dd 400000h ;Адрес нашей проги в памяти (Windows всегда её грузит по этому адресу) hIcon dd 10003h ;Иконка окна по умолчанию hCursor dd 10011h ;Курсор окна по умолчанию (здесь указан ID обычной стрелки) hbrBackground dd COLOR_BTNFACE+1 ;Фон нашего окна lpszMenuName dd NULL;Меню у нас отсутствует lpszClassName dd offset ClassName; У .DATA? ; Hеиницилизиpуемые данные ;hInstance HINSTANCE ? ; Хэндл нашей пpогpаммы CommandLine LPSTR ? hwnd HWND ? msg MSG <> .CODE ; Здесь начинается наш код start: ;invoke GetModuleHandle, NULL ; Взять хэндл пpогpаммы ; Под Win32, hmodule==hinstance mov hInstance,eax ;mov hInstance,eax ;invoke GetCommandLine ; Взять командную стpоку. Вы не обязаны ;вызывать эту функцию ЕСЛИ ваша пpогpамма не обpабатывает командную стpоку. ;mov CommandLine,eax ;invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT ; вызвать основную функцию ;invoke ExitProcess, eax ; Выйти из пpогpаммы. ; Возвpащаемое значение, помещаемое в eax, беpется из WinMain'а. ;WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD ; LOCAL wc:WNDCLASSEX ; создание локальных пеpеменных в стеке ; LOCAL msg:MSG ; LOCAL hwnd:HWND xor ebx,ebx lea edi,cbSize assume edi:ptr WNDCLASSA push edi call _imp__RegisterClassA@4 mov ecx,CW_USEDEFAULT push ebx push [edi].hInstance push ebx push ebx push ecx push ecx push ecx push ecx push WS_OVERLAPPEDWINDOW + WS_VISIBLE push [edi].lpszClassName push [edi].lpszClassName push ebx call _imp__CreateWindowExA@48 ; mov wc.cbSize,SIZEOF WNDCLASSEX ; заполнение стpуктуpы wc ; mov wc.style, CS_HREDRAW or CS_VREDRAW ; mov wc.lpfnWndProc, OFFSET WndProc ; mov wc.cbClsExtra,NULL ; mov wc.cbWndExtra,NULL ; push hInstance ; pop wc.hInstance ; mov wc.hbrBackground,COLOR_WINDOW+1 ; mov wc.lpszMenuName,NULL ; mov wc.lpszClassName,OFFSET ClassName ; invoke LoadIcon,NULL,IDI_APPLICATION ; mov wc.hIcon,eax ; mov wc.hIconSm,eax ; invoke LoadCursor,NULL,IDC_ARROW ; mov wc.hCursor,eax ; invoke RegisterClassEx, addr wc ; pегистpация нашего класса окна ; invoke CreateWindowEx,NULL,\ ; ADDR ClassName,\ ; ADDR AppName,\ ; WS_OVERLAPPEDWINDOW,\ ; CW_USEDEFAULT,\ ; CW_USEDEFAULT,\ ; CW_USEDEFAULT,\ ; CW_USEDEFAULT,\ ; NULL,\ ; NULL,\ ; hInst,\ ; NULL mov hwnd,eax ; invoke ShowWindow, hwnd,CmdShow ; отобpазить наше окно на десктопе ; invoke UpdateWindow, hwnd ; обновить клиентскую область .WHILE TRUE ; Enter message loop invoke GetMessage,ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ; сохpанение возвpащаемого значения в eax ret ;WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY ; если пользователь закpывает окно invoke PostQuitMessage,NULL ; выходим из пpогpаммы .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ; Дефаултная функция обpаботки окна ret .ENDIF xor eax,eax ret WndProc endp end start
Найдите 10 отличий или сколькими способами можно вызвать MessageBox? Во вложениии сорц и ехе 12 способов, которыми можно вызвать MessageBox (просьба сильно не пинать!)
Mikl__ Запускаю bat из #17 для lesson03.asm. Получаю lesson03.exe размером 896 б., 2 секции. Меняю в /MERGE:.data на .rdata - уже 848 б., 1 секция. Но всё-таки не 536, как в архиве. Как Вы добились такого размера? И ещё вопрос: можно ли убрать warning-и?
pinyurij EXE'шники, которые приводятся в "Сам себе Iczelion" собираются с 4-байтным стабом stubby.exe='M','Z',0,0 и переделанным polink1 (смотрите аттач к #69) и пояснения в #71 А если дойти до #159 там PE-заголовок сжимается еще больше
Обычно не отключал но знаю что у ml есть ключи /w /wx /wномер наверное ими стоит поэксперементировать. На WASM.RU есть статья Компиляция файлов .asm с помощью компилятора ml.exe Этот материал дополняет статью MS Developer Studio - среда разработки для ASM. Здесь приведен формат командной строки компилятора MASM 6.1+, расшифровка ее опций и комментарии по их применению при работе в среде MS Developer Studio. /w Same as /W0 /WX То же, что /W0 /WX См. далее. /WX Treat warnings as errors Трактовать предупреждения как ошибки Обычно в применении нет необходимости. В случае возникновения предупреждений компиляция завершается неуспешно. /W<number> Set warning level Установить уровень предупреждеинй Обычно в применении нет необходимости. Устанавливает перечень событий компиляции, трактуемых как предупреждения. Для tasm32 ключи /w0, /w1, /w2 set warning level: w0=none, w1=w2=warnings on /w-xxx, /w+xxx disable (-) or enable (+) warning xxx
Mikl___ Спасибо, получилось. Правда, пока 564, а не 536. Буду разбираться... Кстати, polink1 warning-ами не ругается!
Извините, а нет примерчика тут на чтение строки REG_SZ / EXPAND_SZ из реестра, ну хотя бы в MsgBox на экран вывести? Я видел как типы данных получаются и как дворд кажись, сам сколько крутил эти коды ничего не получается - wsprintf вообще убил... Походу я вилосипед изобретаю, такую фигню никаких уроков не могу нагуглить! моё - http://slil.ru/28230433