Форум программистов, компьютерный форум, киберфорум
Assembler: MASM64, х64/long mode
Войти
Регистрация
Восстановить пароль
Другие темы раздела
Assembler Программирование на 64 битной OS Добрый день, уважаемые. Хочу переделать программу которая работала на 32 битной ОС, под 64 битную. (про приемственность версий знаю) я хочу именно узнать различия программирования под разные ОС. Пишу... https://www.cyberforum.ru/ assembler-x64/ thread1160906.html RegEnumKey - записать параметры в {cls-id}\key Assembler
Пожалуйста, помогите сделать код... SHRegEnumUSKey Нужно записать параметры в {cls-id}\key. Более всего непонятно как забирать названия ключей после SHRegEnumUSKey. Может быть лучше использовать...
Assembler слетает TF флаг https://www.cyberforum.ru/ assembler-x64/ thread1090463.html
win 7, система x64, приложение x32 написал дебагер который ставит бряк и затем включает TF флаг и начинает трассировку трассирует значит, трассирует, и тут я подсовываю ему код типа call far...
Assembler Masm64 и winAPI https://www.cyberforum.ru/ assembler-x64/ thread1026355.html
Здравствуйте. даже не знаю в какую тему писать, с получившейся проблемой. Нужно написать графическое приложение на winAPI но обязательным условием является то что оно должно быть написано на...
RegDeleteTree и WinXP x64 ? Assembler
include '%fasm%/win32ax.inc' section '.code' executable start: invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,'Software\a',NULL,KEY_WOW64_64KEY+KEY_ENUMERATE_SUB_KEYS,o @@: invoke...
Assembler Построчное чтение XML файла <item> <string name="Group" value="TransportWindow"/> <member name="Values"> <obj class="UPoint" name="Location" ID="215319288"> <int name="H"... https://www.cyberforum.ru/ assembler-x64/ thread803168.html
Assembler Ошибка при вызове SHCopyKey https://www.cyberforum.ru/ assembler-x64/ thread797619.html
include '%fasm%/win64ax.inc' section '.code' executable start: sub rsp,8 invoke SHCopyKey,HKEY_LOCAL_MACHINE,'Software\$$',HKEY_CURRENT_USER,NULL exit: invoke...
Assembler Ошибка при вызове MoveFileEx
include '%fasm%/win64ax.inc' section '.code' executable start: invoke ExpandEnvironmentStrings,'%ProgramFiles%\EmEditor\emedshl',a,MAX_PATH invoke...
Assembler X64 AT&T assembly https://www.cyberforum.ru/ assembler-x64/ thread399721.html
.data x_d: .string "abc" .text .globl main .type main, @function main: pushq x_d call printf ret
Assembler Ассемблер для x64 https://www.cyberforum.ru/ assembler-x64/ thread386531.html
Я установил win 7 x64 и теперь не могу ничего скомпилировать. Масмы тасмы пишут о несовместимости. Есть рабочие ассемблеры для win 7 x64??
SendInput как нажать ALT+SHIFT ? Assembler
include '%fasm%/win64ax.inc' section '.code' executable start: sub rsp,8 mov ,$-pInputs mov ,VK_TAB+VK_MENU invoke Sleep,1000 invoke...
Assembler Рекурсивное удаление файлов рекурсивное удаление файловinclude '%fasm%/win64ax.inc' section '.code' executable start: invoke ExpandEnvironmentStrings,'%ProgramFiles%\Videodeluxe\_msi_keyfile_*',open,MAX_PATH ... https://www.cyberforum.ru/ assembler-x64/ thread378004.html
Ушел с форума
Автор FAQ
14413 / 7140 / 858
Регистрация: 11.11.2010
Сообщений: 12,790
11.06.2014, 10:38  [ТС] 0

Все, что нужно знать, чтобы начать программировать для 64-разрядных версий Windows - Assembler - Ответ 6303336

11.06.2014, 10:38. Показов 28982. Ответов 20
Метки (Все метки)

Ответ

