Форум программистов, компьютерный форум, киберфорум
Assembler: MASM64, х64/long mode
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.82/65: Рейтинг темы: голосов - 65, средняя оценка - 4.82
250 / 60 / 6
Регистрация: 21.05.2017
Сообщений: 73

Соглашение о вызовах x64

09.06.2017, 01:29. Показов 13583. Ответов 27

Студворк — интернет-сервис помощи студентам
В x64-соглашении первые четыре целочисленных аргумента (слева направо) передаются в 64-битных регистрах, выбранных специально для этой цели:
RCX: 1-й целочисленный аргумент
RDX: 2-й целочисленный аргумент
R8: 3-й целочисленный аргумент
R9: 4-й целочисленный аргумент
Остальные целочисленные аргументы передаются через стек.
Указатель «this» считается целочисленным аргументом, поэтому он всегда помещается в регистр RCX.
Если передаются значения с плавающей точкой, то первые четыре из них передаются в регистрах XMM0-XMM3, а последующие — через стек.
Так?
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    push 0                      ;lpParam
    lea r10, hInst
    push r10                    ;hInstance
    push 0                      ;hMenu
    push 0                      ;hWndParent 
    lea r10, CW_USEDEFAULT      ;nHeight
    push r10
    lea r10, CW_USEDEFAULT      ;nWidth
    push r10
    lea r10, CW_USEDEFAULT      ;y
    push r10
    lea r10, CW_USEDEFAULT      ;x
    push r10
    lea r9, WS_OVERLAPPEDWINDOW ;dwStyle
    lea r8, lpWindowName
    lea rdx, lpClassName
    xor rcx, rcx                ;dwExStyle
    call CreateWindowExA
2
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.06.2017, 01:29
Ответы с готовыми решениями:

Соглашения о вызовах и masm64
Недавно начал создавать dll на масме64 для си++. Почитал на http://msdn.microsoft.com/ru-ru/library/ms235286.aspx соглашение о вызовах в...

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

Используя соглашение stdcall вызвать функцию на ассемблере
надо используя соглашения stdcall вызвать функцию на ассемблере и используя соглашения cdecl и fastcall вызвать функции с программы на си ...

27
250 / 60 / 6
Регистрация: 21.05.2017
Сообщений: 73
11.09.2017, 12:31  [ТС]
Студворк — интернет-сервис помощи студентам
Спасибо Вам!
Файлы присылаю, а ml64 и link у меня из VS2015. Другие версии не пробовал.
Дебаггер x64dbg зависает после запуска с точки останова GetMessage
Вложения
Тип файла: zip SDI_Ablyazov.zip (3.2 Кб, 8 просмотров)
1
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6816 / 2055 / 239
Регистрация: 14.12.2014
Сообщений: 4,318
Записей в блоге: 12
11.09.2017, 22:25
Не знаю в чём там проблема. Выглядит нормально.

Цитата Сообщение от ml64 Посмотреть сообщение
Дебаггер x64dbg зависает после запуска с точки останова GetMessage
У меня при вызове CreateWindowEx падает на movaps [rax-28h],xmm6 в модуле uxtheme из-за отсутствия выравнивания по 16 байтам. Хотя стек при вызове CreateWindowEx выровнен.
0
250 / 60 / 6
Регистрация: 21.05.2017
Сообщений: 73
11.09.2017, 22:46  [ТС]
Млин. Но всё равно спасибо огромнейшее...
...Где-нибудь ключ не поставлен или директива какая-нибудь. Так наскоком не возьмёшь. Буду курить мануалы...
По результату отпишусь
1
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6816 / 2055 / 239
Регистрация: 14.12.2014
Сообщений: 4,318
Записей в блоге: 12
11.09.2017, 23:17
Есть аналогичный пример на fasm? Только полный исходник...
0
250 / 60 / 6
Регистрация: 21.05.2017
Сообщений: 73
11.09.2017, 23:54  [ТС]
Вот он:
Вложения
Тип файла: zip Ablyazov.zip (1.4 Кб, 6 просмотров)
1
250 / 60 / 6
Регистрация: 21.05.2017
Сообщений: 73
17.09.2017, 01:21  [ТС]
Правильное решение найдено. Выравнивать стек нужно в каждой процедуре.

