1
2
3 // 毕业论文做 Pascal 编译器,需要生成的32位 nasm 汇编代码支持 64位带符号整数
4
5 // 几个标号
6 String line = genLabel( ip ) + ": ";
7 String head = " ";
8 String heaA = " .A ";
9 String heaB = " .B ";
10 String heaC = " .C ";
11 String heaD = " .D ";
12 String heaE = " .E ";
13
14
15
16 // add 次栈顶+栈顶
17 text.add( line + "pop eax" );
18 text.add( head + "pop edx" );
19 text.add( head + "add dword [esp], eax" );
20 text.add( head + "adc dword [esp+4], edx" );
21
22
23 // sub 次栈顶-栈顶
24 text.add( line + "pop eax" );
25 text.add( head + "pop edx" );
26 text.add( head + "not eax" );
27 text.add( head + "not edx" );
28 text.add( head + "add eax, 1" );
29 text.add( head + "adc edx, 0" );
30 text.add( head + "add dword [esp], eax" );
31 text.add( head + "adc dword [esp+4], edx" );
32
33
34 // mul 次栈顶*栈顶
35 // 乘数 X
36 text.add( line + "mov ecx, dword [esp+12]" );
37 text.add( head + "mov ebx, dword [esp+8]" );
38 // 乘数 Y
39 text.add( head + "mov edi, dword [esp+4]" );
40 text.add( head + "mov esi, dword [esp]" );
41 // 结果符号暂存于 dword [esp-8],正 1,负 -1
42 text.add( head + "mov dword [esp-8], 1" );
43 // 乘数 Y
44 text.add( head + "cmp edi, 0" );
45 text.add( head + "jge" + heaA );
46 // 乘数 Y 取相反数
47 text.add( head + "not esi" );
48 text.add( head + "not edi" );
49 text.add( head + "add esi, 1" );
50 text.add( head + "adc edi, 0" );
51 text.add( head + "neg dword [esp-8]" );
52 // 乘数 X
53 text.add( heaA + "cmp ecx, 0" );
54 text.add( head + "jge" + heaB );
55 // 乘数 X 取相反数
56 text.add( head + "not ebx" );
57 text.add( head + "not ecx" );
58 text.add( head + "add ebx, 1" );
59 text.add( head + "adc ecx, 0" );
60 text.add( head + "neg dword [esp-8]" );
61 // 无符号64位乘法
62 text.add( heaB + "mov eax, ecx" );
63 text.add( head + "mul esi" );
64 text.add( head + "mov dword [esp-4], eax" );
65 text.add( head + "mov eax, ebx" );
66 text.add( head + "mul edi" );
67 text.add( head + "add dword [esp-4], eax" );
68 text.add( head + "mov eax, ebx" );
69 text.add( head + "mul esi" );
70 text.add( head + "add edx, dword [esp-4]" );
71 // 设置结果符号
72 text.add( head + "cmp dword [esp-8], 1" );
73 text.add( head + "jz " + heaD );
74 text.add( head + "not eax" );
75 text.add( head + "not edx" );
76 text.add( head + "add eax, 1" );
77 text.add( head + "adc edx, 0" );
78 text.add( heaD + "add esp, 8" );
79 text.add( head + "mov dword [esp], eax" );
80 text.add( head + "mov dword [esp+4], edx" );
81
82
83 // div 次栈顶/栈顶,取商
84 // 绝对值相除,得到商的绝对值,异号得负
85 // 结果符号暂存于 dword [esp-4],正 1,负 -1
86 text.add( line + "mov dword [esp-4], 1" );
87 // 除数 Y
88 text.add( head + "cmp dword [esp+4], 0" );
89 text.add( head + "jge" + heaA );
90 // 除数 Y 取相反数
91 text.add( head + "not dword [esp]" );
92 text.add( head + "not dword [esp+4]" );
93 text.add( head + "add dword [esp], 1" );
94 text.add( head + "adc dword [esp+4], 0" );
95 text.add( head + "neg dword [esp-4]" );
96 // 被除数 X
97 text.add( heaA + "cmp dword [esp+12], 0" );
98 text.add( head + "jge" + heaB );
99 // 被除数 X 取相反数
100 text.add( head + "not dword [esp+8]" );
101 text.add( head + "not dword [esp+12]" );
102 text.add( head + "add dword [esp+8], 1" );
103 text.add( head + "adc dword [esp+12], 0" );
104 text.add( head + "neg dword [esp-4]" );
105 // 循环次数
106 text.add( heaB + "mov ecx, 64" );
107 // 余数
108 text.add( head + "xor edx, edx" );
109 text.add( head + "xor eax, eax" );
110 // 商
111 text.add( head + "xor edi, edi" );
112 text.add( head + "xor esi, esi" );
113 // 循环
114 text.add( heaC + "shl dword [esp+8], 1" );
115 text.add( head + "rcl dword [esp+12], 1" );
116 text.add( head + "rcl eax, 1" );
117 text.add( head + "rcl edx, 1" );
118 text.add( head + "shl esi, 1" );
119 text.add( head + "rcl edi, 1" );
120 text.add( head + "mov ebx, eax" );
121 text.add( head + "sub ebx, dword [esp]" );
122 text.add( head + "mov ebx, edx" );
123 text.add( head + "sbb ebx, dword [esp+4]" );
124 text.add( head + "jl " + heaD );
125 text.add( head + "sub eax, dword [esp]" );
126 text.add( head + "sbb edx, dword [esp+4]" );
127 text.add( head + "add esi, 1" );
128 text.add( head + "adc edi, 0" );
129 text.add( heaD + "loop" + heaC );
130 text.add( head + "cmp dword [esp-4], 1" );
131 text.add( head + "jz " + heaE );
132 text.add( head + "not esi" );
133 text.add( head + "not edi" );
134 text.add( head + "add esi, 1" );
135 text.add( head + "adc edi, 0" );
136 text.add( heaE + "add esp, 8" );
137 text.add( head + "mov dword [esp], esi" );
138 text.add( head + "mov dword [esp+4], edi" );
139
140
141 // rem 次栈顶/栈顶,取余数
142 // 绝对值相除,得到余数的绝对值,符号与被除数相同
143 // 结果符号暂存于 dword [esp-4],正 1,负 -1
144 text.add( line + "mov dword [esp-4], 1" );
145 // 除数 Y
146 text.add( head + "cmp dword [esp+4], 0" );
147 text.add( head + "jge" + heaA );
148 // 除数 Y 取相反数
149 text.add( head + "not dword [esp]" );
150 text.add( head + "not dword [esp+4]" );
151 text.add( head + "add dword [esp], 1" );
152 text.add( head + "adc dword [esp+4], 0" );
153 // 被除数 X
154 text.add( heaA + "cmp dword [esp+12], 0" );
155 text.add( head + "jge" + heaB );
156 // 被除数 X 取相反数
157 text.add( head + "not dword [esp+8]" );
158 text.add( head + "not dword [esp+12]" );
159 text.add( head + "add dword [esp+8], 1" );
160 text.add( head + "adc dword [esp+12], 0" );
161 text.add( head + "neg dword [esp-4]" );
162 // 循环次数
163 text.add( heaB + "mov ecx, 64" );
164 // 余数
165 text.add( head + "xor edx, edx" );
166 text.add( head + "xor eax, eax" );
167 // 商
168 text.add( head + "xor edi, edi" );
169 text.add( head + "xor esi, esi" );
170 // 循环
171 text.add( heaC + "shl dword [esp+8], 1" );
172 text.add( head + "rcl dword [esp+12], 1" );
173 text.add( head + "rcl eax, 1" );
174 text.add( head + "rcl edx, 1" );
175 text.add( head + "shl esi, 1" );
176 text.add( head + "rcl edi, 1" );
177 text.add( head + "mov ebx, eax" );
178 text.add( head + "sub ebx, dword [esp]" );
179 text.add( head + "mov ebx, edx" );
180 text.add( head + "sbb ebx, dword [esp+4]" );
181 text.add( head + "jl " + heaD );
182 text.add( head + "sub eax, dword [esp]" );
183 text.add( head + "sbb edx, dword [esp+4]" );
184 text.add( head + "add esi, 1" );
185 text.add( head + "adc edi, 0" );
186 text.add( heaD + "loop" + heaC );
187 text.add( head + "cmp dword [esp-4], 1" );
188 text.add( head + "jz " + heaE );
189 text.add( head + "not eax" );
190 text.add( head + "not edx" );
191 text.add( head + "add eax, 1" );
192 text.add( head + "adc edx, 0" );
193 text.add( heaE + "add esp, 8" );
194 text.add( head + "mov dword [esp], eax" );
195 text.add( head + "mov dword [esp+4], edx" );
196
197
198 // cmp 比较 次栈顶 与 栈顶,> 1, == 0, < -1
199 text.add( line + "pop eax" );
200 text.add( head + "pop edx" );
201 text.add( head + "not eax" );
202 text.add( head + "not edx" );
203 text.add( head + "add eax, 1" );
204 text.add( head + "adc edx, 0" );
205 text.add( head + "add eax, dword [esp]" );
206 text.add( head + "adc edx, dword [esp+4]" );
207 text.add( head + "cmp edx, 0" );
208 text.add( head + "jle" + heaB );
209 text.add( head + "mov ecx, 1" );
210 text.add( head + "jmp" + heaD );
211 text.add( heaB + "cmp edx, 0" );
212 text.add( head + "jl " + heaC );
213 text.add( head + "cmp eax, 0" );
214 text.add( head + "jz " + heaE );
215 text.add( head + "mov ecx, 1" );
216 text.add( head + "jmp" + heaD );
217 text.add( heaE + "xor ecx, ecx" );
218 text.add( head + "jmp" + heaD );
219 text.add( heaC + "mov ecx, -1" );
220 text.add( heaD + "mov dword [esp], ecx" );
221
222
223
224 // 测试程序
225 /*
226 test int64
227 小心被优化而失去测试效果,尽管目前还优化不到这个程度。
228 */
229 const
230 A = 4123412341L; // > max unsigned int32
231 B = 1111111111L; // < max unsigned int32
232 C = -4123412341L; // -A
233 D = -1111111111L; // -B
234 E = 2L;
235 F = -2L;
236 G = 10000000000L;
237
238 U = 7;
239 V = -7;
240 X = 3;
241 Y = -3;
242 var
243 a, b : int64;
244 i : int32;
245 begin
246 i := U;
247 writeln( i div X );
248 writeln( i mod X );
249 writeln( i div Y );
250 writeln( i mod Y );
251 i := V;
252 writeln( i div X );
253 writeln( i mod X );
254 writeln( i div Y );
255 writeln( i mod Y );
256 writeln( 'V' );
257
258 a := A;
259 writeln( a + B );
260 writeln( a + C );
261 writeln( a + D );
262 writeln( a + E );
263 writeln( a + F );
264 writeln( a + G );
265 writeln( 'A');
266
267 writeln( a - B );
268 writeln( a - C );
269 writeln( a - D );
270 writeln( a - E );
271 writeln( a - F );
272 writeln( a - G );
273 writeln( 'B');
274
275 writeln( a * B );
276 writeln( a * C );
277 writeln( a * D );
278 writeln( a * E );
279 writeln( a * F );
280 writeln( a * G );
281 writeln( 'C');
282
283 writeln( a div B );
284 writeln( a div C );
285 writeln( a div D );
286 writeln( a div E );
287 writeln( a div F );
288 writeln( a div G );
289 writeln( 'D');
290
291 writeln( a mod B );
292 writeln( a mod C );
293 writeln( a mod D );
294 writeln( a mod E );
295 writeln( a mod F );
296 writeln( a mod G );
297 writeln( 'E');
298
299 a := G;
300 writeln( a - 1L );
301 writeln( 'F' );
302 end.
303
304
305 // 测试程序输出(有乘法溢出int64)
306 2
307 1
308 -2
309 1
310 -2
311 -1
312 2
313 -1
314 V
315 5234523452
316 0
317 3012301230
318 4123412343
319 4123412339
320 14123412341
321 A
322 3012301230
323 8246824682
324 5234523452
325 4123412339
326 4123412343
327 -5876587659
328 B
329 4581569267319620851
330 1444214739798451335
331 -4581569267319620851
332 8246824682
333 -8246824682
334 4340635262580896768
335 C
336 3
337 -1
338 -3
339 2061706170
340 -2061706170
341 0
342 D
343 790079008
344 0
345 790079008
346 1
347 1
348 4123412341
349 E
350 9999999999
351 F
352
353