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