1 /******************************************************************************
2 *
3 * Copyright (C) 2009, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * Author: Alexander Krivonogov ( gentee )
11 *
12 * Summary:
13 *
14 ******************************************************************************/
15 /*
16 CNone, // 0x0, 0 Error command
17 * TInt, // 0x1, 1 int type
18 * TUint, // 0x2, 2 uint type
19 * TByte, // 0x3, 3 byte type
20 * TUbyte, // 0x4, 4 ubyte type
21 * TShort, // 0x5, 5 short type
22 * TUshort, // 0x6, 6 ushort type
23 * TFloat, // 0x7, 7 float type
24 * TDouble, // 0x8, 8 double type
25 * TLong, // 0x9, 9 long type
26 * TUlong, // 0xA, 10 ulong type
27 * TReserved, // 0xB, 11 reserved type
28 * TBuf, // 0xC, 12 buf type
29 * TStr, // 0xD, 13 str type
30 * TArr, // 0xE, 14 arr type
31 * TCollection, // 0xF, 15 collection type
32 * TAny, // 0x10, 16 any type
33 * TFordata, // 0x11, 17 foreach type
34 * CNop, // 0x12, 18 The command does nothing
35 * CGoto, // 0x13, 19 The unconditional jump.
36 * CGotonocls, // 0x14, 20 The unconditional jump without clearing stack.
37 * CIfze, // 0x15, 21 The conditional jump
38 * CIfznocls, // 0x16, 22 The conditional jump without clearing stack
39 * CIfnze, // 0x17, 23 The conditional jump
40 * CIfnznocls, // 0x18, 24 The conditional jump without clearing stack.
41 ? CByload, // 0x19, 25 The next ubyte push into stack. GE only
42 ? CShload, // 0x1A, 26 The next ushort push into stack. GE only
43 * CDwload, // 0x1B, 27 The next uint push into stack.
44 * CCmdload, // 0x1C, 28 The next ID push into stack.
45 * CResload, // 0x1D, 29 The next ID (resource) push into stack.
46 * CQwload, // 0x1E, 30 The next ulong push into stack.
47 * CDwsload, // 0x1F, 31 The next uints ( cmd 1 ) ( cmd 2 ) push into the stack
48 * CVarload, // 0x20, 32 Load the value of parameter or variable with number ( cmd 1)
49 * CVarptrload, // 0x21, 33 Load the pointer to value of parameter or variable with number ( cmd 1)
50 * CDatasize, // 0x22, 34 Load the pointer to the next data and the size
51 * CLoglongtrue, // 0x23, 35 Return 1 if ulong in stack is not zero
52 * CLognot, // 0x24, 36 Logical not
53 * CLoglongnot, // 0x25, 37 Logical NOT for long ulong
54 * CDup, // 0x26, 38 Duplicate top value
55 * CDuplong, // 0x27, 39 Duplicate two top value
56 * CTop, // 0x28, 40 Return the pointer to top
57 * CPop, // 0x29, 41 Delete the top value
58 * CGetUB, // 0x2A, 42 * ( pubyte )
59 * CGetB, // 0x2B, 43 * ( pbyte )
60 * CGetUS, // 0x2C, 44 * ( pushort )
61 * CGetS, // 0x2D, 45 * ( pshort )
62 * CGetI, // 0x2E, 46 * ( puint && pint && float )
63 * CGetL, // 0x2F, 47 * ( pulong && plong && double )
64 * CSetUB, // 0x30, 48 * ( pubyte ) =
65 * CSetB, // 0x31, 49 * ( pbyte ) =
66 * CSetUS, // 0x32, 50 * ( pushort ) =
67 * CSetS, // 0x33, 51 * ( pshort ) =
68 * CSetI, // 0x34, 52 * ( puint && pint && float ) =
69 * CSetL, // 0x35, 53 * ( pulong && plong && double ) =
70 * CAddUIUI, // 0x36, 54 +
71 * CSubUIUI, // 0x37, 55 -
72 * CMulUIUI, // 0x38, 56 *
73 * CDivUIUI, // 0x39, 57 /
74 * CModUIUI, // 0x3A, 58 %
75 * CAndUIUI, // 0x3B, 59 &
76 * COrUIUI, // 0x3C, 60 |
77 * CXorUIUI, // 0x3D, 61 ^
78 * CLeftUIUI, // 0x3E, 62 <<
79 * CRightUIUI, // 0x3F, 63 >>
80 * CLessUIUI, // 0x40, 64 <
81 * CGreaterUIUI, // 0x41, 65 >
82 * CEqUIUI, // 0x42, 66 ==
83 * CNotUI, // 0x43, 67 ~
84 * CIncLeftUI, // 0x44, 68 ++i
85 * CIncRightUI, // 0x45, 69 i++
86 * CDecLeftUI, // 0x46, 70 --i
87 * CDecRightUI, // 0x47, 71 i--
88 * CAddUI, // 0x48, 72 +=
89 * CSubUI, // 0x49, 73 -=
90 * CMulUI, // 0x4A, 74 *=
91 * CDivUI, // 0x4B, 75 /=
92 * CModUI, // 0x4C, 76 %=
93 * CAndUI, // 0x4D, 77 &=
94 * COrUI, // 0x4E, 78 |=
95 * CXorUI, // 0x4F, 79 ^=
96 * CLeftUI, // 0x50, 80 <<=
97 * CRightUI, // 0x51, 81 >>=
98 CVarsInit, // 0x52, 82 Initialize variables in block cmd1
99 CGetText, // 0x53, 83 Get current output of text function
100 CSetText, // 0x54, 84 Print string to current output of text function
101 CPtrglobal, // 0x55, 85 Get to the global variable
102 * CSubcall, // 0x56, 86 Call a subfunc cmd 1 - goto
103 * CSubret, // 0x57, 87 The number of returned uint cmd 1
104 * CSubpar, // 0x58, 88 Parameters of subfunc. cmd 1 - Set block
105 * CSubreturn, // 0x59, 89 Return from a subfunc
106 CCmdcall, // 0x5A, 90 Call a funcion
107 CCallstd, // 0x5B, 91 Call a stdcall or cdecl funcion
108 CReturn, // 0x5C, 92 Return from the function.
109 * CAsm, // 0x5D, 93 Assembler
110 CDbgTrace, // 0x5E, 94 Debug line tracing
111 CDbgFunc, // 0x5F, 95 Debug func entering
112 * CMulII, // 0x60, 96 *
113 * CDivII, // 0x61, 97 /
114 * CModII, // 0x62, 98 %
115 * CLeftII, // 0x63, 99 <<
116 * CRightII, // 0x64, 100 >>
117 * CSignI, // 0x65, 101 change sign
118 * CLessII, // 0x66, 102 <
119 * CGreaterII, // 0x67, 103 >
120 * CMulI, // 0x68, 104 *=
121 * CDivI, // 0x69, 105 /=
122 * CModI, // 0x6A, 106 %=
123 * CLeftI, // 0x6B, 107 <<=
124 * CRightI, // 0x6C, 108 >>=
125 CMulB, // 0x6D, 109 *=
126 CDivB, // 0x6E, 110 /=
127 CModB, // 0x6F, 111 %=
128 CLeftB, // 0x70, 112 <<=
129 CRightB, // 0x71, 113 >>=
130 CMulS, // 0x72, 114 *=
131 CDivS, // 0x73, 115 /=
132 CModS, // 0x74, 116 %=
133 CLeftS, // 0x75, 117 <<=
134 CRightS, // 0x76, 118 >>=
135 Cd2f, // 0x77, 119 double 2 float
136 Cd2i, // 0x78, 120 double 2 int
137 Cd2l, // 0x79, 121 double 2 long
138 Cf2d, // 0x7A, 122 float 2 double
139 Cf2i, // 0x7B, 123 float 2 int
140 Cf2l, // 0x7C, 124 float 2 long
141 Ci2d, // 0x7D, 125 int 2 double
142 Ci2f, // 0x7E, 126 int 2 float
143 Ci2l, // 0x7F, 127 int 2 long
144 Cl2d, // 0x80, 128 long 2 double
145 Cl2f, // 0x81, 129 long 2 float
146 Cl2i, // 0x82, 130 long 2 int
147 Cui2d, // 0x83, 131 uint 2 double
148 Cui2f, // 0x84, 132 uint 2 float
149 Cui2l, // 0x85, 133 uint 2 long
150 CAddULUL, // 0x86, 134 +
151 CSubULUL, // 0x87, 135 -
152 CMulULUL, // 0x88, 136 *
153 CDivULUL, // 0x89, 137 /
154 CModULUL, // 0x8A, 138 %
155 CAndULUL, // 0x8B, 139 &
156 COrULUL, // 0x8C, 140 |
157 CXorULUL, // 0x8D, 141 ^
158 CLeftULUL, // 0x8E, 142 <<
159 CRightULUL, // 0x8F, 143 >>
160 CLessULUL, // 0x90, 144 <
161 CGreaterULUL, // 0x91, 145 >
162 CEqULUL, // 0x92, 146 ==
163 CNotUL, // 0x93, 147 ~
164 CIncLeftUL, // 0x94, 148 ++
165 CIncRightUL, // 0x95, 149 ++
166 CDecLeftUL, // 0x96, 150 --
167 CDecRightUL, // 0x97, 151 --
168 CAddUL, // 0x98, 152 +=
169 CSubUL, // 0x99, 153 -=
170 CMulUL, // 0x9A, 154 *=
171 CDivUL, // 0x9B, 155 /=
172 CModUL, // 0x9C, 156 %
173 CAndUL, // 0x9D, 157 &=
174 COrUL, // 0x9E, 158 |=
175 CXorUL, // 0x9F, 159 &=
176 CLeftUL, // 0xA0, 160 <<=
177 CRightUL, // 0xA1, 161 >>=
178 CMulLL, // 0xA2, 162 *
179 CDivLL, // 0xA3, 163 /
180 CModLL, // 0xA4, 164 %
181 CLeftLL, // 0xA5, 165 <<=
182 CRightLL, // 0xA6, 166 >>=
183 CSignL, // 0xA7, 167 sign
184 CLessLL, // 0xA8, 168 <
185 CGreaterLL, // 0xA9, 169 >
186 CMulL, // 0xAA, 170 *=
187 CDivL, // 0xAB, 171 /=
188 CModL, // 0xAC, 172 %=
189 CLeftL, // 0xAD, 173 <<=
190 CRightL, // 0xAE, 174 >>=
191 CAddFF, // 0xAF, 175 +
192 CSubFF, // 0xB0, 176 -
193 CMulFF, // 0xB1, 177 *
194 CDivFF, // 0xB2, 178 /
195 CSignF, // 0xB3, 179 sign
196 CLessFF, // 0xB4, 180 <
197 CGreaterFF, // 0xB5, 181 >
198 CEqFF, // 0xB6, 182 ==
199 CIncLeftF, // 0xB7, 183 ++
200 CIncRightF, // 0xB8, 184 ++
201 CDecLeftF, // 0xB9, 185 --
202 CDecRightF, // 0xBA, 186 --
203 CAddF, // 0xBB, 187 +=
204 CSubF, // 0xBC, 188 -=
205 CMulF, // 0xBD, 189 *=
206 CDivF, // 0xBE, 190 /=
207 CAddDD, // 0xBF, 191 +
208 CSubDD, // 0xC0, 192 -
209 CMulDD, // 0xC1, 193 *
210 CDivDD, // 0xC2, 194 /
211 CSignD, // 0xC3, 195 sign
212 CLessDD, // 0xC4, 196 <
213 CGreaterDD, // 0xC5, 197 >
214 CEqDD, // 0xC6, 198 ==
215 CIncLeftD, // 0xC7, 199 ++
216 CIncRightD, // 0xC8, 200 ++
217 CDecLeftD, // 0xC9, 201 --
218 CDecRightD, // 0xCA, 202 --
219 CAddD, // 0xCB, 203 +=
220 CSubD, // 0xCC, 204 -=
221 CMulD, // 0xCD, 205 *=
222 CDivD, // 0xCE, 206 /=
223 * CIncLeftUB, // 0xCF, 207 ++
224 * CIncRightUB, // 0xD0, 208 ++
225 * CDecLeftUB, // 0xD1, 209 --
226 * CDecRightUB, // 0xD2, 210 --
227 CAddUB, // 0xD3, 211 +=
228 CSubUB, // 0xD4, 212 -=
229 CMulUB, // 0xD5, 213 *=
230 CDivUB, // 0xD6, 214 /=
231 CModUB, // 0xD7, 215 %=
232 CAndUB, // 0xD8, 216 &=
233 COrUB, // 0xD9, 217 |=
234 CXorUB, // 0xDA, 218 ^=
235 CLeftUB, // 0xDB, 219 <<=
236 CRightUB, // 0xDC, 220 >>=
237 * CIncLeftUS, // 0xDD, 221 ++
238 * CIncRightUS, // 0xDE, 222 ++
239 * CDecLeftUS, // 0xDF, 223 --
240 * CDecRightUS, // 0xE0, 224 --
241 CAddUS, // 0xE1, 225 +=
242 CSubUS, // 0xE2, 226 -=
243 CMulUS, // 0xE3, 227 *=
244 CDivUS, // 0xE4, 228 /=
245 CModUS, // 0xE5, 229 %=
246 CAndUS, // 0xE6, 230 &=
247 COrUS, // 0xE7, 231 |=
248 CXorUS, // 0xE8, 232 ^=
249 CLeftUS, // 0xE9, 233 <<=
250 CRightUS, // 0xEA, 234 >>=
251 CCollectadd, // 0xEB, 235 Run-time loading collection
252 99
253 */
254
255 #ifdef _ASM
256
257 #include "ge.h"
258 #include "../vm/vm.h"
259 #include "../vm/vmload.h"
260 #include "../bytecode/bytecode.h"
261 #include "../genteeapi/gentee.h"
262
263
264 pbuf STDCALL buf_append2ch( pbuf pb, ubyte val1, ubyte val2 )
265 {
266 buf_expand( pb, 2 );
267 *( pb->data + pb->use++ ) = val1;
268 *( pb->data + pb->use++ ) = val2;
269 return pb;
270 }
271
272 pbuf STDCALL buf_append3ch( pbuf pb, ubyte val1, ubyte val2, ubyte val3 )
273 {
274 buf_expand( pb, 3 );
275 *( pb->data + pb->use++ ) = val1;
276 *( pb->data + pb->use++ ) = val2;
277 *( pb->data + pb->use++ ) = val3;
278 return pb;
279 }
280
281 pbuf STDCALL buf_append4ch( pbuf pb, ubyte val1, ubyte val2, ubyte val3, ubyte val4 )
282 {
283 buf_expand( pb, 4 );
284 *( pb->data + pb->use++ ) = val1;
285 *( pb->data + pb->use++ ) = val2;
286 *( pb->data + pb->use++ ) = val3;
287 *( pb->data + pb->use++ ) = val4;
288 return pb;
289 }
290
291 uint STDCALL startasm( pbuf b )
292 {
293 uint ret;
294 buf_appenduint( b, CAsm );
295 ret = b->use;
296 buf_appenduint( b, 0 );
297 //buf_appendch( b, 0xCC );
298 //Установка нового стэка
299 // buf_appendch( b, 0x56 );//push esi
300 // buf_appendch( b, 0x8B );//mov esi, esp
301 // buf_appendch( b, 0xF4 );
302 // buf_appendch( b, 0x8B );//mov esp, ebx
303 // buf_appendch( b, 0xE3 );
304 return ret;
305 }
306
307 typedef uint (* puarr)[];
308
309
310 uint STDCALL findnear( pbuf b, uint val, uint flgadd )
311 {
312 puarr array;
313 //uint array[];
314 //uint m = size;
315 int minlast = 0;
316 int maxlast = ( b->use >> 2 );
317 uint cur = 0;
318 array = (puarr)b->data;
319 //print( "Findnear %x %x %x\n", val, flgadd, maxlast );
320 if ( maxlast )
321 {
322 maxlast--;
323 do
324 {
325 cur = ( maxlast + minlast ) >> 1;
326 if ( (*array)[cur] == val )
327 {
328 //print( "Nearfind %x %x\n", val, cur );
329 return cur<<2;
330 }
331 if ( (*array)[cur] > val )
332 {
333 maxlast = cur - 1;
334 }
335 else
336 {
337 minlast = cur + 1;
338 cur++;
339 }
340 }
341 while ( maxlast >= minlast );
342 }
343 if ( flgadd )
344 {
345 buf_insert( b, cur << 2, (pchar)&val, 4 );
346 // print( "near add %x %x\n", cur, val );
347 return cur << 2;
348 }
349 return -1;
350 }
351
352
353 void STDCALL stopasm( pbuf b, uint off )
354 {
355 uint val = 0;
356 uint offcmd;
357
358 //Восстановление стэка и возврат
359 // buf_appendch( b, 0x8B );//mov ebx, esp
360 // buf_appendch( b, 0xDC );
361
362 // buf_appendch( b, 0x8B );//mov esp, esi
363 // buf_appendch( b, 0xE6 );
364
365 //buf_appendch( b, 0x5E); //pop esi
366
367
368 buf_appendch( b, 0xB8 );//mov eax, *
369 offcmd = b->use;
370 buf_appenduint( b, 0 );
371
372 buf_appendch( b, 0xC3 );//ret
373
374 //Выравнивание до dword
375 buf_append( b, ( pubyte )&val,
376 ( sizeof( uint ) - b->use & ( sizeof( uint ) - 1 ) ) & 3 );
377 *(puint)( b->data + off ) = (b->use - off - 4) >> 2;
378 //print( "size %x %x %x\n", b->use, off, (b->use - off - 4) >> 2 );
379 *(puint)( b->data + offcmd ) = (b->use) >> 2;
380 }
381
382 /*
383 puint start; +0
384 puint cmd; +4
385 puint top; +8
386 uint uiret; +c
387 pvmfunc func; +10
388 puint clmark;+14
389 uint nline; +18
390 mov [bx+4], [bx+0x14]
391 */
392
393
394 void STDCALL ge_toasm( uint id, pbuf bout )
395 {
396 puint ptr, end;
397 povmbcode bcode;
398 povmtype ptype;
399 pvmobj pvmo;
400 uint cmd, i, count = 0;
401 uint flgcop = 0;
402 uint off;
403 uint flgjmp = 0;
404 uint flgcls = 0;
405 uint flgtmp;
406 //pbuf bout;
407 buf bjmpsrc;
408 buf bjmpdst;
409 buf bjmpun;
410 buf bsubfuncs;
411 uint subparsize;
412 uint subretsize;
413 //pvarset pset;
414
415 pvartype pvar;
416 uint tmp;
417 uint tmp2;
418 //uint flgcls = 0;
419 uint curjmpsrc;
420 uint funcoff;
421
422 /*bout = mem_alloc( sizeof( buf ));
423 buf_init( bout );
424 buf_reserve( bout, 0x200 );
425 bout->step = 0x200; */
426
427 buf_init( &bjmpsrc );
428 buf_init( &bsubfuncs );
429 buf_init( &bjmpdst );
430 buf_init( &bjmpun );
431
432 if ( id < KERNEL_COUNT )
433 return;
434
435 pvmo = ( pvmobj )PCMD( id );
436 if ( pvmo->type == OVM_BYTECODE )
437 {
438 bcode = ( povmbcode )pvmo;
439 ptr = ( puint )bcode->vmf.func;
440 if ( !ptr )
441 return;
442 end = ( puint )( ( pubyte )ptr + bcode->bcsize );
443 //Первый проход определение переходов
444 while ( ptr < end )
445 {
446 cmd = *ptr++;
447 if ( cmd < CNop || cmd >= CNop + STACK_COUNT )
448 {
449 continue;
450 }
451
452 switch ( cmd )
453 {
454 case CDwsload:
455 case CAsm:
456 i = *ptr++;
457 ptr += i;
458 break;
459
460 case CDatasize:
461 i = *ptr++;
462 i = ( i >> 2 ) + ( i & 3 ? 1 : 0 );
463 ptr += i;
464 break;
465
466 case CSubcall:
467 off = (*(ptr) + 1)<<2;
468 findnear( &bsubfuncs, off, 1 );
469 findnear( &bjmpsrc, off, 1 );
470 goto shiftg;
471
472 case CGoto:
473 case CGotonocls:
474 case CIfze:
475 case CIfznocls:
476 case CIfnze:
477 case CIfnznocls:
478 off = (*(ptr) + 1)<<2;
479 findnear( &bjmpsrc, off , 1 );
480
481 default:
482 shiftg:
483 switch ( shifts[ cmd - CNop ] )
484 {
485 case SH1_3:
486 case SH2_3:
487 ptr++;
488 case SHN1_2:
489 case SH0_2:
490 case SH1_2:
491 ptr++;
492 break;
493 }
494 }
495
496 continue;
497 }
498
499 buf_expand( &bjmpdst, bjmpsrc.use );
500 mem_zero( bjmpdst.data, bjmpsrc.use );
501 curjmpsrc = 0;
502
503 //Второй проход конвертация
504 ptr = ( puint )bcode->vmf.func;
505 while ( ptr < end )
506 {
507 cmd = *ptr++;
508 //print ("cmd %x\n", cmd );
509 funcoff = (uint)ptr - ( uint )bcode->vmf.func;
510
511 if ( ( off = findnear( &bjmpsrc, funcoff, 0 )) != -1 )
512 {
513 if (!flgcop ) flgcop = startasm( bout );
514 *(puint)((uint)bjmpdst.data + off) = bout->use;
515 if ( findnear( &bsubfuncs, funcoff, 0 ) != -1 )
516 {
517 buf_appendch( bout, 0x58 );//pop eax
518 buf_append3ch( bout, 0x83, 0xC6, 0x08 );//add esi,8
519 buf_append3ch( bout, 0x89, 0x46, 0xFC );//mov dword ptr [esi-4],eax
520 buf_append3ch( bout, 0x8B, 0x41, 0x14 );//mov eax, dword ptr [ecx+14h]
521 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
522 buf_append3ch( bout, 0x89, 0x71, 0x14 );//mov dword ptr [ecx+0x14], esi
523
524 subparsize = 0;
525 subretsize = 0;
526 }
527 }
528
529 if ( cmd >= CNop + STACK_COUNT )
530 {
531 if ( flgcop )
532 {
533 stopasm( bout, flgcop);
534 flgcop = 0;
535 }
536 buf_appenduint( bout, cmd );
537 continue;
538 }
539
540 switch ( cmd )
541 {
542 case TInt:
543 case TUint:
544 case TByte:
545 case TUbyte:
546 case TShort:
547 case TUshort:
548 case TFloat:
549 case TDouble:
550 case TLong:
551 case TUlong:
552 case TReserved:
553 case TBuf:
554 case TStr:
555 case TArr:
556 case TCollection:
557 case TAny:
558 case TFordata:
559 if ( !flgcop ) flgcop = startasm( bout );
560 buf_append3ch( bout, 0x83, 0xC6, 0x04 );//add esi,4
561 buf_append2ch( bout, 0xC7, 0x06 );//mov dword ptr [esi], *
562 buf_appenduint( bout, cmd );
563 goto shift;
564
565 case CNop:
566 goto shift;
567
568 case CIfznocls:
569 flgjmp = 0x73;
570 goto cgotonocls;
571 case CIfnznocls:
572 flgjmp = 0x72;
573 goto cgotonocls;
574 case CIfze:
575 flgjmp = 0x73;
576 goto cgoto;
577 case CIfnze:
578 flgjmp = 0x72;
579 goto cgoto;
580 case CGoto:
581 cgoto:
582 flgcls = 1;
583 case CGotonocls:
584 cgotonocls:
585 if ( !flgcop ) flgcop = startasm( bout );
586 if ( flgjmp )
587 {
588 if ( flgcls )
589 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
590 else
591 buf_append2ch( bout, 0x8B, 0x06 );//mov eax,dword ptr [esi]
592 buf_append2ch( bout, 0xF7, 0xD8 );//neg eax
593 }
594 if ( flgcls )
595 {
596 buf_append3ch( bout, 0x8B, 0x71, 0x14 );//mov esi, dword ptr [ecx+14h]
597 //flgcls = 0;
598 }
599 tmp = (*(ptr) + 1)<<2;
600 off = *(puint)((uint)bjmpdst.data + findnear( &bjmpsrc, tmp, 0 ));
601 if ( off )
602 {
603 off = off - bout->use - 2;
604 if ( (int)off > -128 )
605 {
606 buf_append2ch( bout, (ubyte) (flgjmp ? flgjmp : 0xEB), (ubyte)off );//jmp *
607 }
608 else
609 {
610 if ( flgjmp )
611 {
612 off -= 4;
613 buf_append2ch( bout, 0x0F, (ubyte)(flgjmp + 0x10) );//jmp *
614 }
615 else
616 {
617 off -= 3;
618 buf_appendch( bout, 0xE9 );//jmp *
619 }
620 buf_appenduint( bout, off );
621 }
622 }
623 else
624 {
625 if ( flgjmp )
626 {
627 buf_append2ch( bout, 0x0F, (ubyte)(flgjmp + 0x10) );//jmp *
628 }
629 else buf_appendch( bout, 0xE9 );//jmp *
630 buf_appenduint( &bjmpun, bout->use );
631 buf_appenduint( &bjmpun, tmp );
632 buf_appenduint( bout, 0 );
633 }
634 if ( flgjmp && !flgcls )
635 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
636 flgjmp = 0;
637 flgcls = 0;
638 goto shift;
639
640 case CDwload:
641 //case CCmdload:
642 case CResload:
643 if ( !flgcop ) flgcop = startasm( bout );
644 buf_append3ch( bout, 0x83, 0xC6, 0x04 );//add esi,4
645 buf_append2ch( bout, 0xC7, 0x06 );//mov dword ptr [esi], *
646 buf_appenduint( bout, *ptr );
647 goto shift;
648
649 case CQwload:
650 if ( !flgcop ) flgcop = startasm( bout );
651 buf_append3ch( bout, 0x83, 0xC6, 0x08 );//add esi,8
652 buf_append3ch( bout, 0xC7, 0x46, 0xFC );//mov dword ptr [esi-4], *
653 buf_appenduint( bout, *ptr );
654 buf_append2ch( bout, 0xC7, 0x06 );//mov dword ptr [esi], *
655 buf_appenduint( bout, *(ptr+1) );
656 goto shift;
657
658 /* case CDwsload:
659 if ( !flgcop ) flgcop = startasm( bout );
660 tmp = *ptr++;
661 if (tmp < 11 )
662 {
663 buf_append3ch( bout, 0x83, 0xC6, ( ubyte )( tmp << 2 ) );//add esi, tmp * 4
664 for ( i = tmp ; i > 0; i-- )
665 {
666 if ( i > 1 )
667 buf_append3ch( bout, 0xC7, 0x46, (ubyte)( (1-i) * 4 ) );// mov dword ptr [esi-*], *
668 else
669 buf_append2ch( bout, 0xC7, 0x06 );//mov dword ptr [esi], *
670 buf_appenduint( bout, *ptr++ );
671 }
672 }
673 else
674 {
675 buf_appendch( bout, 0x57 );//push edi
676 buf_appendch( bout, 0x51 );//push ecx
677 buf_append3ch( bout, 0x8D, 0x7E, 0x04 );//lea edi,[esi+4]
678 buf_appendch( bout, 0xE8 );//call *
679 buf_appenduint( bout, tmp << 2 );
680 for ( i = tmp ; i > 0; i-- )
681 buf_appenduint( bout, *ptr++ );
682 buf_appendch( bout, 0x5E );//pop esi
683 buf_appendch( bout, 0xFC );//cld
684 buf_appendch( bout, 0xB9 );//mov ecx, *
685 buf_appenduint( bout, tmp );
686 buf_append2ch( bout, 0xF3, 0xA5 );//rep movs dword ptr [edi],dword ptr [esi]
687 buf_appendch( bout, 0xFD );//std
688 buf_append3ch( bout, 0x8D, 0x77, 0xFC );//lea esi,[edi-4]
689 buf_appendch( bout, 0x59 );//pop ecx
690 buf_appendch( bout, 0x5F );//pop edi
691 }
692 break;
693 */
694 case CVarptrload:
695 case CVarload:
696 if ( !flgcop )
697 {
698 flgcop = startasm( bout );
699 }
700 i = *ptr;
701 if ( i < bcode->vmf.parcount )
702 {
703 pvar = bcode->vmf.params + i;
704 off = pvar->off;
705 tmp = 0;
706 }
707 else
708 {
709 pvar = bcode->vars + ( i - bcode->vmf.parcount );
710 off = pvar->off;
711 tmp = 2;
712 }
713 off <<= 2;
714 ptype = ( povmtype )PCMD( pvar->type );
715 if ( cmd == CVarload && ptype->vmo.flag & GHTY_STACK )
716 {
717 buf_appendch( bout, 0x8B ); //mov eax,dword ptr [ebp/edi+*]
718 if ( ptype->stsize > 1 )
719 {
720 if ( off > 127 )
721 {
722 buf_appendch( bout, (ubyte)(0x85 + tmp) );
723 buf_appenduint( bout, off );
724 }
725 else
726 {
727 buf_append2ch( bout, (ubyte)(0x45 + tmp), (ubyte)off );
728 }
729 buf_append3ch( bout, 0x83, 0xC6, 0x04 );//add esi,4
730 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
731 off += 4;
732 buf_appendch( bout, 0x8B );
733 }
734 }
735 else
736 {
737 if ( pvar->flag & VAR_PARAM &&
738 !( ptype->vmo.flag & GHTY_STACK ))
739 buf_appendch( bout, 0x8B );
740 else
741 buf_appendch( bout, 0x8D );//45 lea eax,[ebp+*]
742 }
743 if ( off > 127 )
744 {
745 buf_appendch( bout, (ubyte)(0x85 + tmp) );
746 buf_appenduint( bout, off );
747 }
748 else
749 {
750 buf_append2ch( bout, (ubyte)(0x45 + tmp), (ubyte)off );
751 }
752 buf_append3ch( bout, 0x83, 0xC6, 0x04 );//add esi,4
753 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
754 goto shift;
755
756 case CDatasize:
757 if ( !flgcop ) flgcop = startasm( bout );
758 tmp = *ptr++;
759 i = ( tmp >> 2 ) + ( tmp & 3 ? 1 : 0 );
760 buf_appendch( bout, 0xE8 );//call *
761 buf_appenduint( bout, tmp );
762 buf_append( bout, (pubyte)ptr, tmp );
763 ptr += i;
764 buf_appendch( bout, 0x58 );//pop eax
765 buf_append3ch( bout, 0x83, 0xC6, 0x08 );//add esi,8
766 buf_append3ch( bout, 0x89, 0x46, 0xFC );//mov dword ptr [esi-4],eax
767 buf_append2ch( bout, 0xC7, 0x06 );//mov dword ptr [esi], *
768 buf_appenduint( bout, tmp );
769 break;
770
771 case CLoglongnot:
772 tmp = 1;
773 goto loglong;
774 case CLoglongtrue: //*pop2 = ( val1 || val2 ? 1 : 0 ); break;
775 tmp = 0;
776 loglong:
777 if ( !flgcop ) flgcop = startasm( bout );
778 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
779 buf_append2ch( bout, 0x33, 0xD2);//xor edx,edx
780 buf_append2ch( bout, 0x3B, 0xC2);//cmp eax,edx
781 //buf_append2ch( bout, 0x75, 0x04);//jne 4
782 buf_append2ch( bout, 0x75, (ubyte)(0x04 + tmp) );//jne 4/5
783 buf_append2ch( bout, 0x39, 0x16 );//cmp dword ptr [esi],edx
784 buf_append2ch( bout, (ubyte)(0x74 + tmp), 0x01);//je/jne 1
785 //buf_append2ch( bout, 0x75, 0x01);//jne 1
786 buf_appendch( bout, 0x42 );//inc edx
787 buf_append2ch( bout, 0x89, 0x16 );//mov dword ptr [esi],edx
788 goto shift;
789
790 case CLognot:
791 if ( !flgcop ) flgcop = startasm( bout );
792 buf_append2ch( bout, 0x33, 0xD2);//xor edx,edx
793 buf_append2ch( bout, 0x39, 0x16 );//cmp dword ptr [esi],edx
794 buf_append2ch( bout, (ubyte)(0x75), 0x01);//jne 1
795 buf_appendch( bout, 0x42 );//inc edx
796 buf_append2ch( bout, 0x89, 0x16 );//mov dword ptr [esi],edx
797 goto shift;
798
799 //case CLoglongnot: *pop2 = ( val1 || val2 ? 0 : 1 ); break;
800 case CDup:
801 if ( !flgcop ) flgcop = startasm( bout );
802 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
803 buf_append3ch( bout, 0x83, 0xC6, 0x08 );//add esi,8
804 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
805 goto shift;
806
807 case CDuplong:
808 if ( !flgcop ) flgcop = startasm( bout );
809 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
810 buf_append2ch( bout, 0x8B, 0xD0 );//mov edx,eax
811 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
812 buf_append3ch( bout, 0x83, 0xC6, 0x10 );//add esi,16
813 buf_append3ch( bout, 0x89, 0x46, 0xFC );//mov dword ptr [esi-4],eax
814 buf_append2ch( bout, 0x89, 0x16 );//mov dword ptr [esi],edx
815 goto shift;
816
817 case CTop:
818 if ( !flgcop ) flgcop = startasm( bout );
819 buf_append3ch( bout, 0x89, 0x76, 0x04 );//mov dword ptr [esi+4],esi
820 buf_append3ch( bout, 0x83, 0xC6, 0x04 );//add esi,4
821 goto shift;
822
823 case CPop:
824 if ( !flgcop ) flgcop = startasm( bout );
825 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
826 goto shift;
827
828 case CGetUB:
829 tmp = 0xB6;//movzx eax,byte ptr [ebx]
830 goto getub;
831 case CGetB:
832 tmp = 0xBE;//movsx eax,byte ptr [ebx]
833 goto getub;
834 case CGetUS:
835 tmp = 0xB7;//movzx eax,word ptr [ebx]
836 goto getub;
837 case CGetS:
838 tmp = 0xBF;//movsx eax,word ptr [ebx]
839 getub:
840 if ( !flgcop ) flgcop = startasm( bout );
841 buf_append2ch( bout, 0x8B, 0x1E );//mov ebx,dword ptr [esi]
842 buf_append3ch( bout, 0x0F, (ubyte)(tmp), 0x03 );//movsx/movzx eax,byte/word ptr [ebx]
843 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
844 goto shift;
845
846 case CGetI:
847 if ( !flgcop ) flgcop = startasm( bout );
848 buf_append2ch( bout, 0x8B, 0x1E );//mov ebx,dword ptr [esi]
849 buf_append2ch( bout, 0x8B, 0x03 );//mov eax,word ptr [ebx]
850 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
851 goto shift;
852
853 case CGetL:
854 if ( !flgcop ) flgcop = startasm( bout );
855 buf_append2ch( bout, 0x8B, 0x1E );//mov ebx,dword ptr [esi]
856 buf_append2ch( bout, 0x8B, 0x03 );//mov eax,word ptr [ebx]
857 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
858 buf_append3ch( bout, 0x8B, 0x43, 0x04 );//mov eax,word ptr [ebx+4]
859 buf_append3ch( bout, 0x83, 0xC6, 0x04 );//add esi,4
860 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
861 goto shift;
862
863 case CSetUB:
864 case CSetB:
865 if ( !flgcop ) flgcop = startasm( bout );
866 buf_appendch( bout, 0xAD ); //lods dword ptr [esi]
867 buf_append2ch( bout, 0x8B, 0x1E );//mov ebx,dword ptr [esi]
868 buf_append2ch( bout, 0x88, 0x03 );//mov byte ptr [ebx],al
869 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
870 goto shift;
871
872 case CSetUS:
873 case CSetS:
874 if ( !flgcop ) flgcop = startasm( bout );
875 buf_appendch( bout, 0xAD ); //lods dword ptr [esi]
876 buf_append2ch( bout, 0x8B, 0x1E );//mov ebx,dword ptr [esi]
877 buf_append3ch( bout, 0x66, 0x89, 0x03 );//mov word ptr [ebx],ax
878 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
879 goto shift;
880
881 case CSetI:
882 if ( !flgcop ) flgcop = startasm( bout );
883 buf_appendch( bout, 0xAD ); //lods dword ptr [esi]
884 buf_append2ch( bout, 0x8B, 0x1E );//mov ebx,dword ptr [esi]
885 buf_append2ch( bout, 0x89, 0x03 );//mov dword ptr [ebx],eax
886 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
887 goto shift;
888
889 case CSetL:
890 if ( !flgcop ) flgcop = startasm( bout );
891 buf_appendch( bout, 0xAD ); //lods dword ptr [esi]
892 buf_append2ch( bout, 0x8B, 0x1E );//mov ebx, dword ptr [esi]
893 buf_append3ch( bout, 0x8B, 0x56, 0xFC );//mov edx, dword ptr [esi-4]
894 buf_append2ch( bout, 0x89, 0x1A );//mov dword ptr [edx], ebx
895 buf_append3ch( bout, 0x89, 0x42, 0x04 );//mov dword ptr [edx+4], eax
896 buf_append3ch( bout, 0x89, 0x5E, 0xFC );//mov dword ptr [esi-4], ebx
897 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi], eax
898 goto shift;
899
900 case CSubUIUI:
901 tmp = 0x29;//sub
902 goto binopuiui;
903 case CAndUIUI:
904 tmp = 0x21;//and
905 goto binopuiui;
906 case COrUIUI:
907 tmp = 0x09;//or
908 goto binopuiui;
909 case CXorUIUI:
910 tmp = 0x31;//xor
911 goto binopuiui;
912 case CAddUIUI:
913 tmp = 0x01;//add
914 binopuiui:
915 if ( !flgcop ) flgcop = startasm( bout );
916 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
917 buf_append2ch( bout, (ubyte)tmp, 0x06 );//*tmp dword ptr [esi],eax
918 goto shift;
919
920 case CMulUIUI:
921 case CMulII:
922 if ( !flgcop ) flgcop = startasm( bout );
923 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
924 buf_append3ch( bout, 0x0F, 0xAF, 0x06 );//imul eax,dword ptr [esi]
925 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
926 goto shift;
927
928 case CDivUIUI:
929 tmp = 0;
930 tmp2 = 0xF3;
931 goto divuiui;
932 case CModUIUI:
933 tmp = 0x10;
934 tmp2 = 0xF3;
935 goto divuiui;
936 case CDivII:
937 tmp = 0;
938 tmp2 = 0xFB;
939 goto divuiui;
940 case CModII:
941 tmp = 0x10;
942 tmp2 = 0xFB;
943 divuiui:
944 if ( !flgcop ) flgcop = startasm( bout );
945 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
946 buf_append2ch( bout, 0x8B, 0xD8 );//mov ebx,eax
947 buf_append2ch( bout, 0x8B, 0x06 );//mov eax,dword ptr [esi]
948 if ( tmp2 == 0xF3 )
949 buf_append2ch( bout, 0x33, 0xD2 );//xor edx,edx
950 else
951 buf_appendch( bout, 0x99 );//cdq
952 buf_append2ch( bout, 0xF7, (ubyte)tmp2 );//div eax,ebx
953 buf_append2ch( bout, 0x89, (ubyte)( 0x06 + tmp ) );//mov dword ptr [esi],eax/edx
954 goto shift;
955
956 case CLeftUIUI:
957 case CLeftII:
958 tmp = 0x26;//shl
959 goto rightuiui;
960 case CRightII:
961 tmp = 0x3e;//sar
962 goto rightuiui;
963 case CRightUIUI:
964 tmp = 0x2e;//shr
965 rightuiui:
966 if ( !flgcop ) flgcop = startasm( bout );
967 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
968 buf_appendch( bout, 0x51 );//push ecx
969 buf_append2ch( bout, 0x8A, 0xC8 );//mov cl,al
970 buf_append2ch( bout, 0xD3, (ubyte)tmp );//shr/shl/sar dword ptr [esi],cl
971 buf_appendch( bout, 0x59 );//pop ecx
972 goto shift;
973
974 case CSignI:
975 if ( !flgcop ) flgcop = startasm( bout );
976 buf_append2ch( bout, 0xF7, 0x1E );//neg dword ptr [esi]
977 goto shift;
978
979 case CLessII://jge
980 tmp = 0x7D;
981 goto equiui;
982 case CGreaterII:
983 tmp = 0x7E;//jle
984 goto equiui;
985 case CLessUIUI:
986 tmp = 0x73;//jnb
987 goto equiui;
988 case CGreaterUIUI:
989 tmp = 0x76;//jna
990 goto equiui;
991 case CEqUIUI:
992 tmp = 0x75;//jne
993 equiui:
994 if ( !flgcop ) flgcop = startasm( bout );
995 if ( *ptr == CLognot )
996 {
997 ptr++;
998 switch ( cmd )
999 {
1000 case CGreaterII:
1001 case CGreaterUIUI:
1002 tmp++;
1003 break;
1004 case CLessII:
1005 case CLessUIUI:
1006 case CEqUIUI:
1007 tmp--;
1008 }
1009 }
1010 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
1011 buf_append2ch( bout, 0x33, 0xD2);//xor edx,edx
1012 buf_append2ch( bout, 0x39, 0x06);//cmp dword ptr [esi],eax
1013 buf_append2ch( bout, (ubyte)tmp, 0x01);//jne/jge/jle 1
1014 buf_appendch( bout, 0x42 );//inc edx
1015 buf_append2ch( bout, 0x89, 0x16 );//mov dword ptr [esi],edx
1016 goto shift;
1017
1018 case CNotUI:
1019 if ( !flgcop ) flgcop = startasm( bout );
1020 buf_append2ch( bout, 0xF7, 0x16 );//not dword ptr [esi]
1021 goto shift;
1022
1023 case CSubUI:
1024 tmp = 0x29;//0x2B;//sub
1025 goto binopui;
1026 case CAndUI:
1027 tmp = 0x21;//0x23;//and
1028 goto binopui;
1029 case COrUI:
1030 tmp = 0x09;//0x0B;//or
1031 goto binopui;
1032 case CXorUI:
1033 tmp = 0x31;//0x33;//xor
1034 goto binopui;
1035 case CAddUI:
1036 tmp = 0x01;//0x03;//add
1037 binopui:
1038 if ( !flgcop ) flgcop = startasm( bout );
1039 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
1040 buf_append2ch( bout, 0x8B, 0x16 );//mov edx,dword ptr [esi]
1041 //buf_append2ch( bout, (ubyte)tmp, 0x02 );//add/sub/and/or/xor eax,dword ptr [edx]
1042 buf_append2ch( bout, (ubyte)tmp, 0x02 );//add/sub/and/or/xor dword ptr [edx], eax
1043 //buf_append2ch( bout, 0x89, 0x02 );//mov dword ptr [edx],eax
1044 buf_append2ch( bout, 0x8B, 0x02 );//mov eax, dword ptr [edx]
1045 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
1046 goto shift;
1047
1048 case CMulUI:
1049 case CMulI:
1050 if ( !flgcop ) flgcop = startasm( bout );
1051 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
1052 buf_append2ch( bout, 0x8B, 0x1E );//mov ebx,dword ptr [esi]
1053 buf_append3ch( bout, 0x0F, 0xAF, 0x03 );//imul eax,dword ptr [ebx]
1054 buf_append2ch( bout, 0x89, 0x03 );//mov dword ptr [ebx],eax
1055 buf_append2ch( bout, 0x89, 0x06 );//mov dword ptr [esi],eax
1056 goto shift;
1057
1058
1059 case CDivUI:
1060 tmp = 0;
1061 tmp2 = 0xF3;
1062 goto divui;
1063 case CModUI:
1064 tmp = 0x10;
1065 tmp2 = 0xF3;
1066 goto divui;
1067 case CDivI:
1068 tmp = 0;
1069 tmp2 = 0xFB;
1070 goto divui;
1071 case CModI:
1072 tmp = 0x10;
1073 tmp2 = 0xFB;
1074 divui:
1075 if ( !flgcop ) flgcop = startasm( bout );
1076 buf_appendch( bout, 0x51 );//push ecx
1077 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
1078 buf_append2ch( bout, 0x8B, 0xD8 );//mov ebx,eax
1079 buf_append2ch( bout, 0x8B, 0x0E );//mov ecx,dword ptr [esi]
1080 buf_append2ch( bout, 0x8B, 0x01 );//mov eax, dword ptr[ecx]
1081 if ( tmp2 == 0xF3 )
1082 buf_append2ch( bout, 0x33, 0xD2 );//xor edx,edx
1083 else
1084 buf_appendch( bout, 0x99 );//cdq
1085 buf_append2ch( bout, 0xF7, (ubyte)tmp2 );//div/idiv eax,ebx
1086 buf_append2ch( bout, 0x89, (ubyte)( 0x01 + tmp ) );//mov dword ptr [ecx],eax/edx
1087 buf_append2ch( bout, 0x89, (ubyte)( 0x06 + tmp ) );//mov dword ptr [esi],eax/edx
1088 buf_appendch( bout, 0x59 );//pop ecx
1089 goto shift;
1090
1091
1092 case CLeftUI:
1093 case CLeftI:
1094 tmp = 0xE3;//shl
1095 goto rightui;
1096 case CRightI:
1097 tmp = 0xFB;//sar
1098 goto rightui;
1099 case CRightUI:
1100 tmp = 0xEB;//shr
1101 rightui:
1102 if ( !flgcop ) flgcop = startasm( bout );
1103 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
1104 buf_appendch( bout, 0x51 );//push ecx
1105 buf_append2ch( bout, 0x8A, 0xC8 );//mov cl,al
1106 buf_append2ch( bout, 0x8B, 0x16 );//mov edx,dword ptr [esi]
1107 buf_append2ch( bout, 0x8B, 0x1A );//mov ebx,dword ptr [edx]
1108 buf_append2ch( bout, 0xD3, (ubyte)tmp );//shr/shl/sar ebx,cl
1109 buf_append2ch( bout, 0x89, 0x1E );//mov dword ptr [esi],ebx
1110 buf_append2ch( bout, 0x89, 0x1A );//mov dword ptr [edx],ebx
1111 buf_appendch( bout, 0x59 );//pop ecx
1112 goto shift;
1113
1114 case CSubcall:
1115 if ( !flgcop ) flgcop = startasm( bout );
1116 tmp = (*(ptr) + 1)<<2;
1117 off = *(puint)((uint)bjmpdst.data + findnear( &bjmpsrc, tmp, 0 )) - bout->use - 5;
1118 buf_appendch( bout, 0xE8 );//call
1119 buf_appenduint( bout, off );
1120 /*// Меняем стэк
1121 *curpos->top++ = ( uint )( curpos->cmd + 2 ); // указатель на команду после выхода
1122 *curpos->top++ = ( uint )curpos->clmark; // текущее значение clmark
1123 *curpos->top++ = 0; // Количество возвращаемых dword
1124 *curpos->top++ = 0; // Количество полученных dword в качестве параметров
1125 curpos->clmark = curpos->top; // Новое значение clmark
1126 // Указатель на первую команду подфункции
1127 curpos->cmd = ( puint )curpos->func->func + *( curpos->cmd + 1 );*/
1128 goto shift;
1129
1130 case CSubret:
1131 subretsize = *ptr;
1132 /* *( curpos->clmark - 2 ) = *( curpos->cmd + 1 );*/
1133 goto shift;
1134
1135 case CSubpar:
1136 if ( !flgcop ) flgcop = startasm( bout );
1137 buf_appendch( bout, 0x51 );//push ecx
1138 buf_appendch( bout, 0x56 );//push esi
1139 buf_appendch( bout, 0x57 );//push edi
1140
1141 (pvarset)tmp = bcode->sets + *ptr;
1142 subparsize = ((pvarset)tmp)->size/*pset->size*/;
1143 tmp = (bcode->vars + ((pvarset)tmp)->first)->off << 2;
1144 if (tmp < 128)
1145 {
1146 buf_append3ch( bout, 0x83, 0xC7, ( ubyte )tmp );//add edi, tmp
1147 }
1148 else
1149 {
1150 buf_append2ch( bout, 0x81, 0xC7 );//add edi, tmp
1151 buf_appenduint( bout, tmp );
1152 }
1153
1154 tmp = 4 + subparsize * 4;
1155 if (tmp < 128)
1156 {
1157 buf_append3ch( bout, 0x83, 0xEE, ( ubyte )tmp );//sub esi, tmp
1158 }
1159 else
1160 {
1161 buf_append2ch( bout, 0x81, 0xEE );//sub esi, tmp
1162 buf_appenduint( bout, tmp );
1163 }
1164
1165 buf_appendch( bout, 0xB9 );//mov ecx, subparsize
1166 buf_appenduint( bout, subparsize );
1167 buf_appendch( bout, 0xFC );//cld
1168 buf_append2ch( bout, 0xF3, 0xA5 );//rep movs dword ptr [edi],dword ptr [esi]
1169 buf_appendch( bout, 0xFD );//std
1170
1171 buf_appendch( bout, 0x5F );//pop edi
1172 buf_appendch( bout, 0x5E );//pop esi
1173 buf_appendch( bout, 0x59 );//pop ecx
1174 goto shift;
1175
1176 case CSubreturn:
1177 if ( !flgcop ) flgcop = startasm( bout );
1178 for ( tmp = 0; tmp < subretsize; tmp++ )
1179 {
1180 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
1181 buf_appendch( bout, 0x50 );//push eax
1182 }
1183 buf_append3ch( bout, 0x8B, 0x71, 0x14 );//mov esi, dword ptr [ecx+14h]
1184 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
1185 buf_append3ch( bout, 0x89, 0x41, 0x14 );//mov dword ptr [ecx+0x14], eax
1186 buf_appendch( bout, 0xAD );//lods dword ptr [esi]
1187
1188 tmp = (subparsize - subretsize)<<2;
1189 if (tmp < 128)
1190 {
1191 buf_append3ch( bout, 0x83, 0xEE, ( ubyte )tmp );//sub esi, tmp
1192 }
1193 else
1194 {
1195 buf_append2ch( bout, 0x81, 0xEE );//sub esi, tmp
1196 buf_appenduint( bout, tmp );
1197 }
1198
1199 if ( subretsize == 2 )
1200 {
1201 buf_appendch( bout, 0x5A );//pop edx
1202 buf_append3ch( bout, 0x89, 0x56, 0xFC );//mov dword ptr [esi-4], edx
1203 }
1204 if ( subretsize )
1205 {
1206 buf_appendch( bout, 0x5A );//pop edx
1207 buf_append2ch( bout, 0x89, 0x16 );//mov dword ptr [esi], edx
1208 }
1209
1210 buf_appendch( bout, 0x50 );//push eax
1211 buf_appendch( bout, 0xC3 );//ret
1212
1213 /*// Выход из подфункции
1214 top = curpos->clmark - 4; // Указатель на старый top
1215 // Восстанавливаем команду
1216 curpos->cmd = ( puint )*top;
1217 curpos->clmark = ( puint )*( top + 1 );
1218 i = *( top + 2 );
1219 // записываем возвращаемое значение
1220 if ( i )
1221 mem_copyui( top - *( top + 3 ), curpos->top - i, i );
1222 // Устанавливаем стэк
1223 curpos->top = top + i - *( top + 3 );*/
1224 goto shift;
1225
1226 case CDwsload:
1227 case CAsm:
1228 i = *ptr + 2;
1229 *ptr--;
1230 for ( i; i > 0; i-- )
1231 {
1232 buf_appenduint( bout, *ptr++ );
1233 }
1234 break;
1235
1236 case CDecLeftUB:
1237 flgtmp = 5;
1238 goto leftinc;
1239 case CDecLeftUS:
1240 flgtmp = 4;
1241 goto leftinc;
1242 case CDecLeftUI:
1243 flgtmp = 3;
1244 goto leftinc;
1245 case CIncLeftUB:
1246 flgtmp = 2;
1247 goto leftinc;
1248 case CIncLeftUS:
1249 flgtmp = 1;
1250 goto leftinc;
1251 case CIncLeftUI:
1252 flgtmp = 0;
1253 leftinc:
1254 if ( !flgcop ) flgcop = startasm( bout );
1255 buf_append2ch( bout, 0x8B, 0x06 );//mov eax,dword ptr [esi]
1256 switch ( flgtmp )
1257 {
1258 case 0:
1259 buf_append2ch( bout, 0xFF, 0x00 );//inc dword ptr [eax]
1260 break;
1261 case 1:
1262 buf_append3ch( bout, 0x66, 0xFF, 0x00 );//inc word ptr [eax]
1263 break;
1264 case 2:
1265 buf_append2ch( bout, 0xFE, 0x00 );//inc byte ptr [eax]
1266 break;
1267 case 3:
1268 buf_append2ch( bout, 0xFF, 0x08 );//dec dword ptr [eax]
1269 break;
1270 case 4:
1271 buf_append3ch( bout, 0x66, 0xFF, 0x08 );//dec word ptr [eax]
1272 break;
1273 case 5:
1274 buf_append2ch( bout, 0xFE, 0x08 );//dec byte ptr [eax]
1275 break;
1276 }
1277 buf_append2ch( bout, 0x8B, 0x18 );//mov ebx,dword ptr [eax]
1278 buf_append2ch( bout, 0x89, 0x1E );//mov dword ptr [esi],ebx
1279 goto shift;
1280
1281 case CDecRightUB:
1282 flgtmp = 5;
1283 goto rightinc;
1284 case CDecRightUS:
1285 flgtmp = 4;
1286 goto rightinc;
1287 case CDecRightUI:
1288 flgtmp = 3;
1289 goto rightinc;
1290 case CIncRightUB:
1291 flgtmp = 2;
1292 goto rightinc;
1293 case CIncRightUS:
1294 flgtmp = 1;
1295 goto rightinc;
1296 case CIncRightUI:
1297 flgtmp = 0;
1298 rightinc:
1299 if ( !flgcop ) flgcop = startasm( bout );
1300 buf_append2ch( bout, 0x8B, 0x06 );//mov eax,dword ptr [esi]
1301 buf_append2ch( bout, 0x8B, 0x18 );//mov ebx,dword ptr [eax]
1302 buf_append2ch( bout, 0x89, 0x1E );//mov dword ptr [esi],ebx
1303 switch ( flgtmp )
1304 {
1305 case 0:
1306 buf_append2ch( bout, 0xFF, 0x00 );//inc dword ptr [eax]
1307 break;
1308 case 1:
1309 buf_append3ch( bout, 0x66, 0xFF, 0x00 );//inc word ptr [eax]
1310 break;
1311 case 2:
1312 buf_append2ch( bout, 0xFE, 0x00 );//inc byte ptr [eax]
1313 break;
1314 case 3:
1315 buf_append2ch( bout, 0xFF, 0x08 );//dec dword ptr [eax]
1316 break;
1317 case 4:
1318 buf_append3ch( bout, 0x66, 0xFF, 0x08 );//dec word ptr [eax]
1319 break;
1320 case 5:
1321 buf_append2ch( bout, 0xFE, 0x08 );//dec byte ptr [eax]
1322 break;
1323 }
1324 goto shift;
1325
1326
1327 /*c
1328 case CPtrglobal:
1329 if ( flgcop )
1330 {
1331 stopasm( bout, flgcop);
1332 flgcop = 0;
1333 }
1334 buf_appenduint( bout, cmd );
1335 //ge_getused( *ptr );
1336 buf_appenduint( bout, *ptr++ );
1337 break;*/
1338
1339 default:
1340 if ( flgcop )
1341 {
1342 stopasm( bout, flgcop);
1343 flgcop = 0;
1344 }
1345
1346 buf_appenduint( bout, cmd );//pop ebx
1347 switch ( shifts[ cmd - CNop ] )
1348 {
1349 case SH1_3:
1350 case SH2_3:
1351 buf_appenduint( bout, *ptr++ );
1352 case SHN1_2:
1353 case SH0_2:
1354 case SH1_2:
1355 buf_appenduint( bout, *ptr++ );
1356 break;
1357 }
1358 }
1359
1360 continue;
1361 shift:
1362
1363 switch ( shifts[ cmd - CNop ] )
1364 {
1365 case SH1_3:
1366 case SH2_3:
1367 ptr++;
1368 case SHN1_2:
1369 case SH0_2:
1370 case SH1_2:
1371 ptr++;
1372 break;
1373 }
1374 }
1375 }
1376 ptr = ( puint )bjmpun.data;
1377 end = ( puint )( ( pubyte )ptr + bjmpun.use );
1378 //Коррекция переходов
1379 while ( ptr < end )
1380 {
1381 tmp = *(ptr++);
1382 off = *(puint)((uint)bjmpdst.data + findnear( &bjmpsrc, *(ptr++), 0 ));
1383 if ( off )
1384 {
1385 *(puint)((uint)bout->data + tmp ) = off - tmp - 4;
1386 }
1387 }
1388
1389 // Вывод
1390 /*ptr = ( puint )bcode->vmf.func;
1391 end = ( puint )( ( pubyte )ptr + bcode->bcsize );
1392 print( "src %i\n", bout->use );
1393 while ( ptr < end )
1394 print( " %x", *ptr++ );
1395 print( "\n dest \n" );
1396 ptr = ( puint )bout->data;
1397 end = ( puint )( ( pubyte )ptr + bout->use );
1398 while ( ptr < end )
1399 print( " %x", *ptr++ );
1400 */
1401 /*
1402 bcode->vmf.func = bout->data;
1403 bcode->bcsize = bout->use;
1404 */
1405 }
1406
1407 #endif // _ASM