Уменьшаем размер приложения для Win64
Простейшее приложение выводящее на экран фразу "Win64 Assembly is Great!" на диалекте MASM
исходный текст
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
OPTION DOTNAME
option casemap:none
include \x64\include\temphls.inc
include \x64\include\win64.inc
include \x64\include\kernel32.inc
include \x64\include\user32.inc
includelib \x64\lib\kernel32.lib
includelib \x64\lib\user32.lib
.data
MsgCaption      db "Iczelion's tutorial #2",0
MsgBoxText      db "Win64 Assembly is Great!",0
.code
WinMain proc 
    invoke MessageBox,0,&MsgBoxText,&MsgCaption,0
        invoke ExitProcess,0
WinMain endp
end
текст bat-файла которым собиралось приложение
Код
set file=msgbox
set path=\x64\
%path%bin\ml64 %file%.asm /link /subsystem:windows /entry:WinMain
del %file%.obj
del mllink$.lnk

текст под оттладчиком
Код
	sub rsp,28h
	xor rcx,rcx
	xor r9d,r9d
	lea rdx,[140000287];"Win64 Assembly is Great!"
	lea r8,[140000270];"Iczelion Tutorial #2:MessageBox"
	call MessageBoxA
	xor ecx,ecx
	call ExitProcess

В результате получаем ехе-файл в 2560 байт. При просмотре внутренностей ехе-файла программой hiew32 видно, что 90% содержимого нули. Возникает законный вопрос, а как уменьшить размер программы, но чтобы при этом не терялась ее функциональность?
Шаг первый ― уменьшение размера выравнивания сегментов
  • Программа-компановщик link.exe имеет ключ /ALIGN:размер. Ключ /ALIGN[MENT] ― указывает компановщику на необходимость выравнивания сегментов в исполняемом файле на границу, кратную значению размер. Здесь размер ― это число равное степени двойки (20=1, 21=2, 22=4, 23=8, ..., 29=512 до 64 К включительно).
    Если об этом ключе не упоминать, то выравнивание равно 512 байт для совместимости с программами созданными для Windows 95/98. Посмотреть значение выравнивания можно при помощи любимого редактора бинарных файлов hiew32 в заголовке программы в поле «File alignment» (Открываем наш exe программой hiew32, нажимаем F4 (Mode) и выбираем Hex, нажимаем F8 (Header) в поле «File alignment» видим число 200h=512).
Кроме ключа /ALIGN добавим в файл makeit.bat еще некоторые ключи компиляции и линковки, которые позволят нам уменьшить количество служебной информации в asm-файлах.
  • Добавление ключа компиляции /Cp ― «сохранить регистр символов во всех идентификаторах» позволяет не писать каждый раз в тексте ассемблерного файла «option casemap:none».
  • Добавление ключа компиляции /I:путь ― «установить путь для включаемых файлов» позволяет нам не указывать каждый раз полный путь к inc-файлам.
  • Ключ /LIBPATH:путь говорит линкеру, где находятся библиотеки импорта, что позволяет нам не указывать каждый раз полный путь к lib-файлам.
Так выглядит содержимое файла makeit.bat до изменений:
Код
set file=msgbox
set path=\x64\
%path%bin\ml64 %file%.asm /link /subsystem:windows /entry:WinMain
del %file%.obj
del mllink$.lnk

а так после:
Код
set file=msgbox
set path=\x64\
%path%bin\ml64 /Cp /I%path%include %file%.asm /link /subsystem:windows ^
/LIBPATH:%path%lib /ALIGN:256 /entry:WinMain
del %file%.obj
del mllink$.lnk

