Форум программистов, компьютерный форум, киберфорум
Assembler: MASM64, х64/long mode
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.98/131: Рейтинг темы: голосов - 131, средняя оценка - 4.98
Эксперт быдлокодинга
 Аватар для Полный 30h
2095 / 529 / 70
Регистрация: 04.11.2010
Сообщений: 1,314

Соглашение о вызове функций (выравнивание стека)

13.12.2014, 19:08. Показов 28008. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго дня.
Хотелось бы поделиться одним замечанием, мыслью, наблюдением, моей непоняткой ( нужное подчеркнуть). Касается вопроса о Соглашении вызова функций (в том числе вызов функций API) при 64 программировании. А именно Выравнивание стека.



Относится к коду примера из книги «Программирование на ассемблере на платформе х86-64» автор Руслан Аблязов. К коду примера 64 битной программы в теме «Особенности кодинга под x64» по адресу https://www.cyberforum.ru/post5087633.html И одному утверждению murderer в теме «Особенности кодинга под x64» по адресу https://www.cyberforum.ru/post5083982.html

Пара отступлений:
1. Долгое время меня этот вопрос волновал слабо в виду того что пользовал программу FASM Editor 2.0 где были забиты основные болванки под прожки (64/32/16, окна/консоль-мансоль) от которых я собственно отталкивался не напрягая себя знаниями по поводу того зачем все эти закорючки вначале и в конце. А тут вдруг решил углубиться. Ну и углубился...
2. Изучение мною ассемблера носит бессистемный характер и протекает под девизом Быдлокодерство как высшая форма рукоблудства. Поэтому на истину не претендую.
3. Отсылка к примеру из книги Аблязова носит условный характер в виду того что скачена была мной в интернетах под этим названием. Является ли она таковой на самом деле ручаться не берусь.
4. Рассматриваемые мной примеры условно считались как примеры программ под Windows и проверялись на Windows 7. Компилировались при помощи FASM

Теперь к сути

Цитата Сообщение от murderer
Выравнивание стека
Перед вызовом функции rsp должен быть кратен 16. Таким образом если ваша функция имеет чётное количество параметров и количество параметров больше 4, при передаче ей управления rsp будет кратен 8, иначе rsp кратен 16. В FASM макросы .code/.end автоматически добавляют "sub rsp,8" в точке входа для выравнивания стека.
В миру murderer должно быть работает юристом, потому как со второго предложения смысл прочитанного от меня безнадёжно ускользнул. Однако первое предложение как бы ясно.

Цитата Сообщение от Аблязов
Выравнивание стека Следует помнить, что стек всегда должен быть выровненным на границу 16 байт, т. е. указатель в RSP должен быть кратен 16. Это требование не очевидное, но тем не менее так нам говорит документация. В большинстве случаев отсутствие выравнивания на 16 байт не повлечет за собой никаких последствий, однако некоторые функции вызовут исключение именно по этой причине. В общем случае отсутствие выравнивания уменьшает производительность приложения.
пример в книге Аблязова так и вовсе песня.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
;Итак, например, у нас есть функция и она принимает шесть параметров: 
;function (int 1, reall, int2, real2,int 3,real 3) - три целочисленных параметра 
;и три параметра с плавающей запятой. В соответствии с соглашением вызова в 
;Win64 вызов произойдёт следующим образом:
 
push геа13
push int3
R9=real2, XMM3L=real2
R8=int2
RDX= reall, XMMlL=reall
RCX=intl
RSP= RSP-32
; Вызов функции
; Очистка стека (если это необходимо)
т.е. резервирование стека под первые четыре параметра отсутствует как класс

А это место навеяло грусть
Тем не менее все эти знания вряд ли нам пригодятся, т. к. в компиляторе FASM уже есть необходимый набор макросов, позволяющий одной строчкой производить вызов функций и максимально облегчающий написание процедур и функций, отвечающих модели вызова в fastcall Win64.
Книга позиционируется как пособие для изучения ассемблера, на минуточку.

В коде исходника тоже всё как то для меня сложилось уныло. Фрагменты
Аблязов
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
format PE64 GUI 5.0
entry start
include 'win64a.inc'
section '.data' data readable writeable
   text  db 'Hello world!',0