Теперь есть готовая оконная среда, и можно переходить к разработке нетривиальных приложений.
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
include D:\bin\dev\ml64\VS2015\include\user32.inc
include D:\bin\dev\ml64\VS2015\include\kernel32.inc
includelib D:\bin\dev\ml64\VS2015\lib\user32.lib
includelib D:\bin\dev\ml64\VS2015\lib\kernel32.lib
 
include D:\hob\dev\asm\x64\002_SDI\01_Caecus\include\struct64_03.inc
 
.const
 WindowName db '64-bit SDI Application assembled with MASM',0
 ClassName db 'clsSDI64',0
 
 WinMain_msg db 'Вход в процедуру WinMain выполнен',0
 hInst_msg db 'Дескриптор программы получен',0
 hWnd_msg db 'Дескриптор окна получен',0
 clsReg_msg db 'Класс окна зарегистрирован',0
 pre_loop_msg db 'Готов к входу в цикл обработки сообщений окна',0
 
 err_caption db 'Ошибка',0
 err_loop_msg db 'GetMessageA возвратила код ошибки (-1)',0
 
.data
wcSDI64 label WNDCLASSEX64
  cbSize dd sizeof WNDCLASSEX64
  style dd 0
  lpfnWndProc dq offset WndProc
  cbClsExtra dd 0
  cbWndExtra dd 0
  hInstance dq ?
  hIcon dq ?
  hCursor dq ?
  hbrBackground dq 1
  lpszMenuName dq 0
  lpszClassName dq offset ClassName
  hIconSm dq 0
 
msgSDI64 label MSG64
 
.code
WinMain proc
 
;Выравниваем стек и создаём буфер для процедуры WinMain
  sub rsp, 28h
 
  xor rcx, rcx          ;hWnd
  lea rdx, WinMain_msg      ;lpText
  lea r8, WindowName        ;lpCaption
  xor r9, r9            ;uType = MB_OK = 0
  call MessageBoxA
 
;Получаем дескриптор программы
  xor rcx, rcx
  call GetModuleHandleA
;hInstance - дескриптор программы
  mov wcSDI64.hInstance, rax
 
  cmp rax, 0
  je goodbye
  xor rcx, rcx          ;hWnd
  lea rdx, hInst_msg        ;lpText
  lea r8, WindowName        ;lpCaption
  xor r9, r9            ;uType = MB_OK = 0
  call MessageBoxA
 
;Загружаем пиктограмму
  xor rcx, rcx      ;Загрузить из числа системных
  mov rdx, 32515    ;hIcon = IDI_APPLICATION = 32512
  call LoadIconA
  mov wcSDI64.hIcon, rax
;Загружаем курсор
  xor rcx, rcx      ;Загрузить из числа системных
  mov rdx, 32649    ;hCursor = IDC_ARROW = 32512
  call LoadCursorA
  mov wcSDI64.hCursor, rax
 
;Регистрируем класс окна
  xor rax, rax
  lea rcx, wcSDI64
  call RegisterClassEx
 
  cmp rax, 0
  je goodbye
  xor rcx, rcx          ;hWnd
  lea rdx, clsReg_msg       ;lpText
  lea r8, WindowName        ;lpCaption
  xor r9, r9            ;uType = MB_OK = 0
  call MessageBoxA
 