при компиляции получаем сообщение
LINK : warring LNK4108: /ALIGN specified without /DRIVER; image may not run
размер файла msgbox.exe меняется с 2560 на 1536 байт и, не смотря, на предупреждение image may not run файл msgbox.exe благополучно запускается
Продолжаем эксперимент, изменяя значение ALIGN, наблюдаем за уменьшением размера файла msgbox.exe. При этом каждый раз запускаем получившийся файл msgbox.exe на исполнение и убеждаемся в работоспособности получившегося файла.
/ALIGN:размерзаголовоккодданныеимпортобщий размер msgbox.exe
не указан 1024 5125125122560 байт
256 768 2562562561536 байт
128 640 1281282561152 байт
64 576 6464192896 байт
32 576 6464192896 байт
16 576 4848192864 байт
8ошибка при создании файла
при /ALIGN:8 получаем сообщение об ошибке
msgbox.obj : fatal error LNK1164: section 0x1 alignment (16) greater then /ALIGN value
похоже, что в этом направлении мы достигли предела, хотя от исходной программы в 2560 байт пришли к программе в 848 байт, а это согласитесь не плохо!
Шаг второй ― объединяем сегмент кода и сегмент данных.
Наша программа использует два сегмента, сегмент кода и сегмент данных, посмотрите внимательно через hiew32 ― между этими сегментами прослойка из нулей, от которых мы и пытаемся избавится. А помните во времена DOS'а можно было создавать COM-файлы, которые в единственном сегменте содержал и код, и стек, и данные? А нельзя ли и здесь создать, что-то подобное?
  • Объединения сегмента кода и сегмента данных можно добиться если использовать опцию линкера /SECTION.
    Опция командной строки компановщика link.exe /SECTION:name,[[!]{DEKPRSW}][,ALIGN=#] позволяет принудительно назначать атрибуты секциям PE-файла. Для секции можно задать один или несколько атрибутов. Следует задавать все атрибуты, которые должна иметь секция; если какой-либо знак атрибута не указан, то его бит будет отключен. Если не указан атрибут R, W или E, то существующее состояние чтения, записи или исполнения остается неизмененным. Чтобы инвертировать атрибут, перед его символом указывают знак «!». С помощью параметра ALIGN=# можно задать значение выравнивания для конкретной секции. Значения знаков атрибутов приведены в следующей таблице.
    буква атрибут значениеперевод
    DDiscardableMarks the section as discardableСекция помечается как выгружаемая
    EExecuteThe section is executableСекция является выполняемой
    KCacheableMarks the section as not cacheableСекция помечается как некэшируемая
    PPageableMarks the section as not pageableСекция помечается как секция без страничной организации
    RReadAllows read operations on dataДопускаются операции чтения данных
    SSharedShares the section among all processes that load the imageСекция совместно используется всеми процессами, загружающими образ
    WWriteAllows write operations on dataДопускаются операции записи данных
    В данном случае секции с именем «.text» (содержащей код программы) и уже имеющей атрибуты R (доступна для чтения) и E (исполнимая), устанавливается атрибут W (доступна для записи)
    Код
    /SECTION:.text,W
Вносим изменения в текст программы
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
include win64.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
 
.code
MsgCaption db "Iczelion's tutorial #2", 0
MsgBoxText db "Win64 Assembly is Great!", 0
 
WinMain proc
    sub rsp, 28h        ; space for 4 arguments + 16byte aligned stack
    xor r9d, r9d        ; 4. argument: r9d = uType = 0
    lea r8, MsgCaption  ; 3. argument: r8  = caption
    lea rdx,MsgBoxText  ; 2. argument: edx = window text
    xor ecx, ecx        ; 1. argument: rcx = hWnd = NULL
    call MessageBox
    xor ecx, ecx        ; ecx = exit code
    call ExitProcess
WinMain endp
вносим изменения в файл makeit.bat, создающий msgbox.exe
Код
set file=msgbox
set path=\x64\
%path%bin\ml64 /Cp /I"%path%include" %file%.asm /link /subsystem:windows ^
/LIBPATH:"%path%lib" /ALIGN:16 /SECTION:.text,W /entry:WinMain
del %file%.obj
del mllink$.lnk
В результате получаем msgbox.exe в 832 байт
заголовоккод и данныеимпортобщий размер
54496192832 байт
Шаг третий ― «хирургический» ― ампутируем у файла «хвост».
hiew32 показывает, что в хвосте нашего файла, сразу за строкой «kernel32.dll» целых двенадцать байтов содержащих нули. А не удалить ли их нам вручную?
Код
.40000300:   E2 01 4D 65 73 73 61 67  65 42 6F 78 41 00 75 73 т MessageBoxA us
.40000310:   65 72 33 32 2E 64 6C 6C  00 00 BC 00 45 78 69 74 er32.dll    Exit
.40000320:   50 72 6F 63 65 73 73 00  6B 65 72 6E 65 6C 33 32 Process kernel32
.40000330:   2E 64 6C 6C 00 00 00 00  00 00 00 00 00 00 00 00 .dll
Сказано ― сделано! В far'е нажимаем F4 открываем файл на редактирование, нажимем Ctrl+End и переходим в конец файла. Далее, нажимая на Backspace, удаляем лишнее, жмем на F2 и сохраняем изменения в файле, нажимаем на F10 и выходим из файла ― размер msgbox.exe стал 816 байт. Нажимаем на него и запускаем msgbox.exe ― запускается нормально! Стоп-стоп! 832-816=16 байт, а должно быть 12! Смотрим в hiew32 ― о, боже!, мы отрезали вместе с нулями от «kernel32.dll» кусок «.dll», но файл-то всё равно работает! Запомним на будущее, что от DLL достаточно только названия, а точку и расширение файла система подставит сама.
заголовоккод и данныеимпортобщий размер
54496176816 байт
Шаг четвертый ― уменьшаем DOS-stub.
Код нашей программы начинается с 1F8h=504 байта. Всё, что выше ― это заголовок нашего EXE-файла ― вот бы его уменьшить! Заголовок нашего файла состоит из двух частей. От строки «MZ» до строки «PE» DOS-заголовок (DOS-stub) (0C0h=192 байта) и от строки «PE» до 21Fh PE-заголовок (352 байта). Адрес строки «PE» содержится в DOS-заголовке в двойном слове по смещению 3Ch.
Начнем с уменьшения DOS-stub'а. Возьмем hiew32.exe и создадим с его помощью вот такой файл:
Код
.000000:   4D 5A 00 00 00 00 00 00  00 00 00 00 00 00 00 00 MZ
.000010:   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
.000020:   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
.000030:   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
Присвоим ему имя stub.exe и используем в качестве stub-программы в очередной раз, внеся изменения в makeit.bat.
Код
set file=msgbox
set path=\x64\
%path%bin\ml64 /Cp /I"%path%include" %file%.asm /link /subsystem:windows ^
/LIBPATH:"%path%lib" /ALIGN:16 /SECTION:.text,W /STUB:stubby.exe /entry:WinMain
del %file%.obj
del mllink$.lnk
Запускаем makeit.bat и получаем msgbox.exe в 768 байт, если еще отрезать конечные нулевые байты и «.dll», тогда его размер равен 752 байт. Хотя через hiew32 видно, что размер DOS-заголовка не 64 байта, как мы предполагали, а 128 байт, но это не 192 байта, как было в начале.
заголовоккод и данныеимпортобщий размер
48096176752 байта
to be continued


Вернуться к обсуждению:
Все, что нужно знать, чтобы начать программировать для 64-разрядных версий Windows Assembler
1
Изображения
  
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.06.2014, 10:38
Готовые ответы и решения:

Хочу начать программировать на iOS, нужно ли знать Cи?
Здравствуйте! Хочу научиться программировать различные программы для Iphone (был опыт...

Что необходимо для того чтобы начать программировать на Java
Добрый день, господа!!! Небольшая просьба, вашего покорного слуги. Напишите все необходимые...

Что надо знать в java, чтобы хорошо программировать под android?
Всем привет. Подскажите пожалуйста какие технологии в java мне необходимо изучить что бы начать...

Что нужно знать для того чтобы устроиться на работу?
Я студент вуза 1 курс... Очень хотел бы начать работать пораньше... Знаний минимум, если смотреть...

20
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.06.2014, 10:38

C# для фриланса - Что нужно знать чтобы потянуть на Junior'a?
Интересуюсь обучению C# исключительно для зарабатывания денег. имею опыт работы на...

Что скачать и установить, чтобы начать программировать?
Решил изучить Яву. Хочу научиться создавать оконные приложения для Windows. Пока мне требуется: -...

Какие темы нужно знать, чтобы начать работать с DirectX
День добрый! Прочитал уже почти 3 книги &quot;для начинающих&quot;, множество статей, немного умею работать с...

Java для фриланса - что нужно знать чтобы потянуть на Junior'a?
Имею опыт работы на C/C++/Qt/Delphi(маленький опыт)/Assembler. соответственно в программировании я...

0
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.