如何从C中间代码生成代码到其对应的目标文件?

时间:2015-05-18 09:47:59

标签: compiler-construction code-generation javacc

我编写了一个编译器,我可以将c程序编译到中间代码。我已经使用了javacc工具。

如何为它生成MachineCode? 我有一个程序用于各种指令集,其寻址模式,指令格式但我无法理解它? 任何人都可以帮我解释一下代码吗? 另外我不知道如何从中间代码运行到机器代码?

以下是该计划:

#include<stdio.h> 
#include<stdlib.h>
#define MAXCODE 100 
typedef unsigned char USC; 
USC code[MAXCODE]; 
USC data[4];
short int dataIdx;
unsigned int cc=0;
unsigned int startCount,endCount;


//do effective Address Calculation
void doEAC(short int mod,short int rm)
 {
   dataIdx=0;
   switch(mod)
   {
        case 3:
        break;
        case 0:
        if(rm == 6) //110 - direct address
            {
              code[cc++] = data[dataIdx++];
              code[cc++] = data[dataIdx++];
            }  
           break;
        case 1:
        code[cc++] = data[dataIdx++];
        break;
        case 2:
        code[cc++] = data[dataIdx++];
        code[cc++] = data[dataIdx++];
        break;
    }
  }

//register or memory to or from register
void moveRM2R(USC d,USC w,USC mod,USC reg, USC rm)
{
 USC c;
 // 1 0 0 0 1 0  
 c = 0x88;       // why this value?
 c  = c | (d << 1);  //why this value?
 c  = c | w;      //kya aayegi value?
 code[cc++] = c;  //why this value?
 c = 0x0;  //why this value?
 c = c | (mod << 6);  //why this value?
 c = c | (reg << 3);  //why this value?
 c = c | rm ;   //why this value?
 code[cc++] = c;   //why this value?
 doEAC(mod,rm);  //how they calculated above
}
//Immediate register or memory
void moveImm2RM(USC w, USC mod, USC rm) 
{
 USC c;
 c = 0xc6;
 c = c | w;
 code[cc++] = c;
 c = 0x0;
 c = c | (mod << 6);
 c = c | rm;
 code[cc++] = c;
 doEAC(mod,rm);
 code[cc++] = data[dataIdx++];
 if(w==1)
    code[cc++] = data[dataIdx++];
}

//move immediate to register
void moveImm2R(USC w,USC reg)
{
 USC c;
 c = 0xb0;
 c = c | (w << 3);
 c = c | reg;
 code[cc++]=c;
 dataIdx = 0;
 code[cc++] = data[dataIdx++];
 if(w==1)
 code[cc++] = data[dataIdx++];
 }  

//Move Memory to accumulator
void moveMem2Acc(USC w) 
{
 USC c;
 c = 0xb0;
 c = c | w;
 code[cc++] = c;
 dataIdx = 0;
 code[cc++] = data[dataIdx++];
 code[cc++] = data[dataIdx++];
}   

//Move accumulator to memory
void moveAcc2Mem(USC w)
{
 USC c;
 c = 0xb2;
 c = c | w;
 code[cc++] = c;
 dataIdx = 0;
 code[cc++] = data[dataIdx++];
 code[cc++] = data[dataIdx++];
}    

//Move register or memory to segment register
void moveRM2SegR(USC mod, USC sreg, USC rm)
{
 USC c;
 c = 0x8e;
 code[cc++] = c;
 c = 0x0;
 c = c | (mod << 6);
 c = c | (sreg << 3);
 c = c | rm;
 code[cc++]=c;
 doEAC(mod,rm);
}   

 //Move  segment register to register or memory 
 void moveSegR2RM(USC mod, USC sreg, USC rm)
 {
  USC c;
  c = 0x8c;
  code[cc++] = c;
  c = 0x0;
  c = c | (mod << 6);
  c = c | (sreg << 3);
  c = c | rm;
  code[cc++]=c;
  doEAC(mod,rm); 
}   

 //push data on reg or memory  on stack
 void pushRM(USC mod, USC rm)
 {
   USC c;
   c = 0xff;
   code[cc++] = c;
   c = 0x00;
   c =  c | (mod << 6);
   c =  c | (0x06 << 3); //mod 110 rm
   c =  c | rm;
   code[cc++] = c;
   doEAC(mod,rm);
 }

  //push data on reg on stack
  void pushR(USC reg)
 {
   USC c;
   c = 0x40;
   c =  c | reg;
   code[cc++] = c; 
 }
  //push segment reg on stack
  void pushSR(USC sreg)
 {
   USC c;
   c = 0x0;
   c =  c | (sreg << 3);
   c =  c | 0x6;        //000 reg 110
   code[cc++] = c;
 }

  //pop stack into reg or mem
  //1000 1111 - mod 000 r/m
  void pop2RM(USC mod, USC rm)
  {
   USC c;
   c = 0x8f;
   code[cc++] = c;
   c = 0x0;
   c = c | (mod << 6);
   c = c | rm;
   code[cc++] = c;
   doEAC(mod,rm); 
  }

  //pop into a reg
 //0101 1reg
 void pop2R(USC reg)
{ 
 USC c;
 c = 0x58;
 c = c | reg;
 code[cc++] = c;
}

 //pop into a seg reg
//000 sreg 111
void pop2SR(USC sreg)
{
 USC c;
 c = 0x0;
 c = c | (sreg << 3);
 c = c | 0x07;
 code[cc++] = c;
} 