;Создаём окно
  sub rsp, 40h
  xor rcx, rcx                  ;dwExStyle
  lea rdx, ClassName
  lea r8, WindowName
  mov r9, 00CF0000h         ;dwStyle = WS_OVERLAPPEDWINDOW = 00CF.0000h
  mov qword ptr [rsp+20h], 80000000h    ;x = CW_USEDEFAULT = 8000.0000h
  mov qword ptr [rsp+28h], 80000000h    ;y = СW_USEDEFAULT = 8000.0000h
  mov qword ptr [rsp+30h], 80000000h    ;nWidth = CW_USEDEFAULT = 8000.0000h
  mov qword ptr [rsp+38h], 80000000h    ;nHeight = CW_USEDEFAULT = 8000.0000h
  mov qword ptr [rsp+40h], 0        ;hWndParent 
  mov qword ptr [rsp+48h], 0        ;hMenu
  mov rax, wcSDI64.hInstance
  mov qword ptr [rsp+50h], rax      ;hInstance
  mov qword ptr [rsp+58h], 0        ;lpParam 
  call CreateWindowExA
  add rsp, 40h
 
;hWnd - дескриптор окна
  mov msgSDI64.hWnd, rax
 
  cmp rax, 0
  je goodbye
  xor rcx, rcx          ;hWnd
  lea rdx, hWnd_msg     ;lpText
  lea r8, WindowName        ;lpCaption
  xor r9, r9            ;uType = MB_OK = 0
  call MessageBoxA
 
;Показываем окно:
  mov rcx, msgSDI64.hWnd
  mov rdx, 1            ;nCmdShow = SW_SHOWNORMAL = 1
  call ShowWindow
 
;Обновляем окно:
  mov rcx, msgSDI64.hWnd
  call UpdateWindow
 
  xor rcx, rcx          ;hWnd
  lea rdx, pre_loop_msg     ;lpText
  lea r8, WindowName        ;lpCaption
  xor r9, r9            ;uType = MB_OK = 0
  call MessageBoxA
 
;Цикл обработки сообщений окна
msg_loop:
  lea rcx, msgSDI64     ;lpMsg
  xor rdx, rdx          ;hWnd
  xor r8, r8            ;wMsgFilterMin
  xor r9, r9            ;wMsgFilterMax
  call GetMessageA
 
  cmp rax, 1
  jb goodbye            ;Если WM_QUIT = 0
  jne err_loop          ;Код_ошибки = -1
 
  lea rcx, msgSDI64
  call TranslateMessage
  lea rcx, msgSDI64
  call DispatchMessageA
  jmp msg_loop
 
err_loop:
  xor rcx, rcx          ;hWnd
  lea rdx, err_loop_msg     ;lpText
  lea r8, err_caption       ;lpCaption
  xor r9, r9            ;uType = MB_OK = 0
  call MessageBoxA
 
goodbye:
  xor rcx, rcx
  call ExitProcess      ;В процедуре WinMain должен быть ExitProcess
WinMain endp
 
WndProc proc
;Выравниваем стек и создаём буфер для процедуры WndProc
  sub rsp, 28h
 
  cmp rdx, 2            ;WM_DESTROY = 2
  je destroy
 
default:
  ;mov rcx, msgSDI64.hWnd
  ;mov rdx, qword ptr msgSDI64.message
  ;xor r8, r8           ;wParam,
  ;xor r9, r9           ;lParam
  call DefWindowProc        ;Параметры уже заданы функцией DispatchMessageA
  jmp finish
destroy:
  xor rcx, rcx
  call PostQuitMessage      ;В процедуре WndProc должен быть PostQuitMessage
  xor eax, eax
finish:
  add rsp, 28h          ;Восстановление стека после процедуры WndProc
  ret
WndProc endp
end
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
;struct64_03.inc
 
POINT64 STRUCT      ;typedef struct tagPOINT {
  x dd ?        ;LONG x;
  y dd ?        ;LONG y;
POINT64 ENDS        ;} POINT, *PPOINT;
 
MSG64 STRUCT        ;typedef struct tagMSG {     // msg 
  hWnd dq ?     ;HWND hWnd;     Identifies the window whose window procedure receives the message
  message dd ?      ;UINT message;      Specifies the message number
  wParam dq ?       ;WPARAM wParam;     Specifies additional information about the message
  lParam dq ?       ;LPARAM lParam;     Specifies additional information about the message
  time dd ?     ;DWORD time;        Specifies the time at which the message was posted
  pt POINT64 <?>    ;POINT pt;      Specifies the cursor position, in screen coordinates, when the message was posted
MSG64 ENDS      ;} MSG;
 
