source: dev/trunk/abdev/BasicCompiler32/op32_main.cpp@ 206

Last change on this file since 206 was 206, checked in by dai_9181, 17 years ago

コード全体のリファクタリングを実施

File size: 21.6 KB
Line 
1#include "stdafx.h"
2
3#include "../BasicCompiler_Common/common.h"
4#include "Opcode.h"
5
6
7
8BOOL IsSafeReg(int reg){
9 if(reg==REG_EBX||reg==REG_ESI||reg==REG_EDI) return 1;
10 return 0;
11}
12
13
14
15/////////////////////////////////////////////////
16// ModR/Mバイト、SIBバイト、ディスプレースメント
17/////////////////////////////////////////////////
18
19//スケール
20#define SCALE_NON (char)0x00
21#define SCALE_2 (char)0x40
22#define SCALE_4 (char)0x80
23#define SCALE_8 (char)0xC0
24
25//インデックスなし
26#define INDEX_NON 0x04
27
28void set_mod_rm_sib_disp(char mod,int reg,int scale,int index_reg,int base_reg,int disp){
29 if(mod==MOD_DISP32){
30 //ModR/Mバイト
31 OpBuffer[obp++]=(char)( REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(0x04));
32
33 base_reg=0x05;
34 index_reg=INDEX_NON;
35 }
36 else{
37 //ModR/Mバイト
38 OpBuffer[obp++]=(char)(mod | REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(base_reg));
39 }
40
41
42 //レジスタモードの場合は、ここで終了
43 if(mod==MOD_REG) return;
44
45
46 if(REGISTER_OPERAND(base_reg)==0x04||mod==MOD_DISP32){
47 //////////////////////
48 // SIBバイトを使う
49 //////////////////////
50
51 OpBuffer[obp++]=(char)(scale| REGISTER_OPERAND(index_reg)<<3 | REGISTER_OPERAND(base_reg));
52 }
53
54 //ディスプレースメントを必要としない場合は、ここで終了
55 if(mod==MOD_BASE) return;
56
57
58 //////////////////////////
59 // ディスプレースメント
60 //////////////////////////
61
62 if(mod==MOD_BASE_DISP8) OpBuffer[obp++]=(char)disp;
63 else{
64 *((long *)(OpBuffer+obp))=disp;
65 obp+=sizeof(long);
66 }
67}
68
69
70
71void __op_format(char op_prefix,char opcode,int reg){
72 //命令プリフィックス
73 if(op_prefix) OpBuffer[obp++]=op_prefix;
74
75 //オペコード、レジスタ
76 OpBuffer[obp++]=(char)(opcode|REGISTER_OPERAND(reg));
77}
78void __op_format(char op_prefix,char opcode1,char opcode2,int reg,int base_reg,int offset,char mod){
79 //命令プリフィックス
80 if(op_prefix) OpBuffer[obp++]=op_prefix;
81
82 //オペコード
83 OpBuffer[obp++]=opcode1;
84 if(opcode2) OpBuffer[obp++]=opcode2;
85
86 //ModR/M, SIB, disp
87 set_mod_rm_sib_disp(mod,reg,SCALE_NON,INDEX_NON,base_reg,offset);
88}
89
90
91
92///////////////////
93// mov関連
94///////////////////
95
96void op_mov_RV(int reg,int offset){
97 //mov reg,value
98
99 //オペコード、レジスタ
100 OpBuffer[obp++]=(char)(0xB8|REGISTER_OPERAND(reg));
101
102 //DISP32
103 *((long *)(OpBuffer+obp))=offset;
104 obp+=sizeof(long);
105}
106void op_mov_RV(int op_size,int reg,int offset){
107 if(op_size==PTR_SIZE) op_mov_RV(reg,offset);
108 else SetError(300,NULL,cp);
109}
110void op_mov_RR(int reg1,int reg2){
111 //mov reg1,reg2
112
113 if(reg1==reg2) return;
114
115 //1000 1011 11xx xbbb
116 OpBuffer[obp++]=(char)0x8B;
117 OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2));
118}
119void op_mov_RM(int op_size,int reg,int base_reg,int offset,char mod){
120 //mov reg32,dword ptr[base_reg+offset]
121 //mov reg16,word ptr[base_reg+offset]
122 //mov reg8,byte ptr[base_reg+offset]
123
124 //16ビット演算の命令プリフィックス
125 char op_prefix=0;
126 if(op_size==sizeof(short)) op_prefix=(char)0x66;
127
128 //オペコード
129 char opcode;
130 if(op_size==sizeof(char)) opcode=(char)0x8A;
131 else opcode=(char)0x8B;
132
133 __op_format(op_prefix,opcode,0,reg,base_reg,offset,mod);
134}
135void op_mov_RM_ex(int op_size,int reg,int base_reg1,int base_reg2,int offset,BOOL bUseOffset){
136 //mov reg32,dword ptr[base_reg1+base_reg2+offset]
137 //mov reg16,word ptr[base_reg1+base_reg2+offset]
138 //mov reg8,byte ptr[base_reg1+base_reg2+offset]
139
140 if(base_reg1==REG_ESP){
141 //SIBバイトのindex部にespは指定できない
142 base_reg1=base_reg2;
143 base_reg2=REG_ESP;
144 }
145
146 //16ビット演算のプリフィックス
147 if(op_size==sizeof(short)) OpBuffer[obp++]=(char)0x66;
148
149 //オペコード
150 if(op_size==sizeof(char)) OpBuffer[obp++]=(char)0x8A;
151 else OpBuffer[obp++]=(char)0x8B;
152
153 if(bUseOffset){
154 ///////////////////////////
155 // オフセット値を使う
156 ///////////////////////////
157
158 //レジスタ
159 OpBuffer[obp++]=(char)(0x84| REGISTER_OPERAND(reg)<<3);
160
161 //ベースレジスタ
162 OpBuffer[obp++]=(char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2));
163
164 //オフセット値
165 *((long *)(OpBuffer+obp))=offset;
166 obp+=sizeof(long);
167 }
168 else{
169 ///////////////////////////
170 // オフセット値を使わない
171 ///////////////////////////
172
173 //レジスタ
174 OpBuffer[obp++]=(char)(0x04| REGISTER_OPERAND(reg)<<3);
175
176 //ベースレジスタ
177 OpBuffer[obp++]=(char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2));
178 }
179}
180void op_mov_MR(int op_size,int reg,int base_reg,int offset,char mod){
181 //mov dword ptr[base_reg+offset],reg32
182 //mov word ptr[base_reg+offset],reg16
183 //mov byte ptr[base_reg+offset],reg8
184
185 //16ビット演算の命令プリフィックス
186 char op_prefix=0;
187 if(op_size==sizeof(short)) op_prefix=(char)0x66;
188
189 //オペコード
190 char opcode;
191 if(op_size==sizeof(char)) opcode=(char)0x88;
192 else opcode=(char)0x89;
193
194 __op_format(op_prefix,opcode,0,reg,base_reg,offset,mod);
195}
196void op_mov_MR_ex(int op_size,int reg,int base_reg1,int base_reg2,int offset,BOOL bUseOffset){
197 //mov dword ptr[base_reg1+base_reg2+offset],reg32
198 //mov word ptr[base_reg1+base_reg2+offset],reg16
199 //mov byte ptr[base_reg1+base_reg2+offset],reg8
200
201 if(base_reg1==REG_ESP){
202 //SIBバイトのindex部にrspは指定できない
203 base_reg1=base_reg2;
204 base_reg2=REG_ESP;
205 }
206
207 //16ビット演算のプリフィックス
208 if(op_size==sizeof(short)) OpBuffer[obp++]=(char)0x66;
209
210 //オペコード
211 if(op_size==sizeof(char)) OpBuffer[obp++]=(char)0x88;
212 else OpBuffer[obp++]=(char)0x89;
213
214 if(bUseOffset==USE_OFFSET){
215 //////////////////////////
216 //オフセット値を使う
217 //////////////////////////
218
219 //レジスタ
220 OpBuffer[obp++]=(char)(0x84| REGISTER_OPERAND(reg)<<3);
221
222 //ベースレジスタ
223 OpBuffer[obp++]=(char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2));
224
225 //オフセット値
226 *((long *)(OpBuffer+obp))=offset;
227 obp+=sizeof(long);
228 }
229 else{
230 //////////////////////////
231 //オフセット値を使わない
232 //////////////////////////
233
234 //レジスタ
235 OpBuffer[obp++]=(char)(0x04| REGISTER_OPERAND(reg)<<3);
236
237 //ベースレジスタ
238 OpBuffer[obp++]=(char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2));
239 }
240}
241
242
243
244
245////////////////////////////////
246// movsx関連
247////////////////////////////////
248
249void op_movsx_R32R16(int reg32,int reg16){
250 //movsx reg32,reg16
251
252 //16ビット演算の命令プリフィックス
253 char op_prefix=0;
254
255 //オペコード
256 char opcode=(char)0x0F;
257 char opcode2=(char)0xBF;
258
259 __op_format(op_prefix,opcode,opcode2,reg32,reg16,0,MOD_REG);
260}
261void op_movsx_R32R8(int reg32,int reg8){
262 //movsx reg32,reg8
263
264 //16ビット演算の命令プリフィックス
265 char op_prefix=0;
266
267 //オペコード
268 char opcode=(char)0x0F;
269 char opcode2=(char)0xBE;
270
271 __op_format(op_prefix,opcode,opcode2,reg32,reg8,0,MOD_REG);
272}
273void op_movsx_R16R8(int reg16,int reg8){
274 //movsx reg16,reg8
275
276 //16ビット演算の命令プリフィックス
277 char op_prefix=(char)0x66;
278
279 //オペコード
280 char opcode=(char)0x0F;
281 char opcode2=(char)0xBE;
282
283 __op_format(op_prefix,opcode,opcode2,reg16,reg8,0,MOD_REG);
284}
285
286
287
288//////////////////////////////////
289// インクリメント・デクリメント
290//////////////////////////////////
291
292void op_inc(int reg){
293 //inc reg
294
295 //16ビット演算の命令プリフィックス
296 char op_prefix=0;
297
298 //オペコード
299 char opcode=(char)0xFF;
300
301 __op_format(op_prefix,opcode,0,0,reg,0,MOD_REG);
302}
303void op_dec(int reg){
304 op_inc(reg);
305 OpBuffer[obp-1]=OpBuffer[obp-1]|0x08;
306}
307
308
309
310/////////////////////
311// add関連
312/////////////////////
313
314void op_add_RV8(int reg,char cValue){
315 //add reg,value8
316
317 OpBuffer[obp++]=(char)0x83;
318 OpBuffer[obp++]=(char)(0xC0|REGISTER_OPERAND(reg));
319 OpBuffer[obp++]=cValue;
320}
321void op_add_RM(int op_size,int reg,int base_reg,int offset,char mod){
322 //add reg32,dword ptr[base_reg+offset]
323 //add reg16,word ptr[base_reg+offset]
324 //add reg8,byte ptr[base_reg+offset]
325
326 //16ビット演算の命令プリフィックス
327 char op_prefix=0;
328 if(op_size==sizeof(short)) op_prefix=(char)0x66;
329
330 //オペコード
331 char opcode;
332 if(op_size==sizeof(char)) opcode=(char)0x02;
333 else opcode=(char)0x03;
334
335 __op_format(op_prefix,opcode,0,reg,base_reg,offset,mod);
336}
337void op_adc_RV8(int reg,char cValue){
338 //adc reg,value8
339
340 OpBuffer[obp++]=(char)0x83;
341 OpBuffer[obp++]=(char)(0xD0|REGISTER_OPERAND(reg));
342 OpBuffer[obp++]=cValue;
343}
344
345
346/////////////////////
347// sub関連
348/////////////////////
349
350void op_sub_RV8(int reg,char cValue){
351 //sub reg,value8
352
353 OpBuffer[obp++]=(char)0x83;
354 OpBuffer[obp++]=(char)(0xE8|REGISTER_OPERAND(reg));
355 OpBuffer[obp++]=cValue;
356}
357void op_sbb_RV8(int reg,char cValue){
358 //sbb reg,value8
359
360 OpBuffer[obp++]=(char)0x83;
361 OpBuffer[obp++]=(char)(0xD8|REGISTER_OPERAND(reg));
362 OpBuffer[obp++]=cValue;
363}
364void op_sbb_RR( int reg1, int reg2 ){
365 //sbb reg1,reg2
366
367 //オペコード
368 OpBuffer[obp++]=(char)0x1B;
369
370 //レジスタ
371 OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2));
372}
373
374
375
376////////////////////////
377// imul関連
378////////////////////////
379
380void op_imul_RR(int reg1,int reg2){
381 //imul reg1,reg2
382
383 //オペコード
384 OpBuffer[obp++]=(char)0x0F;
385 OpBuffer[obp++]=(char)0xAF;
386
387 //レジスタ
388 OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2));
389}
390
391void op_imul_RV(int reg,int i32data){
392 //imul reg,i32data
393
394 if(-128<=i32data&&i32data<=127){
395 //オペコード
396 OpBuffer[obp++]=(char)0x6B;
397
398 //レジスタ
399 OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg));
400
401 //値
402 OpBuffer[obp++]=(char)i32data;
403 }
404 else{
405 //オペコード
406 OpBuffer[obp++]=(char)0x69;
407
408 //レジスタ
409 OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg));
410
411 //値
412 *((long *)(OpBuffer+obp))=i32data;
413 obp+=sizeof(long);
414 }
415}
416
417
418
419//////////////////////
420// and関連
421//////////////////////
422
423void op_and_RV(int reg,int value){
424 //and reg,value
425
426 if(reg==REG_RAX){
427 //eaxのみ特殊
428
429 // [8bit rex] 0010 0101 [32bit offset]
430 OpBuffer[obp++]=(char)0x25;
431 *((long *)(OpBuffer+obp))=value;
432 obp+=sizeof(long);
433 }
434 else{
435 //16ビット演算の命令プリフィックス
436 char op_prefix=0;
437
438 //オペコード
439 char opcode=(char)0x81;
440
441 __op_format(op_prefix,opcode,0,0,reg,value,MOD_REG);
442 }
443}
444
445void op_or_RR( int op_size, int reg1, int reg2 ){
446 //16ビット演算のプリフィックス
447 if(op_size==sizeof(short)) OpBuffer[obp++]=(char)0x66;
448
449 //オペコード
450 if(op_size==sizeof(char)) OpBuffer[obp++]=(char)0x0A;
451 else OpBuffer[obp++]=(char)0x0B;
452
453 //レジスタ
454 OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2));
455}
456
457
458
459void op_neg( int reg ){
460 //neg reg
461
462 //オペコード
463 OpBuffer[obp++]=(char)0xF7;
464
465 //レジスタ
466 OpBuffer[obp++]=(char)(0xD8| REGISTER_OPERAND(reg));
467}
468
469
470
471///////////////////////
472// 64ビット関連
473///////////////////////
474
475void op_cdq(){
476 //cdq
477 OpBuffer[obp++]=(char)0x99;
478}
479
480
481
482/////////////////////
483// ストリング関係
484/////////////////////
485
486void op_rep_movs(int op_size){
487 if(op_size==sizeof(BYTE)){
488 //rep movs byte ptr[edi],byte ptr[esi]
489 OpBuffer[obp++]=(char)0xF3;
490 OpBuffer[obp++]=(char)0xA4;
491 }
492 else if(op_size==sizeof(short)){
493 //rep movs word ptr[edi],word ptr[esi]
494 OpBuffer[obp++]=(char)0xF3;
495 OpBuffer[obp++]=(char)0x66;
496 OpBuffer[obp++]=(char)0xA5;
497 }
498 else if(op_size==sizeof(long)){
499 //rep movs dword ptr[edi],dword ptr[esi]
500 OpBuffer[obp++]=(char)0xF3;
501 OpBuffer[obp++]=(char)0xA5;
502 }
503}
504
505
506
507
508//////////////////////////
509// スタック関連
510//////////////////////////
511
512void op_push(int reg){
513 //push reg
514
515 if( reg == REG_NON ){
516 op_sub_esp( PTR_SIZE );
517 return;
518 }
519
520 //オペコード、レジスタ
521 __op_format(0,(char)0x50,reg);
522}
523void op_push_V(long data){
524 //スタックにリテラル値をプッシュ
525 if(-128<=data&&data<=127){
526 //push 8ビット値
527 OpBuffer[obp++]=(char)0x6A;
528 OpBuffer[obp++]=(char)data;
529 }
530 else{
531 //push 32ビット値
532 OpBuffer[obp++]=(char)0x68;
533 *((long *)(OpBuffer+obp))=data;
534 obp+=sizeof(long);
535 }
536}
537void op_pop(int reg){
538 //pop reg
539
540 if( reg == REG_NON ){
541 op_add_esp( PTR_SIZE );
542 return;
543 }
544
545 //オペコード、レジスタ
546 __op_format(0,(char)0x58,reg);
547}
548void op_add_esp(int num){
549 //スタックポインタの加算(pop方向)
550
551 //add esp,num
552 if(0xFFFFFF80&num){
553 OpBuffer[obp++]=(char)0x81;
554 OpBuffer[obp++]=(char)0xC4;
555 *((long *)(OpBuffer+obp))=num;
556 obp+=sizeof(long);
557 }
558 else{
559 //「128 > num > -127」の場合
560 OpBuffer[obp++]=(char)0x83;
561 OpBuffer[obp++]=(char)0xC4;
562 OpBuffer[obp++]=(char)num;
563 }
564}
565void op_sub_esp(int num){
566 //スタックポインタの減算(push方向)
567
568 //sub esp,num
569 if(0xFFFFFF80&num){
570 OpBuffer[obp++]=(char)0x81;
571 OpBuffer[obp++]=(char)0xEC;
572 *((long *)(OpBuffer+obp))=num;
573 obp+=sizeof(long);
574 }
575 else{
576 //「128 > num > -127」の場合
577 OpBuffer[obp++]=(char)0x83;
578 OpBuffer[obp++]=(char)0xEC;
579 OpBuffer[obp++]=(char)num;
580 }
581}
582
583
584
585/////////////////////
586// cmp関連
587/////////////////////
588void op_cmp_RR( int reg1, int reg2 ){
589 //オペコード
590 OpBuffer[obp++]=(char)0x3B;
591
592 //レジスタ
593 OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2));
594}
595void op_cmp_value(int op_size,int reg,char byte_data){
596 //cmp reg,byte_data
597
598 if(op_size==sizeof(char)&&reg==REG_EAX){
599 //alレジスタの場合は特殊
600 OpBuffer[obp++]=(char)0x3C;
601
602 //8ビット値
603 OpBuffer[obp++]=byte_data;
604
605 return;
606 }
607
608 //16ビット演算のプリフィックス
609 if(op_size==sizeof(short)) OpBuffer[obp++]=(char)0x66;
610
611 //オペコード
612 if(op_size==sizeof(char)) OpBuffer[obp++]=(char)0x80;
613 else OpBuffer[obp++]=(char)0x83;
614
615 //レジスタ
616 OpBuffer[obp++]=(char)(0xF8| REGISTER_OPERAND(reg));
617
618 //8ビット値
619 OpBuffer[obp++]=byte_data;
620}
621void op_setne( int reg ){
622 //オペコード
623 OpBuffer[obp++]=(char)0x0F;
624 OpBuffer[obp++]=(char)0x95;
625
626 //レジスタ
627 OpBuffer[obp++]=(char)( 0xC0 | REGISTER_OPERAND(reg) );
628}
629
630
631
632////////////////////
633// test関連
634////////////////////
635
636void op_test(int reg1,int reg2){
637 //test reg1,reg2
638
639 //1000 0101 11rr rbbb
640 OpBuffer[obp++]=(char)0x85;
641 OpBuffer[obp++]=(char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2));
642}
643
644
645
646//////////////////////////////
647// 浮動小数点関連
648//////////////////////////////
649
650void op_fld_ptr_esp(int type){
651 //スタックポインタが示すバッファのデータを浮動小数点レジスタへロード
652
653 if(type==DEF_DOUBLE){
654 //fld qword ptr[esp]
655 OpBuffer[obp++]=(char)0xDD;
656 OpBuffer[obp++]=(char)0x04;
657 OpBuffer[obp++]=(char)0x24;
658 }
659 else if(type==DEF_SINGLE){
660 //fld dword ptr[esp]
661 OpBuffer[obp++]=(char)0xD9;
662 OpBuffer[obp++]=(char)0x04;
663 OpBuffer[obp++]=(char)0x24;
664 }
665 else if(type==DEF_INT64){
666 //fild qword ptr[esp]
667 OpBuffer[obp++]=(char)0xDF;
668 OpBuffer[obp++]=(char)0x2C;
669 OpBuffer[obp++]=(char)0x24;
670 }
671 else if(type==DEF_LONG){
672 //fild dword ptr[esp]
673 OpBuffer[obp++]=(char)0xDB;
674 OpBuffer[obp++]=(char)0x04;
675 OpBuffer[obp++]=(char)0x24;
676 }
677}
678void op_fld_basereg(int type,int base_reg){
679 //fld ptr[reg]
680
681 //オペコード
682 if(type==DEF_DOUBLE) OpBuffer[obp++]=(char)0xDD;
683 else if(type==DEF_SINGLE) OpBuffer[obp++]=(char)0xD9;
684 else SetError(300,NULL,cp);
685
686 if(base_reg==REG_ESP){
687 OpBuffer[obp++]=(char)0x04;
688 OpBuffer[obp++]=(char)0x24;
689 }
690 else if(base_reg==REG_EBP){
691 OpBuffer[obp++]=(char)0x45;
692 OpBuffer[obp++]=(char)0x00;
693 }
694 else{
695 OpBuffer[obp++]=(char)REGISTER_OPERAND(base_reg);
696 }
697}
698void op_fld_base_offset(int type,int base_reg,int offset){
699 //fld ptr[reg+offset]
700
701 //オペコード
702 if(type==DEF_DOUBLE) OpBuffer[obp++]=(char)0xDD;
703 else if(type==DEF_SINGLE) OpBuffer[obp++]=(char)0xD9;
704 else SetError(300,NULL,cp);
705
706 //オペコード、レジスタ
707 if(base_reg==REG_ESP){
708 OpBuffer[obp++]=(char)0x84;
709 OpBuffer[obp++]=(char)0x24;
710 }
711 else{
712 OpBuffer[obp++]=(char)(0x80|REGISTER_OPERAND(base_reg));
713 }
714
715 //オフセット値
716 *((long *)(OpBuffer+obp))=offset;
717 obp+=sizeof(long);
718}
719void op_fld_base_offset_ex(int type,int base_reg1,int base_reg2,int offset,BOOL bUseOffset){
720 //fld ptr[base_reg1+base_reg2+offset]
721
722 if(base_reg1==REG_ESP){
723 //SIBバイトのindex部にespは指定できない
724 base_reg1=base_reg2;
725 base_reg2=REG_ESP;
726 }
727
728 //オペコード
729 if(type==DEF_DOUBLE) OpBuffer[obp++]=(char)0xDD;
730 else if(type==DEF_SINGLE) OpBuffer[obp++]=(char)0xD9;
731 else SetError(300,NULL,cp);
732
733 int reg=0;
734 if(bUseOffset){
735 ///////////////////////////
736 // オフセット値を使う
737 ///////////////////////////
738
739 //レジスタ
740 OpBuffer[obp++]=(char)(0x84| REGISTER_OPERAND(reg)<<3);
741
742 //ベースレジスタ
743 OpBuffer[obp++]=(char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2));
744
745 //オフセット値
746 *((long *)(OpBuffer+obp))=offset;
747 obp+=sizeof(long);
748 }
749 else{
750 ///////////////////////////
751 // オフセット値を使わない
752 ///////////////////////////
753
754 //レジスタ
755 OpBuffer[obp++]=(char)(0x04| REGISTER_OPERAND(reg)<<3);
756
757 //ベースレジスタ
758 OpBuffer[obp++]=(char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2));
759 }
760}
761void op_fstp_basereg(int type,int base_reg){
762 //fstp ptr[reg]
763
764 //オペコード
765 if(type==DEF_DOUBLE) OpBuffer[obp++]=(char)0xDD;
766 else if(type==DEF_SINGLE) OpBuffer[obp++]=(char)0xD9;
767 else SetError(300,NULL,cp);
768
769 if(base_reg==REG_ESP){
770 OpBuffer[obp++]=(char)0x1C;
771 OpBuffer[obp++]=(char)0x24;
772 }
773 else if(base_reg==REG_EBP){
774 OpBuffer[obp++]=(char)0x5D;
775 OpBuffer[obp++]=(char)0x00;
776 }
777 else{
778 OpBuffer[obp++]=(char)(0x18|REGISTER_OPERAND(base_reg));
779 }
780}
781void op_fstp_base_offset(int type,int base_reg,int offset){
782 //fstp ptr[reg+offset]
783
784 //オペコード
785 if(type==DEF_DOUBLE) OpBuffer[obp++]=(char)0xDD;
786 else if(type==DEF_SINGLE) OpBuffer[obp++]=(char)0xD9;
787 else SetError(300,NULL,cp);
788
789 //オペコード、レジスタ
790 if(base_reg==REG_ESP){
791 OpBuffer[obp++]=(char)0x9C;
792 OpBuffer[obp++]=(char)0x24;
793 }
794 else{
795 OpBuffer[obp++]=(char)(0x98|REGISTER_OPERAND(base_reg));
796 }
797
798 //オフセット値
799 *((long *)(OpBuffer+obp))=offset;
800 obp+=sizeof(long);
801}
802void op_fstp_base_offset_ex(int type,int base_reg1,int base_reg2,int offset,BOOL bUseOffset){
803 //fstp ptr[base_reg1+base_reg2+offset]
804
805 if(base_reg1==REG_ESP){
806 //SIBバイトのindex部にespは指定できない
807 base_reg1=base_reg2;
808 base_reg2=REG_ESP;
809 }
810
811 //オペコード
812 if(type==DEF_DOUBLE) OpBuffer[obp++]=(char)0xDD;
813 else if(type==DEF_SINGLE) OpBuffer[obp++]=(char)0xD9;
814 else SetError(300,NULL,cp);
815
816 int reg=0;
817 if(bUseOffset){
818 ///////////////////////////
819 // オフセット値を使う
820 ///////////////////////////
821
822 //レジスタ
823 OpBuffer[obp++]=(char)(0x9C| REGISTER_OPERAND(reg)<<3);
824
825 //ベースレジスタ
826 OpBuffer[obp++]=(char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2));
827
828 //オフセット値
829 *((long *)(OpBuffer+obp))=offset;
830 obp+=sizeof(long);
831 }
832 else{
833 ///////////////////////////
834 // オフセット値を使わない
835 ///////////////////////////
836
837 //レジスタ
838 OpBuffer[obp++]=(char)(0x1C| REGISTER_OPERAND(reg)<<3);
839
840 //ベースレジスタ
841 OpBuffer[obp++]=(char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2));
842 }
843}
844void op_fistp_ptr_esp( int typeSize ){
845 if( typeSize == sizeof(_int64) ){
846 //64bit
847
848 //fistp qword ptr[esp]
849 fpu_cast();
850 OpBuffer[obp++]=(char)0xDF;
851 OpBuffer[obp++]=(char)0x3C;
852 OpBuffer[obp++]=(char)0x24;
853 fpu_cast_end();
854 }
855 else if( typeSize == sizeof(long) ){
856 //32bit
857
858 //fistp dword ptr[esp]
859 fpu_cast();
860 OpBuffer[obp++]=(char)0xDB;
861 OpBuffer[obp++]=(char)0x1C;
862 OpBuffer[obp++]=(char)0x24;
863 fpu_cast_end();
864 }
865 else{
866 SetError();
867 }
868}
869void op_fstp_push( Type &type ){
870 //sub esp,size
871 op_sub_esp( type.GetBasicSize() );
872
873 op_fstp_basereg( type.GetBasicType(), REG_ESP );
874}
875
876
877
878//////////////////////////////
879// レジスタ関連
880//////////////////////////////
881
882void op_zero_reg(int reg){
883 //レジスタに0をセット
884
885 switch(reg){
886 case REG_EAX:
887 //xor eax,eax
888 OpBuffer[obp++]=(char)0x33;
889 OpBuffer[obp++]=(char)0xC0;
890 break;
891 case REG_EBX:
892 //xor ebx,ebx
893 OpBuffer[obp++]=(char)0x33;
894 OpBuffer[obp++]=(char)0xDB;
895 break;
896 case REG_ECX:
897 //xor ecx,ecx
898 OpBuffer[obp++]=(char)0x33;
899 OpBuffer[obp++]=(char)0xC9;
900 break;
901 case REG_EDX:
902 //xor edx,edx
903 OpBuffer[obp++]=(char)0x33;
904 OpBuffer[obp++]=(char)0xD2;
905 break;
906 case REG_EBP:
907 //xor ebp,ebp
908 OpBuffer[obp++]=(char)0x33;
909 OpBuffer[obp++]=(char)0xED;
910 break;
911 }
912}
913
914void fpu_cast(){
915 ///////////////////////
916 // FPUの切り捨て設定
917 ///////////////////////
918
919 //sub esp,16
920 op_sub_esp(16);
921
922 //mov dword ptr[esp+4],eax
923 OpBuffer[obp++]=(char)0x89;
924 OpBuffer[obp++]=(char)0x44;
925 OpBuffer[obp++]=(char)0x24;
926 OpBuffer[obp++]=(char)0x04;
927
928 //fnstcw word ptr[esp]
929 OpBuffer[obp++]=(char)0xD9;
930 OpBuffer[obp++]=(char)0x3C;
931 OpBuffer[obp++]=(char)0x24;
932
933 //mov ax,word ptr[esp]
934 OpBuffer[obp++]=(char)0x66;
935 OpBuffer[obp++]=(char)0x8B;
936 OpBuffer[obp++]=(char)0x04;
937 OpBuffer[obp++]=(char)0x24;
938
939 //or ah,0Ch
940 OpBuffer[obp++]=(char)0x80;
941 OpBuffer[obp++]=(char)0xCC;
942 OpBuffer[obp++]=(char)0x0C;
943
944 //mov word ptr[esp+2],ax
945 OpBuffer[obp++]=(char)0x66;
946 OpBuffer[obp++]=(char)0x89;
947 OpBuffer[obp++]=(char)0x44;
948 OpBuffer[obp++]=(char)0x24;
949 OpBuffer[obp++]=(char)0x02;
950
951 //fldcw word ptr[esp+2]
952 OpBuffer[obp++]=(char)0xD9;
953 OpBuffer[obp++]=(char)0x6C;
954 OpBuffer[obp++]=(char)0x24;
955 OpBuffer[obp++]=(char)0x02;
956
957 //mov eax,dword ptr[esp+4]
958 OpBuffer[obp++]=(char)0x8B;
959 OpBuffer[obp++]=(char)0x44;
960 OpBuffer[obp++]=(char)0x24;
961 OpBuffer[obp++]=(char)0x04;
962
963 //add esp,16
964 op_add_esp(16);
965}
966void fpu_cast_end(){
967 //sub esp,16
968 op_sub_esp(16);
969
970 //fldcw word ptr[esp]
971 OpBuffer[obp++]=(char)0xD9;
972 OpBuffer[obp++]=(char)0x2C;
973 OpBuffer[obp++]=(char)0x24;
974
975 //add esp,16
976 op_add_esp(16);
977}
978
979
980/////////////////////////////
981// 関数呼び出し
982/////////////////////////////
983
984void op_call(const UserProc *pUserProc){
985 OpBuffer[obp++]=(char)0xE8;
986 pobj_SubAddrSchedule->add(pUserProc,1);
987 pUserProc->Using();
988 obp+=sizeof(long);
989}
990void op_ret(){
991 OpBuffer[obp++]=(char)0xC3;
992}
Note: See TracBrowser for help on using the repository browser.