Rev 593 | Rev 2288 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 593 | Rev 750 | ||
---|---|---|---|
1 | $Revision: 593 $ |
1 | $Revision: 750 $ |
2 | 2 | ||
3 | 3 | ||
4 | ; Macroinstructions for defining and calling procedures |
4 | ; Macroinstructions for defining and calling procedures |
5 | 5 | ||
6 | macro stdcall proc,[arg] ; directly call STDCALL procedure |
6 | macro stdcall proc,[arg] ; directly call STDCALL procedure |
7 | { common |
7 | { common |
8 | if ~ arg eq |
8 | if ~ arg eq |
9 | reverse |
9 | reverse |
10 | pushd arg |
10 | pushd arg |
11 | common |
11 | common |
12 | end if |
12 | end if |
13 | call proc } |
13 | call proc } |
14 | 14 | ||
15 | macro invoke proc,[arg] ; indirectly call STDCALL procedure |
15 | macro invoke proc,[arg] ; indirectly call STDCALL procedure |
16 | { common |
16 | { common |
17 | if ~ arg eq |
17 | if ~ arg eq |
18 | reverse |
18 | reverse |
19 | pushd arg |
19 | pushd arg |
20 | common |
20 | common |
21 | end if |
21 | end if |
22 | call [proc] } |
22 | call [proc] } |
23 | 23 | ||
24 | macro ccall proc,[arg] ; directly call CDECL procedure |
24 | macro ccall proc,[arg] ; directly call CDECL procedure |
25 | { common |
25 | { common |
26 | size@ccall = 0 |
26 | size@ccall = 0 |
27 | if ~ arg eq |
27 | if ~ arg eq |
28 | reverse |
28 | reverse |
29 | pushd arg |
29 | pushd arg |
30 | size@ccall = size@ccall+4 |
30 | size@ccall = size@ccall+4 |
31 | common |
31 | common |
32 | end if |
32 | end if |
33 | call proc |
33 | call proc |
34 | if size@ccall |
34 | if size@ccall |
35 | add esp,size@ccall |
35 | add esp,size@ccall |
36 | end if } |
36 | end if } |
37 | 37 | ||
38 | macro cinvoke proc,[arg] ; indirectly call CDECL procedure |
38 | macro cinvoke proc,[arg] ; indirectly call CDECL procedure |
39 | { common |
39 | { common |
40 | size@ccall = 0 |
40 | size@ccall = 0 |
41 | if ~ arg eq |
41 | if ~ arg eq |
42 | reverse |
42 | reverse |
43 | pushd arg |
43 | pushd arg |
44 | size@ccall = size@ccall+4 |
44 | size@ccall = size@ccall+4 |
45 | common |
45 | common |
46 | end if |
46 | end if |
47 | call [proc] |
47 | call [proc] |
48 | if size@ccall |
48 | if size@ccall |
49 | add esp,size@ccall |
49 | add esp,size@ccall |
50 | end if } |
50 | end if } |
51 | 51 | ||
52 | macro proc [args] ; define procedure |
52 | macro proc [args] ; define procedure |
53 | { common |
53 | { common |
54 | match name params, args> |
54 | match name params, args> |
55 | \{ define@proc name, |
55 | \{ define@proc name, |
56 | 56 | ||
57 | prologue@proc equ prologuedef |
57 | prologue@proc equ prologuedef |
58 | 58 | ||
59 | macro prologuedef procname,flag,parmbytes,localbytes,reglist |
59 | macro prologuedef procname,flag,parmbytes,localbytes,reglist |
60 | { if parmbytes | localbytes |
60 | { if parmbytes | localbytes |
61 | push ebp |
61 | push ebp |
62 | mov ebp,esp |
62 | mov ebp,esp |
63 | if localbytes |
63 | if localbytes |
64 | sub esp,localbytes |
64 | sub esp,localbytes |
65 | end if |
65 | end if |
66 | end if |
66 | end if |
67 | irps reg, reglist \{ push reg \} } |
67 | irps reg, reglist \{ push reg \} } |
68 | 68 | ||
69 | epilogue@proc equ epiloguedef |
69 | epilogue@proc equ epiloguedef |
70 | 70 | ||
71 | macro epiloguedef procname,flag,parmbytes,localbytes,reglist |
71 | macro epiloguedef procname,flag,parmbytes,localbytes,reglist |
72 | { irps reg, reglist \{ reverse pop reg \} |
72 | { irps reg, reglist \{ reverse pop reg \} |
73 | if parmbytes | localbytes |
73 | if parmbytes | localbytes |
74 | leave |
74 | leave |
75 | end if |
75 | end if |
76 | if (flag and 10000b) | (parmbytes=0) |
76 | if (flag and 10000b) | (parmbytes=0) |
77 | retn |
77 | retn |
78 | else |
78 | else |
79 | retn parmbytes |
79 | retn parmbytes |
80 | end if } |
80 | end if } |
81 | 81 | ||
82 | macro define@proc name,statement |
82 | macro define@proc name,statement |
83 | { local params,flag,regs,parmbytes,localbytes,current |
83 | { local params,flag,regs,parmbytes,localbytes,current |
84 | if used name |
84 | if used name |
85 | name: |
85 | name: |
86 | match =stdcall args, statement \{ params equ args |
86 | match =stdcall args, statement \{ params equ args |
87 | flag = 11b \} |
87 | flag = 11b \} |
88 | match =stdcall, statement \{ params equ |
88 | match =stdcall, statement \{ params equ |
89 | flag = 11b \} |
89 | flag = 11b \} |
90 | match =c args, statement \{ params equ args |
90 | match =c args, statement \{ params equ args |
91 | flag = 10001b \} |
91 | flag = 10001b \} |
92 | match =c, statement \{ params equ |
92 | match =c, statement \{ params equ |
93 | flag = 10001b \} |
93 | flag = 10001b \} |
94 | match =params, params \{ params equ statement |
94 | match =params, params \{ params equ statement |
95 | flag = 0 \} |
95 | flag = 0 \} |
96 | virtual at ebp+8 |
96 | virtual at ebp+8 |
97 | match =uses reglist=,args, params \{ regs equ reglist |
97 | match =uses reglist=,args, params \{ regs equ reglist |
98 | params equ args \} |
98 | params equ args \} |
99 | match =regs =uses reglist, regs params \{ regs equ reglist |
99 | match =regs =uses reglist, regs params \{ regs equ reglist |
100 | params equ \} |
100 | params equ \} |
101 | match =regs, regs \{ regs equ \} |
101 | match =regs, regs \{ regs equ \} |
102 | match =,args, params \{ defargs@proc args \} |
102 | match =,args, params \{ defargs@proc args \} |
103 | match =args@proc args, args@proc params \{ defargs@proc args \} |
103 | match =args@proc args, args@proc params \{ defargs@proc args \} |
104 | parmbytes = $ - (ebp+8) |
104 | parmbytes = $ - (ebp+8) |
105 | end virtual |
105 | end virtual |
106 | name # % = parmbytes/4 |
106 | name # % = parmbytes/4 |
107 | all@vars equ |
107 | all@vars equ |
108 | current = 0 |
108 | current = 0 |
109 | match prologue:reglist, prologue@proc: |
109 | match prologue:reglist, prologue@proc: |
110 | macro locals |
110 | macro locals |
111 | \{ virtual at ebp-localbytes+current |
111 | \{ virtual at ebp-localbytes+current |
112 | macro label . \\{ deflocal@proc .,:, \\} |
112 | macro label . \\{ deflocal@proc .,:, \\} |
113 | struc db [val] \\{ \common deflocal@proc .,db,val \\} |
113 | struc db [val] \\{ \common deflocal@proc .,db,val \\} |
114 | struc dw [val] \\{ \common deflocal@proc .,dw,val \\} |
114 | struc dw [val] \\{ \common deflocal@proc .,dw,val \\} |
115 | struc dp [val] \\{ \common deflocal@proc .,dp,val \\} |
115 | struc dp [val] \\{ \common deflocal@proc .,dp,val \\} |
116 | struc dd [val] \\{ \common deflocal@proc .,dd,val \\} |
116 | struc dd [val] \\{ \common deflocal@proc .,dd,val \\} |
117 | struc dt [val] \\{ \common deflocal@proc .,dt,val \\} |
117 | struc dt [val] \\{ \common deflocal@proc .,dt,val \\} |
118 | struc dq [val] \\{ \common deflocal@proc .,dq,val \\} |
118 | struc dq [val] \\{ \common deflocal@proc .,dq,val \\} |
119 | struc rb cnt \\{ deflocal@proc .,rb cnt, \\} |
119 | struc rb cnt \\{ deflocal@proc .,rb cnt, \\} |
120 | struc rw cnt \\{ deflocal@proc .,rw cnt, \\} |
120 | struc rw cnt \\{ deflocal@proc .,rw cnt, \\} |
121 | struc rp cnt \\{ deflocal@proc .,rp cnt, \\} |
121 | struc rp cnt \\{ deflocal@proc .,rp cnt, \\} |
122 | struc rd cnt \\{ deflocal@proc .,rd cnt, \\} |
122 | struc rd cnt \\{ deflocal@proc .,rd cnt, \\} |
123 | struc rt cnt \\{ deflocal@proc .,rt cnt, \\} |
123 | struc rt cnt \\{ deflocal@proc .,rt cnt, \\} |
124 | struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} |
124 | struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} |
125 | macro endl |
125 | macro endl |
126 | \{ purge label |
126 | \{ purge label |
127 | restruc db,dw,dp,dd,dt,dq |
127 | restruc db,dw,dp,dd,dt,dq |
128 | restruc rb,rw,rp,rd,rt,rq |
128 | restruc rb,rw,rp,rd,rt,rq |
129 | restruc byte,word,dword,pword,tword,qword |
129 | restruc byte,word,dword,pword,tword,qword |
130 | current = $-(ebp-localbytes) |
130 | current = $-(ebp-localbytes) |
131 | end virtual \} |
131 | end virtual \} |
132 | macro ret operand |
132 | macro ret operand |
133 | \{ match any, operand \\{ retn operand \\} |
133 | \{ match any, operand \\{ retn operand \\} |
134 | match , operand \\{ match epilogue:reglist, epilogue@proc: |
134 | match , operand \\{ match epilogue:reglist, epilogue@proc: |
135 | \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} |
135 | \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} |
136 | macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 |
136 | macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 |
137 | end if \} } |
137 | end if \} } |
138 | 138 | ||
139 | macro defargs@proc [arg] |
139 | macro defargs@proc [arg] |
140 | { common |
140 | { common |
141 | if ~ arg eq |
141 | if ~ arg eq |
142 | forward |
142 | forward |
143 | local ..arg,current@arg |
143 | local ..arg,current@arg |
144 | match argname:type, arg |
144 | match argname:type, arg |
145 | \{ current@arg equ argname |
145 | \{ current@arg equ argname |
146 | label ..arg type |
146 | label ..arg type |
147 | argname equ ..arg |
147 | argname equ ..arg |
148 | if dqword eq type |
148 | if dqword eq type |
149 | dd ?,?,?,? |
149 | dd ?,?,?,? |
150 | else if tbyte eq type |
150 | else if tbyte eq type |
151 | dd ?,?,? |
151 | dd ?,?,? |
152 | else if qword eq type | pword eq type |
152 | else if qword eq type | pword eq type |
153 | dd ?,? |
153 | dd ?,? |
154 | else |
154 | else |
155 | dd ? |
155 | dd ? |
156 | end if \} |
156 | end if \} |
157 | match =current@arg,current@arg |
157 | match =current@arg,current@arg |
158 | \{ current@arg equ arg |
158 | \{ current@arg equ arg |
159 | arg equ ..arg |
159 | arg equ ..arg |
160 | ..arg dd ? \} |
160 | ..arg dd ? \} |
161 | common |
161 | common |
162 | args@proc equ current@arg |
162 | args@proc equ current@arg |
163 | forward |
163 | forward |
164 | restore current@arg |
164 | restore current@arg |
165 | common |
165 | common |
166 | end if } |
166 | end if } |
167 | 167 | ||
168 | macro deflocal@proc name,def,[val] |
168 | macro deflocal@proc name,def,[val] |
169 | { common |
169 | { common |
170 | match vars, all@vars \{ all@vars equ all@vars, \} |
170 | match vars, all@vars \{ all@vars equ all@vars, \} |
171 | all@vars equ all@vars name |
171 | all@vars equ all@vars name |
172 | forward |
172 | forward |
173 | local ..var,..tmp |
173 | local ..var,..tmp |
174 | ..var def val |
174 | ..var def val |
175 | match =?, val \{ ..tmp equ \} |
175 | match =?, val \{ ..tmp equ \} |
176 | match any =dup (=?), val \{ ..tmp equ \} |
176 | match any =dup (=?), val \{ ..tmp equ \} |
177 | match tmp : value, ..tmp : val |
177 | match tmp : value, ..tmp : val |
178 | \{ tmp: end virtual |
178 | \{ tmp: end virtual |
179 | initlocal@proc ..var,def value |
179 | initlocal@proc ..var,def value |
180 | virtual at tmp\} |
180 | virtual at tmp\} |
181 | common |
181 | common |
182 | match first rest, ..var, \{ name equ first \} } |
182 | match first rest, ..var, \{ name equ first \} } |
183 | 183 | ||
184 | macro initlocal@proc name,def |
184 | macro initlocal@proc name,def |
185 | { virtual at name |
185 | { virtual at name |
186 | def |
186 | def |
187 | size@initlocal = $ - name |
187 | size@initlocal = $ - name |
188 | end virtual |
188 | end virtual |
189 | position@initlocal = 0 |
189 | position@initlocal = 0 |
190 | while size@initlocal > position@initlocal |
190 | while size@initlocal > position@initlocal |
191 | virtual at name |
191 | virtual at name |
192 | def |
192 | def |
193 | if size@initlocal - position@initlocal < 2 |
193 | if size@initlocal - position@initlocal < 2 |
194 | current@initlocal = 1 |
194 | current@initlocal = 1 |
195 | load byte@initlocal byte from name+position@initlocal |
195 | load byte@initlocal byte from name+position@initlocal |
196 | else if size@initlocal - position@initlocal < 4 |
196 | else if size@initlocal - position@initlocal < 4 |
197 | current@initlocal = 2 |
197 | current@initlocal = 2 |
198 | load word@initlocal word from name+position@initlocal |
198 | load word@initlocal word from name+position@initlocal |
199 | else |
199 | else |
200 | current@initlocal = 4 |
200 | current@initlocal = 4 |
201 | load dword@initlocal dword from name+position@initlocal |
201 | load dword@initlocal dword from name+position@initlocal |
202 | end if |
202 | end if |
203 | end virtual |
203 | end virtual |
204 | if current@initlocal = 1 |
204 | if current@initlocal = 1 |
205 | mov byte [name+position@initlocal],byte@initlocal |
205 | mov byte [name+position@initlocal],byte@initlocal |
206 | else if current@initlocal = 2 |
206 | else if current@initlocal = 2 |
207 | mov word [name+position@initlocal],word@initlocal |
207 | mov word [name+position@initlocal],word@initlocal |
208 | else |
208 | else |
209 | mov dword [name+position@initlocal],dword@initlocal |
209 | mov dword [name+position@initlocal],dword@initlocal |
210 | end if |
210 | end if |
211 | position@initlocal = position@initlocal + current@initlocal |
211 | position@initlocal = position@initlocal + current@initlocal |
212 | end while } |
212 | end while } |
213 | 213 | ||
214 | macro endp |
214 | macro endp |
215 | { purge ret,locals,endl |
215 | { purge ret,locals,endl |
216 | finish@proc |
216 | finish@proc |
217 | purge finish@proc |
217 | purge finish@proc |
218 | restore regs@proc |
218 | restore regs@proc |
219 | match all,args@proc \{ restore all \} |
219 | match all,args@proc \{ restore all \} |
220 | restore args@proc |
220 | restore args@proc |
221 | match all,all@vars \{ restore all \} } |
221 | match all,all@vars \{ restore all \} } |
222 | 222 | ||
223 | macro local [var] |
223 | macro local [var] |
224 | { common |
224 | { common |
225 | locals |
225 | locals |
226 | forward done@local equ |
226 | forward done@local equ |
227 | match varname[count]:vartype, var |
227 | match varname[count]:vartype, var |
228 | \{ match =BYTE, vartype \\{ varname rb count |
228 | \{ match =BYTE, vartype \\{ varname rb count |
229 | restore done@local \\} |
229 | restore done@local \\} |
230 | match =WORD, vartype \\{ varname rw count |
230 | match =WORD, vartype \\{ varname rw count |
231 | restore done@local \\} |
231 | restore done@local \\} |
232 | match =DWORD, vartype \\{ varname rd count |
232 | match =DWORD, vartype \\{ varname rd count |
233 | restore done@local \\} |
233 | restore done@local \\} |
234 | match =PWORD, vartype \\{ varname rp count |
234 | match =PWORD, vartype \\{ varname rp count |
235 | restore done@local \\} |
235 | restore done@local \\} |
236 | match =QWORD, vartype \\{ varname rq count |
236 | match =QWORD, vartype \\{ varname rq count |
237 | restore done@local \\} |
237 | restore done@local \\} |
238 | match =TBYTE, vartype \\{ varname rt count |
238 | match =TBYTE, vartype \\{ varname rt count |
239 | restore done@local \\} |
239 | restore done@local \\} |
240 | match =DQWORD, vartype \\{ label varname dqword |
240 | match =DQWORD, vartype \\{ label varname dqword |
241 | rq count+count |
241 | rq count+count |
242 | restore done@local \\} |
242 | restore done@local \\} |
243 | match , done@local \\{ virtual |
243 | match , done@local \\{ virtual |
244 | varname vartype |
244 | varname vartype |
245 | end virtual |
245 | end virtual |
246 | rb count*sizeof.\#vartype |
246 | rb count*sizeof.\#vartype |
247 | restore done@local \\} \} |
247 | restore done@local \\} \} |
248 | match :varname:vartype, done@local:var |
248 | match :varname:vartype, done@local:var |
249 | \{ match =BYTE, vartype \\{ varname db ? |
249 | \{ match =BYTE, vartype \\{ varname db ? |
250 | restore done@local \\} |
250 | restore done@local \\} |
251 | match =WORD, vartype \\{ varname dw ? |
251 | match =WORD, vartype \\{ varname dw ? |
252 | restore done@local \\} |
252 | restore done@local \\} |
253 | match =DWORD, vartype \\{ varname dd ? |
253 | match =DWORD, vartype \\{ varname dd ? |
254 | restore done@local \\} |
254 | restore done@local \\} |
255 | match =PWORD, vartype \\{ varname dp ? |
255 | match =PWORD, vartype \\{ varname dp ? |
256 | restore done@local \\} |
256 | restore done@local \\} |
257 | match =QWORD, vartype \\{ varname dq ? |
257 | match =QWORD, vartype \\{ varname dq ? |
258 | restore done@local \\} |
258 | restore done@local \\} |
259 | match =TBYTE, vartype \\{ varname dt ? |
259 | match =TBYTE, vartype \\{ varname dt ? |
260 | restore done@local \\} |
260 | restore done@local \\} |
261 | match =DQWORD, vartype \\{ label varname dqword |
261 | match =DQWORD, vartype \\{ label varname dqword |
262 | dq ?,? |
262 | dq ?,? |
263 | restore done@local \\} |
263 | restore done@local \\} |
264 | match , done@local \\{ varname vartype |
264 | match , done@local \\{ varname vartype |
265 | restore done@local \\} \} |
265 | restore done@local \\} \} |
266 | match ,done@local |
266 | match ,done@local |
267 | \{ var |
267 | \{ var |
268 | restore done@local \} |
268 | restore done@local \} |
269 | common |
269 | common |
270 | endl }>> |
270 | endl }>> |