Я привык этим пользоваться .end start, очень удобно для ленивых, не надо импорт описывать. Хотя для win64ax.inc это не работает. Но вот с этим тоже загвоздка - library msvcrt,'msvcrt.dll' import msvcrt,\ printf,'printf' А почему, что трудно было зделать?
боты все умнее и умнее. Сгенерированные сообщения с каждым разом выглядят все более связными. Даже грамматические ошибки делать умеет, не говоря уже о пунктуации
Что ж вы сразу: "боты, боты". Зимние боты вообще всех в минуса заруливают. Semiono, Я как-то на flatassembler.net постил такую штуку: Code (Text): ;;; This file is named "Win32X+.Inc", because it really doesn't depend on A/W ; These symbolic constants will collect additional libraries/imports irp lib, kernel32,user32,gdi32,advapi32,comctl32,comdlg32,shell32,wsock32 { additional_#lib#_imports equ } additional_libs equ ;;; ;;; Support macros (actually strucs ;-) ;;; struc reequ [value] { common restore .; «value» should not depend on equated symbolic constant, to keep it simple . equ value } struc append [items] { ; assumes list is initialized (at least empty, not undefined) common match items_value, items \{; got something to append match list_value, . \\{; both non-empty, concatenate with comma . reequ list_value, items_value \\} match , . \\{; list was empty, simply equate . reequ items \\} \} } struc if_in_list item, [list] { common . equ 0 forward match =item, list \{ . reequ 1 \} } struc if_odd_in_list item, [first, second] { common . equ 0 forward match =item, first \{ . reequ 1 \} } ;;; ;;; Some real things ;;; macro library [lib, name] { ; Instead of generating import directory, collect lib names in additional_libs common local .done forward .done if_in_list lib, kernel32,user32,gdi32,advapi32,comctl32,comdlg32,shell32,wsock32 ; just in case somebody forgot that they're imported by default match =0, .done \{; not standard lib ;;;--- ;;; That was original line, unconditionally append libname ;;; ;;; additional_libs append lib, name ;;;+++ ;;; This code is added: now we can have several <library> invocations for the same library, ;;; so check for duplicate should be done. ;;; match .libs, additional_libs \\{; dereference libraries list .done if_odd_in_list lib, .libs \\} match =0, .done \\{ additional_libs append lib, name \\} ;;;=== match =additional_#lib#_imports,\; clumsy way to check for undefined equ additional_#lib#_imports \\{ ; «import» before «library» additional_#lib#_imports equ \\} \} restore .done } macro import lib, [function] { ; Similar to «library» above, collect imports common local .done .done if_in_list lib, kernel32,user32,gdi32,advapi32,comctl32,comdlg32,shell32,wsock32 match =1, .done \{ additional_#lib#_imports append function \} match =0, .done \{; not standard lib match .libs, additional_libs \\{; dereference libraries list restore .done .done if_odd_in_list lib, .libs \\} match =0, .done \\{; «import» before «library» match =additional_#lib#_imports,\; clumsy way to check for undefined equ additional_#lib#_imports \\\{ additional_#lib#_imports equ \\\} \\} match .imports, additional_#lib#_imports \\{ forward restore .done .done if_in_list function, .imports match =0, .done \\\{ additional_#lib#_imports append function \\\} common \\} match , additional_#lib#_imports \\{ additional_#lib#_imports append function \\} \} restore .done } macro .code { .code if ~ defined __START__ | defined __START_DEFINED__ __START__ = $ __START_DEFINED__ = 1 end if } macro .end label { purge library, import; flush collectors down the drain, real workers on the way macro library [args] \{ \common match .libs, additional_libs \\{ library args, .libs \\} match , additional_libs \\{ library args \\} \} macro import lib, [functions] \{ \common local .done .done if_in_list lib, kernel32,user32,gdi32,advapi32,comctl32,comdlg32,shell32,wsock32 match =1, .done \\{; got standard lib match .imports, additional_\#lib\#_imports \\\{; got imports to add import lib, functions, .imports \\\} match , additional_\#lib\#_imports \\\{; got nothing import lib, functions \\\} \\} match =0,.done \\{; not standard lib import lib, functions \\} restore .done \} macro additional_libs_imports [lib, name] \{ match .imports, additional_\#lib\#_imports \\{ import lib, .imports restore additional_\#lib\#_imports \\} \} match any, label \{ .end label \} match , label \{ .end __START__ \} match .libs, additional_libs \{ additional_libs_imports .libs \} purge library, import, additional_libs_imports; work is done, so are the workers } ;;;+++ ;;; Redefine macros to accept lib::function name syntax and add import ;;; irps invoke_macro, invoke cinvoke { macro invoke_macro name,[args] \{ \common \local .done .done equ 0 match lib=:=:function, name \\{ library lib,\\`lib import lib,function,\\`function invoke_macro function,args .done reequ 1 \\} match =0, .done \\{ invoke_macro name,args \\} restore .done \} } ;;;=== ;;; That's all, folks! Использовать так: Code (Text): format PE include "Win32WX.Inc" include "Custom\Win32X+.Inc" .code invoke shell32::CommandLineToArgvW, <invoke GetCommandLine>, argc mov esi, eax cinvoke MSVCRT::wprintf, _argc, [argc] cinvoke _putws, _banner .repeat cinvoke MSVCRT::_putws, dword[esi] add esi, 4 dec [argc] .until ZERO? ret .data _argc TCHAR "argc: %u", 10, 0 _banner TCHAR "argv[]:", 0 align 4 argc rd 1 .end
Понятно. =) Это что динамический импорт? Я подключил сюда, не помогло Code (Text): format PE console include '%fasm%/macro/import32.inc' section '.code' executable start: push ebp mov ebp,esp sub esp,12 mov dword [ebp-4],1 @@: ; loop mov eax,dword [ebp-4] cmp eax,11 jge @f mov eax,dword [ebp-4] mov dword [esp+4],eax mov dword [esp],intl call [printf] mov eax,dword [ebp-4] inc eax mov dword [ebp-4],eax jmp @r @@: ; break add esp,4 mov dword [esp],p call [system] mov dword [esp],0 call [exit] section '.data' readable intl db '%d',10,0 p db 'pause>nul',0 section '.idata' import readable library msvcrt,'msvcrt.dll' import msvcrt,\ printf,'printf',\ scanf,'scanf',\ system,'system',\ exit,'exit' Мне просто printf захотелось юзать. Хотя я так низко кодить не умею. Мне без invoke страшно становиться. ))
В определённом смысле — да. Новые макроинструкции library и import вместо определения данных для справочника импорта собирают переданные им аргументы в символических константах, а новая макроинструкция .end вновь переопределяет их для того, чтобы добавить накопленные аргументы к спискам, указанным для старых library/import в макроинструкции .end из Win32*X.Inc. Расширение синтаксиса invoke было придумано позже, вначале было так: Code (Text): format PE include "Win32AX.Inc" include "Custom\Win32X+.Inc" .code import MSVCRT, printf, "printf"; взаимное расположение «library»/«import» library MSVCRT, "MSVCRT.DLL" ; на качество не влияет cinvoke printf, <"Hello, world!", 10, "I'm going back to %#x.", 10> ret .end Строки с library/import можно удалить, если в cinvoke написать напрямую MSVCRT::printf. Естественно, не помогло. Лекарство надо принимать согласно предписанию врача. Win32*X.Inc не подключен, .end не используется — как же оно взлетит?
Возможно похоже, baldr :? Code (Text): format pe gui 4.0 include 'win32ax.inc' include 'win32x+.inc' entry $ invoke kernel32::ExitProcess,0 ;ret 0 ;.end
Мня, это мне очки так мощно помогают видеть? Повторяю ещё раз: Code (Text): include "Win32AX.Inc"; это обязательно include "Win32X+.Inc"; ради этого весь лай irp def, CPL_INIT=1, CPL_INQUIRE=3, CPL_DBLCLK=5, CPL_STOP=6, CPL_EXIT=7 { def }; типа enum struct CPLINFO; авось кому пригодится idIcon rd 1 idName rd 1 idInfo rd 1 lData rd 1 ends .code; модифицирован, определит точку старта здесь, если в .end не указать invoke CPlApplet, HWND_DESKTOP, CPL_INIT, 0, 0 sub esp, sizeof.CPLINFO; так надо, Федя, хотя и не используется ;-) invoke CPlApplet, HWND_DESKTOP, CPL_INQUIRE, 0, esp invoke AppWiz.CPL::CPlApplet, HWND_DESKTOP, CPL_DBLCLK, 0, esp; здесь сработают мой invoke и первые library/import invoke CPlApplet, HWND_DESKTOP, CPL_STOP, 0, esp invoke CPlApplet, HWND_DESKTOP, CPL_EXIT, 0, esp add esp, sizeof.CPLINFO invoke ExitProcess, eax; ret не подойдёт, виснут какие-то левые потоки .end; здесь мои вторые library/import дадут эффект (соответственно, обязательный пункт) Компоненты успеха: 1. Подключить Win32*X.Inc — он определяет ключевую макроинструкцию .end 2. Подключить Win32X+.Inc — это вроде бы должно быть понятно. 3. Где-нибудь при использовании invoke указать ей имя динамической библиотеки для непонятного имени. 4. Ближе к концу вызвать .end (хотя, учитывая возможность не указывать точку старта, end. выглядит красивше . Возможны конфликты имён в DLL, тут на помощь спешат те самые library/import, которые переопределены в первую очередь. Синтаксис у них тот же, что и у стандартных (хотя семантика отличается весьма: к примеру можно import вызвать раньше соответствующей library), употреблять их можно где угодно (вроде бы между include и вызовом .end За прошедшие с момента последнего обновления 4 месяца появилась пара-тройка идей, может и родится что-нибудь более удобоваримое.
я только .end не подключил, так как не знал об этом. а код я вывалил в качестве примера, разумеется про инклюды я не забыл Win32X+.Inc и win32ax.inc.
Если сможете преобразовать strsafe.lib (находится тут Microsoft Visual Studio 8\VC\PlatformSDK\Lib\) в strsafe.dll, то из strsafe.dll
Не совсем верно. strsafe.lib содержит вспомогательные функции (вроде StringExValidateSrcA() и StringCopyWorkerA()), а преобразовывать надо strsafe.h. ----8<---- Semiono, А что в них такого ценного? Глянул StringCchLength(), чуть с пола не упал: кроме 5 байт, вызывающих StringLengthWorker(), она состоит из кода для поиска повода послать вызвавшего на три буквы (порядка 60 байт). «Ладно», думаю, «авось StringLengthWorker() умная и шустрая». Не тут-то было: из 59 байт реально делом заняты всего 8 (!!!) — вот они: Code (Text): @@: cmp [edx], al; eax обнулён ранее jz @f inc edx dec esi; тут значение из cchMax jnz @b @@: Да, очень ценная функция для тех, кому код оплачивают по весу.
baldr Собственно практически все функции из сишных библиотек именно такие Semiono Использовать в прогах на асме CRT и т.п. аццкая жесть для того чтобы просто поучиться это конечно сойдёт, но если ты их серьёзно собрался использовать в реальном программировании, то лучше переходи на С и не парься. Там asm вставки в местах критичных к быстродействию выглядят куда уместнее чем С либы в асме.
гы)) Да ладно, если я рантаймы толком не понимаю, чего ж мне в ассемблер лезть! А кампилятор, я fasm ни на что не променяю! Вобще я асм использую как скриптовый язык, и мне пока хватает. Чем JavaScript лучше асм, так как всегда есть повод научиться в том числе и коду. Но это очень в далёкой перспективе. Крута! =) Но не я их придумал, не мне судить )) Я бы с радостью MS C++ поучил бы, если бы портативный маленький дистр был, что нибудь типа Dev-Cpp. Однако те минговские движки наверняка msdn диалект не понимают.
Semiono Вот и осваивай api, в них есть практически всё что нужно без всяких crt извращений, которые в отличие от api не обязаны быть на компе
Code (Text): section '.idata' import readable library kernel32,'KERNEL32.DLL',shell32,'SHELL32.DLL' include '%fasm%\api\kernel32.inc' include '%fasm%\api\shell32.inc' Если kernel32.inc включаемый файл, то ясное дело, что library kernel32,'KERNEL32.DLL' , надо было это в kernel32.inc включить.
Semiono Так возьми и впиши - инклюдов не так уж и много Единственный минус - когда пишешь для форума приходится возвращаться к стандартному варианту чтобы у других компилилось без напильника.
Так работают стандартные макро для создания секции импорта: все импортируемые библиотеки указываются в одном вызове library.