//exchange register or memory with register
// 1000 011w - mod reg rm
void exchangeRM2R(USC w, USC mod, USC reg, USC rm)
{
 USC c;
 c = 0x86;
 c = c | w;
 code[cc++] = c;
 c = 0x0;
 c = c | (mod << 6);
 c = c | (reg << 3);
 c = c | reg;
 code[cc++] = c;
 doEAC(mod,rm);
}

void exchangeR2Acc(USC reg)
{
 USC c;
 c = 0x90;
 c = c | reg;
 code[cc++] = c;
}
void printCode()
{
  int i;
  for(i=startCount;i<endCount;i++)
  printf("\t%0x\t",code[i]);
  printf("\n");
}
int main()
{ 
 int i;
 USC d,w,mod,reg,sreg,rm,data1,data2,addrlow,addrhigh;

   //register or memory to or from register 
  //void moveRM2R(USC d,USC w,USC mod,USC reg, USC rm)
startCount = cc;//what is it doing?
printf("\nMOV CX,AX Move AX register to CX register\n"); 
d = 0x01; //why this value?   memory mode with 8 bit displacement
w = 0x01; //why this value?   memory mode with 8 bit displacement
mod = 0x11; //why this value? Register Mode(No Displacement)
rm = 0x01;  //why this value? memory mode with 8 bit displacement
reg = 0x00;  //why this value?  memory mode with no displacement
moveRM2R(d,w,mod,reg,rm);
endCount = cc;
printCode();

//Move Immediate data to register or memory
//void moveImm2RM(USC w, USC mod, USC rm, USC data1, USC data2)
startCount = cc;
printf("\nMOV DX, #4050 - move an immediate data to DX reg\n"); 
w = 0x01;
mod = 0x11;
rm = 0x03;
data[0] = 0x40;
data[1]= 0x50;
moveImm2RM(w, mod, rm);
endCount=cc;
printCode();

//move immediate to register
//void moveImm2R(USC w,USC reg)
printf("\nMov SI, #4050 - Move a immediate number to SI index reg\n");
startCount = cc;
w = 1;
reg = 0x06;
data[0] = 0x40;
data[1] = 0x50;
moveImm2R(w,reg);
endCount=cc;
printCode();

printf("\nMov AX, 2025 - Move the contents of the memory 2025 into    accumulator\n");
startCount = cc;
w = 1;
//Move Memory to accumulator
//void moveMem2Acc(USC w)
w = 0x01;
data[0] = 0x25;    //addrlow
data[1] = 0x20;    //addrhigh;
moveMem2Acc(w);
endCount=cc;
printCode();

//Move accumulator to memory
//void moveAcc2Mem(USC w)
printf("\nMove the content of acc to a mem addressed by 2025\n");
startCount = cc;
w = 0x01;
data[0] = 0x25;    //addrlow
data[1] = 0x20;    //addrhigh;
moveAcc2Mem(w);
endCount=cc;
printCode();

//Move register or memory to segment register
//void moveRM2SegR(USC mod, USC sreg, USC rm)
printf("\nMov SS, BX - Move the contents of BX register to DS\n");
startCount=cc;
mod = 0x03;
sreg = 0x02;
rm = 0x03;
moveRM2SegR(mod,sreg,rm);
endCount=cc;
printCode();

//Move  segment register to register or memory 
//void moveSegR2RM(USC mod, USC sreg, USC rm)
printf("\nMov BX,SS - Move the contents of SS to BX\n");
startCount = cc;
mod = 0x03;
sreg = 0x02;
rm = 0x03;
moveSegR2RM(mod,sreg,rm);
endCount=cc;
printCode();

//push data on reg or memory  on stack
//void pushRM(USC mod, USC rm)
printf("\nPush SI - Push SI contents onto stack\n");
startCount = cc;
mod = 0x03;
rm = 0x06;
pushRM(mod,rm);
endCount=cc;
printCode();

//push data on reg on stack
//void pushR(USC reg)
printf("\nPush DI - Push DI contents onto Stack\n");
startCount = cc;
reg = 0x07;
pushR(reg);
endCount=cc;
printCode();

//push segment reg on stack
//void pushSR(USC sreg)
printf("\nPush DS - Push Segment Register onto stack\n");
startCount = cc;
sreg = 0x03;
pushSR(sreg);
endCount=cc;
printCode();

//pop stack into reg or mem
//1000 1111 - mod 000 r/m
//void pop2RM(USC mod, USC rm)
printf("\nPop SI- Pop the top of the stack into SI reg\n");
startCount = cc;
mod = 0x03;
rm = 0x06;
pop2RM(mod,rm);
endCount=cc;
printCode();

//pop into a reg
//0101 1reg
//void pop2R(USC reg)
printf("\nPop DX - Pop the top into DX reg\n");
startCount=cc;
reg = 0x2;
pop2R(reg);
endCount=cc;
printCode();

//pop into a seg reg
//000 sreg 111
//void pop2SR(USC sreg)
printf("\nPop ES - pop the top contents into ES reg\n");
startCount = cc;
sreg = 0x03;
pop2SR(sreg);
endCount=cc;
printCode();

startCount = cc;
printf("\nXCNG DI -Exchange Register DI with Accumulator\n");
reg = 0x07;
exchangeR2Acc(reg);
endCount = cc;
printCode();

//exchange register or memory with register
// 1000 011w - mod reg rm
//void exchangeRM2R(USC w, USC mod, USC reg, USC rm)
printf("\nEXNG SI, DI -Exchange Register DI and SI\n");
startCount = cc;
w = 0x1;
mod = 0x03;
reg = 0x6;
rm  = 0x7;
exchangeRM2R(w,mod,reg,rm);
endCount=cc;
printCode();
return 1;

}

0 个答案:

没有答案