WNDCLASSEX64 STRUCT ;typedef struct tagWNDCLASSEX {
  cbSize dd ?       ;UINT cbSize;       The size, in bytes, of this structure
  style dd ?        ;UINT style;        The class style(s)
  lpfnWndProc dq;WNDPROC lpfnWndProc;   A pointer to the window procedure
  cbClsExtra dd ?   ;int cbClsExtra;    The number of extra bytes to allocate following the window-class structure
  cbWndExtra dd ?   ;int cbWndExtra;    The number of extra bytes to allocate following the window instance
  hInstance dq ?    ;HINSTANCE hInstance;   A handle to the instance that contains the window procedure for the class
  hIcon dq ?        ;HICON hIcon;       A handle to the class icon
  hCursor dq;HCURSOR hCursor;   A handle to the class cursor
  hbrBackground dq ?    ;HBRUSH hbrBackground;  A handle to the class background brush
  lpszMenuName dq ? ;LPCTSTR lpszMenuName;  Pointer to a null-terminated character string that specifies the resource name of the class menu, as the name appears in the resource file
  lpszClassName dq ?    ;LPCTSTR lpszClassName; A pointer to a null-terminated string or is an atom
  hIconSm dq;HICON hIconSm;     A handle to a small icon that is associated with the window class
WNDCLASSEX64 ENDS   ;} WNDCLASSEX, *PWNDCLASSEX;
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@echo off
 
set filename=Caecus_056_proc
 
if exist %filename%.obj del %filename%.obj
if exist %filename%.exe del %filename%.exe
 
D:\bin\dev\ml64\VS2015\bin\ml64 /c %filename%.asm
D:\bin\dev\ml64\VS2015\bin\link %filename%.obj /ENTRY:WinMain /SUBSYSTEM:WINDOWS /LARGEADDRESSAWARE:NO
 
del %filename%.obj
 
dir %filename%.*
 
pause
1
250 / 60 / 6
Регистрация: 21.05.2017
Сообщений: 73
19.09.2017, 13:46  [ТС]
Лучший ответ Сообщение было отмечено ФедосеевПавел как решение

Решение

И в завершение - анализ моей ошибки при переводе кода Руслана Аблязова.

Суть программы: SDI-окно с двумя кнопками, одна из которых выводит MessageBox "О программе", другая - завершает программу.

Вот моя ошибка:
Assembler
1
2
3
msgSDI64 label MSG64
msgAbout label MSG64
msgExit label MSG64
Я пытался создать три структуры типа MSG64, хотя для одной оконной процедуры WndProc нужна одна структура сообщений.
Каждая кнопка (BUTTON) в Windows - это самостоятельное дочернее окно. Каждая кнопка подлежит регистрации и обладает уникальным дескриптором окна, но все кнопки ссылаются на единый (родительский) дескриптор программы и посылают сообщения в единую структуру.
1
250 / 60 / 6
Регистрация: 21.05.2017
Сообщений: 73
16.12.2017, 21:19  [ТС]
Мне всё-таки надоело каждый раз загружать параметры в регистры.
Вместо макроса invoke я сделал свои маленькие вызывалки, без блэкджека и прочих излишеств.
Они просто загружают параметры в регистры, не меняя указатель стека.
Т.е. я (это лишь мой эксперимент) не резервирую стек перед каждым вызовом,
а один раз в прологе каждой процедуры выравниваю по 10h и просаживаю на 80h:
Assembler
1
2
and rsp, -16
sub rsp, 80h
Почему and rsp, -16? - Чтобы не заморачиваться каждый раз вычислением вершины стека, которая зависит от числа параметров процедуры, используемых регистров и локальных переменных
Почему 80h? - С потолка. С запасом. На 16 гипотетических параметров по 8 байт.
Вроде работает.
Если я не прав, то очень прошу: скажите об этом, пожалуйста,
потому что это ассемблер, и я могу осознать ошибку очень не скоро.

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
;-----------------------------------------------------------------------------------------
;Макросы-аналоги INVOKE, которые помещают параметры в регистры и вызывают внешнюю функцию,
;но в отличие от invoke не изменяют регистра rsp
;(предполагается, что в прологе вызывающей процедуры выполнена инструкция sub rsp,20h,
;а в эпилоге предусмотрена инструкция add rsp,20h либо leave)
;Вход: имя вызываемой функции и n параметров
;-----------------------------------------------------------------------------------------
Call5 MACRO funcname, par1, par2, par3, par4, par5
    mov rcx, par1
    mov rdx, par2
    mov r8, par3
    mov r9, par4
    mov rax, par5
    mov qword ptr [rsp+20h], rax
    call funcname