section '.code' code readable executable
start:
    sub rsp, 32
    mov rcx, 0
    mov rdx, text
    mov r8,  text
    mov r9, 0
    call [MessageBox]
    xor rcx, rcx
    call [ExitProcess]
; и т.д.
Собирается но не работает. В принципе как бы зная свою рукожопость в плане компиляции сперва подумал может упускаю чего, однако в исходниках имеется так же и собранный без меня экзешник. Не работает сволочь тоже.

Mikl___
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
; создать кодовую секцию с атрибутами на чтение и исполнение
section '.code' code readable executable
start:  mov        r9d,0                   ; uType == MB_OK (кнопка по умолчанию)
                                           ; аргументы по соглашению x86-64
                                           ; передаются через регистры, не через стек!
                                           ; префикс d задает регистр размером в слово,
                                           ; можно использовать и mov r9,0, но тогда
                                           ; машинный код будет на байт длиннее
        lea        r8,[_caption]           ; lpCaption, передаем смещение
                                           ; команда lea занимает всего 7 байт,
                                           ; а mov reg,offset - целых 11, так что
                                           ; lea намного более предпочтительна
        lea        rdx,[_message]          ; lpText, передаем смещение выводимой строки
        mov        rcx,0                   ; hWnd, передам дескриптор окна-владельца
                                           ; (можно также использовать xor rcx,rcx
                                           ; что на три байта короче)
        call       [MessageBox]            ; вызываем функцию MessageBox
        mov        ecx,eax                 ; заносим в ecx результат возврата
                                           ; (Функция ExitProcess ожидает 32-битный параметр;
                                           ; можно использовать и mov rcx,rax, но это будет
                                           ; на байт длиннее)
        call       [ExitProcess]           ; вызываем функцию ExitProcess
Собирается но не работает.

Отчаялся бы я совершенно на ниве самообразования если бы не два обстоятельства - Гугл и Пирогов. Захожу я через первы в ЖЖ ко второму и что я вижу?! А вижу я рабочий код, внятное пояснение почему он рабочий, а так же понимание того почему всё что сверху мной приведено нихрена не работало.

Цитирую Пирогова

В 64-битовых Windows принята следующая конвенция вызова функций (в том числе вызов функций API).
1. Первые четыре параметра передаются в функцию через регистры: rcx, rdx, r8, r9. Остальные параметры (если они есть) передаются через стек.
2. Перед вызовом функции резервируется область в стеке, на случай, если вызываемая функция "захочет" временно сохранить параметры в стеке. Таким образом, параметры, которые передаются через стек, помещаются туда после резервируемой области.
3. При передаче параметров, размер которых меньше 64 бит, передаются как 64-битовые параметры. При этом следует обнулить старшие биты. Параметры, большие 64-бит передаются по ссылке.
4. Данные возвращаются через регистр rax. Если возвращаемое значение имеет размер больший 64 бит, то данное передается через область памяти, адрес которой передается в первом параметре. Для возвращения может также использоваться регистр xmm0.
5. Все регистры при вызове функций сохраняются за исключением rax, rcx, rdx, r8, r9, r10, r11, сохранность которых не гарантируется.
6. Граница стека должна быть выровнена по адресу кратному 16.
Рассмотрим в общих чертах схему вызова функции API с пятью параметрами.
И код
Assembler
1
2
3
4
5
6
7
8
9
10
11
...
sub rsp,40 ; резервируем стек
mov qword ptr [rsp+32],par5
mov r9,par4
mov r8,par3,
mov rdx,par2
mov rcx,par1
call f_api64
...
add rsp,40 ;восстанавливаем стек
...
Сперва подумалось - то ли я дурак, то ли Пирогов, на 16 делить не умеет, но следующая после примера фраза поставила всё на свои места

Обратите внимание, что в нашем случае стек с учетом адреса возврата при вызове функции оказывается выровненным на величину кратную 16 (48 байт).

После этого собственно так же появилось понимание того за каким хреном в болванке программы на 64 бита от FASM Editor стоит строчка sub rsp,8
Потому что если верить IDA pro макрос invoke FASMa не равняет стек под 16 байтовую кратность
Assembler
1
2
 
invoke MessageBox,0,text,text,0
.code:0000000000402004 sub rsp, 20h
.code:0000000000402008 mov rcx, 0 ; hWnd
.code:000000000040200F mov rdx, offset Text ; lpText
.code:0000000000402016 mov r8, offset Text ; lpCaption
.code:000000000040201D mov r9, 0 ; uType
.code:0000000000402024 call cs:MessageBoxA
.code:000000000040202A add rsp, 20h

