coreBugZJ

此 blog 已弃。

nasm x86 32位汇编实现 int64 带符号 加 减 乘 除 比较大小

  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 

posted on 2013-04-29 20:46 coreBugZJ 阅读(2884) 评论(0)  编辑 收藏 引用 所属分类: AssembleCPUGPU


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理