source: dev/BasicCompiler32/op32_main.cpp@ 122

Last change on this file since 122 was 97, checked in by dai_9181, 18 years ago

関数の戻り値オブジェクトのメンバ・メソッドを一時オブジェクトを介さずに参照できるようにした。

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