Срезюмирую.
Выравнивать стек с кратностью 16 нужно не перед вызовом функции, а с учётом вызова, т.е. перед вызовом он как раз таки не должен быть кратен 16, но кратен 8. Тогда при вызове функции адрес возврата в аккурат его подравняет.

З.Ы. Столпы апологеты, сильно не пинайте. Хотел внести ясность прежде всего для себя. В чём не прав укажите. Если конечно кто то это кирпич текста осилит.
4
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.12.2014, 19:08
Ответы с готовыми решениями:

Нюансы работы стека при вызове функций
Добрый день! # include <iostream> int foo(int b,int w){ int y=b+3; return y; } int main(){ int c=2;

Соглашение о вызове фукции
Чем в обусловлено использование соглашения stdcall в winAPI?

Calling convention (Соглашение о вызове) c#
Какое соглашение о вызове функций (Calling convention) используется в C# (CIL) по умолчанию? Нигде не могу найти информации, вероятно в C#...

30
Эксперт быдлокодинга
 Аватар для Полный 30h
2095 / 529 / 70
Регистрация: 04.11.2010
Сообщений: 1,314
27.03.2015, 00:51  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Убежденный Посмотреть сообщение
Ведь x64-версии
kernel32.dll, ntdll.dll и т.п. напичканы SSE, там везде проверки и
на невыровненных данных сразу генерируется alignment fault...
Если честно для меня это пока что тёмный лес. Я воспринимаю данный уровень уже как божественную данность на которую не могу повлиять. Однако следуя житейской логике про себя думал что kernel32.dll как бы намекает на его 32 битную природу с соответствующим наследием.
0
Модератор
Эксперт по компьютерным сетямЭксперт Windows
 Аватар для NoNaMe
2623 / 760 / 164
Регистрация: 10.06.2009
Сообщений: 2,989
27.03.2015, 01:50
[SPOILER"offtop"]kernel32.dll, ntdll.dll в папке system32 все x64
kernel32.dll, ntdll.dll в папке SysWOW64 все x32
папка system для 16bit[/SPOILER]
После выполнения программа проверяется на правильность завершения.
Написано уже очень много в винде, а она всё толще и толще.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
27.03.2015, 09:19
Цитата Сообщение от NoNaMe Посмотреть сообщение
Я вот экспериментировал с данным моментом, и получил что стек можно двигать на n+4
Мои эксперименты говорят об обратном.
Windows 7 x64, консольное приложение:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
;
; MASM (ml64.exe)
;
 
;
; Disable standard compiler-generated
; prologue and epilogue for the functions.
;
option prologue:none
option epilogue:none
 
 
 
MessageBoxA         PROTO
ExitProcess         PROTO
 
 
 
.data
 
Text    db "Hello, World !",0
Caption db "Info",0
 
 
 
.code
 
MyEntryPoint PROC
 
    sub rsp, 038h; Align the stack pointer.
 
    ; sub rsp, 0;  [FAILED]
    ; sub rsp, 4;  [FAILED]
    ; sub rsp, 8;  [OK]
    ; sub rsp, 12; [FAILED]
    ; sub rsp, 16; [FAILED]
    ; sub rsp, 20; [FAILED]
    ; sub rsp, 24; [OK]
    ; sub rsp, 28; [FAILED]
    ; sub rsp, 32; [FAILED]
    ; sub rsp, 36; [FAILED]
    ; sub rsp, 40; [OK]
    ; sub rsp, 44; [FAILED]
    ; sub rsp, 48; [FAILED]
    ; sub rsp, 52; [FAILED]
    ; sub rsp, 56; [OK]
    ; sub rsp, 60; [FAILED]
    ; sub rsp, 64; [FAILED]
 
    mov rcx, 0
    mov rdx, offset Text
    mov r8,  offset Caption
    mov r9,  0
    call MessageBoxA
    
    mov rcx, 0
    call ExitProcess
    
    add rsp, 038h; Restore stack pointer.    
    ret
 
MyEntryPoint ENDP
 
END
Если поменять аргумент для "sub rsp" на любое значение из [FAILED]-строки,
то при запуске программа падает, до ExitProcess дело не доходит.

Цитата Сообщение от NoNaMe Посмотреть сообщение
Даже 5-ый аргумент функции передавать не надо, если он равен 0 то она сама подставляет.
Ничего она не подставляет. Просто в "rsp+0x20" случайно оказался 0.
1
Эксперт быдлокодинга
 Аватар для Полный 30h
2095 / 529 / 70
Регистрация: 04.11.2010
Сообщений: 1,314
27.03.2015, 11:07  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
Сообщение от NoNaMe
Я вот экспериментировал с данным моментом, и получил что стек можно двигать на n+4
Мои эксперименты говорят об обратном.
У меня всё пучком.

Видимо нестабильное колдунство.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
27.03.2015, 11:40
Цитата Сообщение от Полный 30h Посмотреть сообщение
У меня всё пучком.
Попробуй с MessageBox. Понятно, что не на любых WinAPI-функциях
это "волшебство" проявляется. У меня, например, на 64-битной
Windows Server 2003 R2 падает на CreateRemoteThread на невыровненном
стеке (генерируется исключение в nt!ExRaiseDataTypeMisalignment), а
тот же код на Windows 7 работает нормально.
0
Эксперт быдлокодинга
 Аватар для Полный 30h
2095 / 529 / 70
Регистрация: 04.11.2010
Сообщений: 1,314
27.03.2015, 12:37  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
Попробуй с MessageBox. Понятно, что не на любых WinAPI-функциях
это "волшебство" проявляется.
Так я и без проб могу сказать что обрыбится сразу. Потому что MessageBox это окошко, а шаманство работает только в консоли. В ширину по API не копал. Потому как практического применения для этой задрочки я себе не увидел, а перебирать от нечего делать как то не моё.
0
Модератор
Эксперт по компьютерным сетямЭксперт Windows
 Аватар для NoNaMe
2623 / 760 / 164
Регистрация: 10.06.2009
Сообщений: 2,989
27.03.2015, 16:34
Данное шаманство работает если мы не обращаемся к стеку.
FASM WriteConsole+MessageBox WINDOWS_CUI/GUI
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
IMAGE_DOS_SIGNATURE equ 5A4Dh
IMAGE_NT_SIGNATURE  equ 00004550h
 
IMAGE_MACHINE_UNKNOWN   equ 0
IMAGE_MACHINE_I386      equ 014Ch  ; Intel 386
IMAGE_MACHINE_I860      equ 014Dh  ; Intel i860
IMAGE_MACHINE_R3000B    equ 0160h  ; MIPS R3000 big-endian
IMAGE_MACHINE_R3000L    equ 0162h  ; MIPS R3000 little-endian
IMAGE_MACHINE_R4000     equ 0166h  ; MIPS little-endian
IMAGE_MACHINE_R10000    equ 0168h  ; MIPS little-endian
IMAGE_MACHINE_WCEMIPSV2 equ 0169h  ; MIPS little-endian WCE v2
IMAGE_MACHINE_OLD_ALPHA equ 0184h  ; old Alpha AXP
IMAGE_MACHINE_ALPHA     equ 0184h  ; Alpha AXP
IMAGE_MACHINE_SH3       equ 01A2h  ; Hitachi SH3 little-endian
IMAGE_MACHINE_SH3DSP    equ 01A3h  ; Hitachi SH3 little-endian DSP
IMAGE_MACHINE_SH3E      equ 01A4h  ; Hitachi SH3E little-endian
IMAGE_MACHINE_SH4       equ 01A6h  ; Hitachi SH4 little-endian
IMAGE_MACHINE_SH5       equ 01A8h  ; Hitachi SH5
IMAGE_MACHINE_ARM       equ 01C0h  ; ARM Little-Endian
IMAGE_MACHINE_THUMB     equ 01C2h  ; Thumb
IMAGE_MACHINE_AM33      equ 01D3h  ; Matsushita AM33
IMAGE_MACHINE_POWERPC   equ 01F0h  ; IBM PowerPC Little-Endian
IMAGE_MACHINE_POWERPCFP equ 01F1h  ; IBM PowerPC with floating point support
IMAGE_MACHINE_IA64      equ 0200h  ; Intel IA64
IMAGE_MACHINE_MIPS16    equ 0266h  ; MIPS16
IMAGE_MACHINE_ALPHA64   equ 0284h  ; ALPHA64
IMAGE_MACHINE_MIPSFPU   equ 0366h  ; MIPS with FPU
IMAGE_MACHINE_MIPSFPU16 equ 0466h  ; MIPS16 with FPU
IMAGE_MACHINE_TRICORE   equ 0520h  ; Infineon
IMAGE_MACHINE_CEF       equ 0CEFh                   ;UNKNOWN
IMAGE_MACHINE_EBC       equ 0EBCh  ; EFI Byte Code
IMAGE_MACHINE_AMD64     equ 8664h  ; AMD AMD64 (K8)
IMAGE_MACHINE_M32R      equ 9041h  ; Mitsubishi M32R little-endian
IMAGE_MACHINE_CEE       equ C0EEh                   ;UNKNOWN
 
;IMAGE_SCN_TYPE_REG                  equ 00000000h  ; Reserved.
;IMAGE_SCN_TYPE_DSECT                equ 00000001h  ; Reserved.
;IMAGE_SCN_TYPE_NOLOAD               equ 00000002h  ; Reserved.
;IMAGE_SCN_TYPE_GROUP                equ 00000004h  ; Reserved.
IMAGE_SCN_TYPE_NO_PAD                equ 00000008h  ; Reserved.
;IMAGE_SCN_TYPE_COPY                 equ 00000010h  ; Reserved.
 
IMAGE_SCN_CNT_CODE                   equ 00000020h  ; Section contains code.
IMAGE_SCN_CNT_INITIALIZED_DATA       equ 00000040h  ; Section contains initialized data.
IMAGE_SCN_CNT_UNINITIALIZED_DATA     equ 00000080h  ; Section contains uninitialized data.
 
IMAGE_SCN_LNK_OTHER                  equ 00000100h  ; Reserved.
IMAGE_SCN_LNK_INFO                   equ 00000200h  ; Section contains comments or some  other type of information.
;IMAGE_SCN_TYPE_OVER                 equ 00000400h  ; Reserved.
IMAGE_SCN_LNK_REMOVE                 equ 00000800h  ; Section contents will not become part of image.
IMAGE_SCN_LNK_COMDAT                 equ 00001000h  ; Section contents comdat.
;                                    equ 00002000h  ; Reserved
;IMAGE_SCN_MEM_PROTECTED             equ 00004000h  ; Reserved IMAGE_SCN_MEM_PROTECTED - Obsolete
IMAGE_SCN_NO_DEFER_SPEC_EXC          equ 00004000h  ; Reset speculative exceptions handling bits in the TLB entries for this section.
IMAGE_SCN_GPREL                      equ 00008000h  ; Section content can be accessed relative to GP
IMAGE_SCN_MEM_FARDATA                equ 000080000  ;
;IMAGE_SCN_MEM_SYSHEAP               equ 00010000h  ; Reserved IMAGE_SCN_MEM_SYSHEAP  - Obsolete
IMAGE_SCN_MEM_PURGEABLE              equ 000200000  ;
IMAGE_SCN_MEM_16BIT                  equ 000200000  ;
IMAGE_SCN_MEM_LOCKED                 equ 000400000  ;
IMAGE_SCN_MEM_PRELOAD                equ 000800000  ;
 
IMAGE_SCN_ALIGN_1BYTES               equ 00100000h  ;
IMAGE_SCN_ALIGN_2BYTES               equ 00200000h  ;
IMAGE_SCN_ALIGN_4BYTES               equ 00300000h  ;
IMAGE_SCN_ALIGN_8BYTES               equ 00400000h  ;
IMAGE_SCN_ALIGN_16BYTES              equ 00500000h  ; Default alignment if no others are specified.
IMAGE_SCN_ALIGN_32BYTES              equ 00600000h  ;
IMAGE_SCN_ALIGN_64BYTES              equ 00700000h  ;
IMAGE_SCN_ALIGN_128BYTES             equ 00800000h  ;
IMAGE_SCN_ALIGN_256BYTES             equ 00900000h  ;
IMAGE_SCN_ALIGN_512BYTES             equ 00A00000h  ;
IMAGE_SCN_ALIGN_1024BYTES            equ 00B00000h  ;
IMAGE_SCN_ALIGN_2048BYTES            equ 00C00000h  ;
IMAGE_SCN_ALIGN_4096BYTES            equ 00D00000h  ;
IMAGE_SCN_ALIGN_8192BYTES            equ 00E00000h  ;
 
;Unused                               equ 00F00000h  ;
IMAGE_SCN_ALIGN_MASK                 equ 00F00000h  ;
 
IMAGE_SCN_LNK_NRELOC_OVFL            equ 01000000h  ; Section contains extended relocations.
IMAGE_SCN_MEM_DISCARDABLE            equ 02000000h  ; Section can be discarded.
IMAGE_SCN_MEM_NOT_CACHED             equ 04000000h  ; Section is not cachable.
IMAGE_SCN_MEM_NOT_PAGED              equ 08000000h  ; Section is not pageable.
IMAGE_SCN_MEM_SHARED                 equ 10000000h  ; Section is shareable.
IMAGE_SCN_MEM_EXECUTE                equ 20000000h  ; Section is executable.
IMAGE_SCN_MEM_READ                   equ 40000000h  ; Section is readable.
IMAGE_SCN_MEM_WRITE                  equ 80000000h  ; Section is writeable.
 
IMAGE_SUBSYSTEM_UNKNOWN                  equ 0    ;  Unknown subsystem.
IMAGE_SUBSYSTEM_NATIVE                   equ 1    ;  Image doesn't require a subsystem.
IMAGE_SUBSYSTEM_WINDOWS_GUI              equ 2    ;  Image runs in the Windows GUI subsystem.
IMAGE_SUBSYSTEM_WINDOWS_CUI              equ 3    ;  Image runs in the Windows character subsystem.
IMAGE_SUBSYSTEM_OS2_CUI                  equ 5    ;  image runs in the OS/2 character subsystem.
IMAGE_SUBSYSTEM_POSIX_CUI                equ 7    ;  image runs in the Posix character subsystem.
IMAGE_SUBSYSTEM_NATIVE_WINDOWS           equ 8    ;  image is a native Win9x driver.
IMAGE_SUBSYSTEM_WINDOWS_CE               equ 9                          
IMAGE_SUBSYSTEM_EFI_APPLICATION          equ 10
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER  equ 11
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER       equ 12
IMAGE_SUBSYSTEM_EFI_ROM                  equ 13
IMAGE_SUBSYSTEM_XBOX                     equ 14
IMAGE_SUBSYSTEM_UNKNOWN2                 equ 15
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION equ 16
 
IMAGE_NT_OPTIONAL_HDR64_MAGIC   equ 523  ;20Bh    ; NT MAGIC translation code x64
IMAGE_NT_OPTIONAL_HDR32_MAGIC   equ 267  ;10Bh    ; NT MAGIC translation code x32
 
IMAGE_FILE_RELOCS_STRIPPED  equ 1
IMAGE_FILE_EXECUTABLE_IMAGE equ 2
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE equ 8000h
exebase         equ 400000h
include 'include\WIN64A.INC'
org 0
use64
 
Signature:               dq IMAGE_DOS_SIGNATURE,0
ntHeader                 dd IMAGE_NT_SIGNATURE;'PE'
;image_header--------------------------
.Machine                 dw IMAGE_MACHINE_AMD64
.Count_of_section        dw 1
.TimeStump               dd 0
.Symbol_table_offset     dd 0
.Symbol_table_count      dd 0
.Size_of_optional_header dw section_table-optional_header
.Characteristics         dw 0x20 or IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_EXECUTABLE_IMAGE
;20h = Handle >2Gb addresses
;-------------------------------------
optional_header:
.Magic_optional_header          dw IMAGE_NT_OPTIONAL_HDR64_MAGIC
.Linker_version_major_minor     db 9,0
.Size_of_code                   dd 0x60
.Size_of_init_data              dd 0x00
.Size_of_uninit_data            dd 0
.entry_point                    dd begin
.base_of_code                   dd ntHeader
.image_base                     dq 0x140000000
.section_alignment              dd 0x10
.file_alignment                 dd 0x10
.OS_version_major_minor         dw 5,2
.image_version_major_minor      dd 0
.subsystem_version_major_minor  dw 5,2
.Win32_version                  dd 0
.size_of_image                  dd end_import-1h
.size_of_header                 dd begin
.checksum                       dd 0x8C1B  ; calc checksum
.subsystem                      dw IMAGE_SUBSYSTEM_WINDOWS_CUI
.DLL_flag                       dw IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
.Stack_allocation               dq 0x100000
.Stack_commit                   dq 0x1000
.Heap_allocation                dq 0x100000
.Heap_commit                    dq 0x1000
.loader_flag                    dd 0
.number_of_dirs                 dd (section_table-export_RVA_size)/8
export_RVA_size                 dq 0
.import_RVA                     dd import_
.import_size                    dd end_import-import_
;------------------------------------------------
section_table:      dq '.text'
.virtual_size       dd 0x55
.virtual_address    dd begin
.Physical_size      dd end_import-begin
.Physical_offset    dd begin
.Relocations        dd 0
.Linenumbers        dd 0
.Relocations_and_Linenumbers_count dd 0
.Attributes      dd IMAGE_SCN_MEM_WRITE or IMAGE_SCN_CNT_CODE;0x80000020
;-------------------------------------------------
begin:
enter 20h, 0h
    mov ecx,7
    lea rdx, [msgtw]
    mov r8d, 18h
    xor r9d,r9d
    call [WriteConsole]
    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]
leave
ret;-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-
;------------------------------------------------
msgtw db "Win64 Assembly is Great!",0
MsgCaption db "Iczelion's tutorial #2", 0
MsgBoxText db "Win64 Assembly is Great!",0
;------------------------------------------------
Import_Table:
kernel32_table:
WriteConsole dq _WriteConsole,0
user32_table:
MessageBox  dq _MessageBox,0
import_:
dd 0,0,0,user32_dll,user32_table
dd 0,0,0,kernel32_dll,kernel32_table
dq 0,0,0
_MessageBox     db 0,0,"MessageBoxA",0
user32_dll      db "user32",0,0
_WriteConsole   db 0,0,"WriteConsoleA",0
kernel32_dll    db "kernel32"
end_import:

~enter 20h, 0h~ и ~leave~ И никакого шаманства нету)
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
27.03.2015, 16:57
Цитата Сообщение от NoNaMe Посмотреть сообщение
Данное шаманство работает если мы не обращаемся к стеку.
А можно мне exe-шничек на тест ?
0
Модератор
Эксперт по компьютерным сетямЭксперт Windows
 Аватар для NoNaMe
2623 / 760 / 164
Регистрация: 10.06.2009
Сообщений: 2,989
27.03.2015, 18:20
HellowCUI_GUI.7z

Добавлено через 53 минуты
В моём варианте стек стал равен:
n+10h
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
27.03.2015, 19:21
Вот что значит долго не писать на ассемблере !
Я уже подумал, что enter/leave - это какие-то макросы FASM-а и
хотел глянуть, какой ассемблерный код будет сгенерирован

А так все верно, enter в данном случае ведь все равно выравнивает
RSP по границе 16 байт. Так что шаманства действительно нету...
0
Модератор
Эксперт по компьютерным сетямЭксперт Windows
 Аватар для NoNaMe
2623 / 760 / 164
Регистрация: 10.06.2009
Сообщений: 2,989
31.03.2015, 10:36
Ничего она не подставляет. Просто в "rsp+0x20" случайно оказался 0.
Взял дебагер, и убедился...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
31.03.2015, 10:36

Выравнивание стека на x64
все , с регистрами я разобрался. вроде понял, немного работу отладчика. но только на самом поверхностном уровне. про выравнивание...

GCC и выравнивание стека
Никак не могу найти, можно ли GCC заставить выравнивать данные по заданной границе, если быть точным, то я хочу, чтобы 3 матрицы в моей...

Переполнение стека при вызове рекурсивной функции
Вообщем есть у меня рекурсивный вызов функции, и как я понял у меня переполняется некий "стек вызовов" ( там рандом, так что...

Переполнение стека при первом же вызове функции
Обычно переполнение стека возникает при глубокой (в том числе бесконечной) рекурсии, не так ли? А тут функция вызывается первый раз, в...

Переполнение стека при вызове функции из Dll
Есть Dll на С++, в ней определена функция extern "C" __declspec(dllexport) long __stdcall Connect (long theSmartlinkTag, char*...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
31
Ответ Создать тему
Новые блоги и статьи
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов. Логика кажется понятной: 1. Находим ключевые слова. 2. Добавляем их на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru