-
Notifications
You must be signed in to change notification settings - Fork 0
/
proc_mod.inc
433 lines (405 loc) · 10.8 KB
/
proc_mod.inc
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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
purge fastcall
;Just taken from FASM source and modfified
;Now uses unaligned qwords variable
macro fastcall proc,[arg]
{ common local stackspace,argscount,counter
if argscount < 4
qwords = 4
else
qwords = argscount
end if
counter = 0
if qwords
if defined current@frame
if current@frame < qwords
current@frame = qwords
end if
else
if argscount and 1
qwords = argscount+1
end if
if qwords
sub rsp, qwords*8
end if
end if
end if
forward
counter = counter + 1
define type@param
define definition@param arg
match =float value,definition@param
\{ define definition@param value
define type@param float \}
match =addr value,definition@param
\{ define definition@param value
define type@param addr \}
match any=,any,definition@param
\{ \local ..string,..continue
jmp ..continue
align sizeof.TCHAR
..string TCHAR definition@param,0
..continue:
define definition@param ..string
define type@param addr \}
match any,definition@param
\{ match \`any,any
\\{ \\local ..string,..continue
jmp ..continue
align sizeof.TCHAR
..string TCHAR definition@param,0
..continue:
define definition@param ..string
define type@param addr \\} \}
match param,definition@param
\{ local opcode,origin
size@param = 0
if param eqtype 0 | param eqtype 0f | type@param eq addr
size@param = 8
else if param eqtype byte 0 | param eqtype byte 0f
match prefix value,definition@param
\\{ if prefix eq qword
size@param = 8
else if prefix eq dword
size@param = 4
else if prefix eq word
size@param = 2
else if prefix eq byte
size@param = 1
end if \\}
else if ~ param in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
virtual
origin = $
inc param
load opcode byte from origin
if opcode = 67h | opcode = 41h
load opcode byte from origin+1
end if
if opcode and 0F8h = 48h
size@param = 8
else if opcode = 66h
size@param = 2
else if opcode = 0FFh
size@param = 4
else
size@param = 1
end if
end virtual
end if
if counter = 1
if type@param eq float
if ~ param eq xmm0
if size@param = 4
if param eqtype byte 0 | param eqtype byte 0f
mov eax,param
movd xmm0,eax
else
movd xmm0,param
end if
else
if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f
mov rax,param
movq xmm0,rax
else
movq xmm0,param
end if
end if
end if
if vararg@fastcall & ~ param eq rcx
movq rcx,xmm0
end if
else if type@param eq addr
if ~ param eq rcx
lea rcx,[param]
end if
else if size@param = 8
if ~ param eq rcx
mov rcx,param
end if
else if size@param = 4
if ~ param eq ecx
mov ecx,param
end if
else if size@param = 2
if ~ param eq cx
mov cx,param
end if
else if size@param = 1
if ~ param eq cl
mov cl,param
end if
end if
else if counter = 2
if type@param eq float
if ~ param eq xmm1
if size@param = 4
if param eqtype byte 0 | param eqtype byte 0f
mov eax,param
movd xmm1,eax
else
movd xmm1,param
end if
else
if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f
mov rax,param
movq xmm1,rax
else
movq xmm1,param
end if
end if
end if
if vararg@fastcall & ~ param eq rdx
movq rdx,xmm1
end if
else if type@param eq addr
if ~ param eq rdx
lea rdx,[param]
end if
else if size@param = 8
if ~ param eq rdx
mov rdx,param
end if
else if size@param = 4
if ~ param eq edx
mov edx,param
end if
else if size@param = 2
if ~ param eq dx
mov dx,param
end if
else if size@param = 1
if ~ param eq dl
mov dl,param
end if
end if
else if counter = 3
if type@param eq float
if ~ param eq xmm2
if size@param = 4
if param eqtype byte 0 | param eqtype byte 0f
mov eax,param
movd xmm2,eax
else
movd xmm2,param
end if
else
if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f
mov rax,param
movq xmm2,rax
else
movq xmm2,param
end if
end if
end if
if vararg@fastcall & ~ param eq r8
movq r8,xmm2
end if
else if type@param eq addr
if ~ param eq r8
lea r8,[param]
end if
else if size@param = 8
if ~ param eq r8
mov r8,param
end if
else if size@param = 4
if ~ param eq r8d
mov r8d,param
end if
else if size@param = 2
if ~ param eq r8w
mov r8w,param
end if
else if size@param = 1
if ~ param eq r8b
mov r8b,param
end if
end if
else if counter = 4
if type@param eq float
if ~ param eq xmm3
if size@param = 4
if param eqtype byte 0 | param eqtype byte 0f
mov eax,param
movd xmm3,eax
else
movd xmm3,param
end if
else
if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f
mov rax,param
movq xmm3,rax
else
movq xmm3,param
end if
end if
end if
if vararg@fastcall & ~ param eq r9
movq r9,xmm3
end if
else if type@param eq addr
if ~ param eq r9
lea r9,[param]
end if
else if size@param = 8
if ~ param eq r9
mov r9,param
end if
else if size@param = 4
if ~ param eq r9d
mov r9d,param
end if
else if size@param = 2
if ~ param eq r9w
mov r9w,param
end if
else if size@param = 1
if ~ param eq r9b
mov r9b,param
end if
end if
else
if type@param eq addr
lea rax,[param]
mov [rsp+(counter-1)*8],rax
else if param eqtype [0] | param eqtype byte [0]
if size@param = 8
mov rax,param
mov [rsp+(counter-1)*8],rax
else if size@param = 4
mov eax,param
mov [rsp+(counter-1)*8],eax
else if size@param = 2
mov ax,param
mov [rsp+(counter-1)*8],ax
else
mov al,param
mov [rsp+(counter-1)*8],al
end if
else if size@param = 8
virtual
origin = $
mov rax,param
load opcode byte from origin+1
end virtual
if opcode = 0B8h
mov rax,param
mov [rsp+(counter-1)*8],rax
else
mov qword [rsp+(counter-1)*8],param
end if
else if param in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
movq [rsp+(counter-1)*8],param
else
mov [rsp+(counter-1)*8],param
end if
end if \}
common
argscount = counter
call proc
if qwords & ~defined current@frame
add rsp, qwords*8
end if }
purge frame
purge endf
macro frame0 odd* {
local qwords, current
if qwords + (1-(qwords and 1)) * odd + (qwords and 1) * (1-odd)
sub rsp, (qwords + (1-(qwords and 1)) * odd + (qwords and 1) * (1-odd)) * 8
end if
current = 0
current@frame equ current
qwords@frame equ qwords
odd@frame equ odd
}
macro frame {frame0 FALSE}
macro frame_odd {frame0 TRUE}
macro endfi {
local qwords
qwords = qwords@frame + (1-(qwords@frame and 1)) * odd@frame + (qwords@frame and 1) * (1-odd@frame)
if qwords
add rsp, qwords*8
end if
}
macro endf {
qwords@frame = current@frame
endfi
restore qwords@frame,current@frame,odd@frame
}
;==== For functions ====
macro save_func0 do_odd*, noalign*, do_save*, [arg] {
common
local argscount
argscount = 0
forward
if do_save
argscount = argscount + 1
if argscount <= 4
mov [rsp + argscount*8], arg
else
push arg
end if
end if
common
local odd
odd = FALSE
if argscount <= 4
if do_odd
odd = TRUE
end if
else if noalign
odd = argscount and 1
else if argscount and 1 xor do_odd
odd = TRUE
end if
frame0 odd
macro fin@save \{
common
local revcount
revcount = argscount
endfi
reverse
if do_save
if revcount > 4
pop arg
else
mov arg, [rsp + revcount*8]
end if
revcount = revcount - 1
end if
common
\}
}
macro save [arg] {common save_func0 TRUE, FALSE, TRUE, arg}
macro save_nothing [arg] {common save_func0 TRUE, FALSE, FALSE}
macro save_noalign [arg] {common save_func0 NULL, TRUE, TRUE, arg}
;=== For inline use ===
macro save_inline0 do_odd*, noalign*, [arg] {
common
local argscount
argscount = 0
forward
argscount = argscount + 1
push arg
common
frame0 noalign*(argscount and 1) + (1-noalign)*(argscount and 1 xor do_odd)
macro fin@save \{
common
local revcount
revcount = argscount
endfi
reverse
pop arg
common
\}
}
macro save_inline [arg] {common save_inline0 FALSE, FALSE, arg}
macro save_inline_odd [arg] {common save_inline0 TRUE, FALSE, arg}
macro save_inline_noalign [arg] {common save_inline0 NULL, TRUE, arg}
;save_nothing_inline would be just to use frame
macro resti {fin@save}
macro rest {
qwords@frame = current@frame
fin@save
restore qwords@frame,current@frame,odd@frame
purge fin@save
}