ENDM ;Call5
;-----------------------------------------------------------------------------------------
Call4 MACRO funcname, par1, par2, par3, par4
    mov rcx, par1
    mov rdx, par2
    mov r8, par3
    mov r9, par4
    call funcname
ENDM ;Call4
;-----------------------------------------------------------------------------------------
Call3 MACRO funcname, par1, par2, par3
    mov rcx, par1
    mov rdx, par2
    mov r8, par3
    call funcname
ENDM ;Call3
;-----------------------------------------------------------------------------------------
Call2 MACRO funcname, par1, par2
    mov rcx, par1
    mov rdx, par2
    call funcname
ENDM ;Call2
;-----------------------------------------------------------------------------------------
Call1 MACRO funcname, par1
    mov rcx, par1
    call funcname
ENDM ;Call1
;-----------------------------------------------------------------------------------------
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.12.2017, 21:19

Как зовут соглашение о вызовах для функции main консольного Window x 64 приложения?
Как зовут соглашение о вызовах для функции main консольного Window x 64 приложения?

FASM соглашение о вызовах winapi64 (который почему то всё так же называеться 32) ручками
Вот не сидеться мне на моём мягком месте спокойно и взялся я писать на асме без макросов(конечно же раньше даже с макросами не пробовал). ...

Соглашения о вызовах.
Соглашения о вызовах.

Соглашения о вызовах в Keil
Чёто полазил по справке и ничего про __cdecl или __fastcall какой, ни духом. Как быть?

Функции с разными соглашениями о вызовах
Здравствуйте. Вот, допустим, у меня есть две функции: void __stdcall FirstFunction(); void __thiscall SecondFunction(); ...


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

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Новые блоги и статьи
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
Сукцессия 20. Война автоботов. Делаем ставки. Лёд против "пш-пш!".
anaschu 11.07.2026
Битва ИИ в ризосфере: Как мы скрестили жесткие ОДУ, закон Фика и «подземный шантаж» Уважаемые коллеги! Хочу поделиться уникальным опытом ведения междисциплинарной компьютерной разработки. Прямо. . .
Сукцессия 19. Какие выводы я сделал из модели? Часть 2.Внутримикоризный стехиометрический буфер и хроно-дискретные зоны экспансии
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования
Сукцессия 18. Какие выводы я сделал из войны грибов с деревьями? Часть 1- рассказ и немного про термины
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования Система ОДУ описывает динамику изменения массы различных компонентов системы во времени. Ключевой. . .
Просветление в 5 секунд
kumehtar 10.07.2026
Андрей Веретенников выдал фразу недавно: "Вам не обязательно кем-то себя считать"
Эксперимент с картинкой-обложкой на CodinGame
Adler 10.07.2026
Решил на днях провести эксперимент. У меня есть аккаунт на CodinGame, ТОП-3 по РФ среди 2200 участников (в разделе соревнования по программированию ИИ-ботов). Там есть обложка, куда можно влепить. . .
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru