?? assembler.cpp
字號(hào):
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "assembler.h"
#include "asmutils.h"
#include "memory.h"
#include "error.h"
#include "opcodes.h"
#include "pxdScriptHeaders.h"
/* ****************** PROTOTYPES ****************** */
void AssembleFunction();
void AssembleProgram();
/* ****************** STRUCTS ******************* */
typedef struct LABELADDRESS {
char *label;
unsigned int offset;
struct LABELADDRESS *next;
} LABELADDRESS, LABELPLUG;
/* ******************* GLOBALS ******************** */
unsigned int curCodeArraySize = 0; // Utility variable for the growing byte code array
// Where to add the next byte code.
unsigned int codeposition = 0;
// Our final output file with the binary code.
static FILE *emitFILE;
// The input text file with the symbolic byte code
FILE *sourceFILE;
// This is the (single) growing array of byte codes
unsigned char *bytecode = NULL;
// A linked list of unfilled "offset holes" in the code segment.
LABELPLUG *labelPlugs = NULL;
// A linked list of the labels and their corresponding offsets in the code segment.
unsigned int numLabels = 0;
LABELADDRESS *asmLabels = NULL;
// A linked list of the constants in the programs and functions
unsigned int nextconst = 0;
unsigned int numConsts = 0;
CONSTANT *asmConstants = NULL;
// The name of the function or program we are currently assembling.
// This is used to prefix all label names so we get truely unique names
// (remember label names are otherwise only unique within the function or
// program in which they are used)
char *currentName = NULL;
/* *************** UTILITY FUNCTIONS ************** */
// Check that we have 'nrBytes' bytes of free space in the code segment
void checkSpace(int nrBytes) {
unsigned char *temp = NULL;
// Grow code segment if there isn't already room
if (codeposition+nrBytes >= curCodeArraySize) {
temp = (unsigned char *)Malloc(2*curCodeArraySize);
memcpy(temp, bytecode, curCodeArraySize);
bytecode = temp;
curCodeArraySize *= 2;
}
}
/* Add a plug to the list of label plugs at the current code position */
void addPlug(char *label) {
LABELPLUG *plug = NULL;
// Generate unique name for this label.
char *uniqueName = strconcat(currentName, label);
plug = NEW(LABELPLUG);
plug->label = uniqueName; // which label?
plug->offset = codeposition; // where in the code should its address be placed?
// link it in
plug->next = labelPlugs;
labelPlugs = plug;
// Make sure there is space:
checkSpace(4);
// increase code position to make room for address later when we fill the plugs
codeposition += sizeof(unsigned int);
}
/* Search the list of labels and returns the address */
unsigned int getAddressOfLabel(char *uniqueLabel) {
LABELADDRESS *labels = asmLabels;
while (labels != NULL) {
if (strcmp(labels->label, uniqueLabel) == 0)
return labels->offset;
labels = labels->next;
}
// Error - label was not found!
printf("Internal assembler error - label '%s' is referenced but not defined\n", uniqueLabel);
return 0;
}
/* Run through the list of plugs, look up their labels addresses and insert into byte code buffer */
void fillPlugs() {
unsigned int address = 0;
LABELPLUG *plugs = labelPlugs;
// Loop over all plugs
while (plugs != NULL) {
// look up address of labels (by now it MUST be defined)
address = getAddressOfLabel(plugs->label);
// fill address into the code segment
*((unsigned int*)&bytecode[plugs->offset]) = address;
plugs = plugs->next;
}
}
// Add the byte code 'bc' to the code segment.
void addCode(char bc) {
// Make sure there is room
checkSpace(sizeof(char));
// add code
bytecode[codeposition] = bc;
codeposition++;
}
/* save a 32bit integer in the code segment */
void addIndex(unsigned int index) {
// Make sure there is room
checkSpace(sizeof(unsigned int));
// add 32bit index to code segment
*((unsigned int*)&bytecode[codeposition]) = index;
// increase code pointer
codeposition += sizeof(unsigned int);
}
/* save a 16bit integer in the code segment */
void addInt16(short unsigned int index) {
// Make sure there is room
checkSpace(sizeof(short unsigned int));
// add 16bit integer to code segment
*((short unsigned int*)&bytecode[codeposition]) = index;
// increase code pointer
codeposition += sizeof(short unsigned int);
}
// Is a given token a label? It is if its name ends with a ':'
int isLabel(char *token) {
if (token == NULL) return 0;
return (token[strlen(token)-1] == ':');
}
/* We must prefix the names of the labels because they are only
unique in their own scopes and we do global assembling of labels
and constants */
void setLabelPosition(char *name) {
LABELADDRESS *newLabel = NULL;
LABELADDRESS **pList = NULL;
// generate unique name for label
char *uniqueName = strconcat(currentName, name);
// Add the label
newLabel = NEW(LABELADDRESS);
newLabel->label = uniqueName;
newLabel->offset = codeposition;
newLabel->next = NULL;
// Link it into the global list of labels.
pList = &asmLabels;
while (*pList) {
pList = &(*pList)->next;
}
*pList = newLabel;
}
/* Get the number of a certain int constant in the constant pool */
unsigned int getIntConstNr(int val) {
CONSTANT *temp = asmConstants;
CONSTANT *newConst = NULL;
CONSTANT **pList;
// first try to find label in list
while (temp != NULL) {
if (temp->type == INT_CONST && temp->val.intval == val)
return temp->nr;
temp = temp->next;
}
// Constant has not been defined yet, so we create a new one.
newConst = NEW(CONSTANT);
newConst->nr = nextconst++;
newConst->type = INT_CONST;
newConst->val.intval = val;
newConst->next = NULL;
// Link it in
pList = &asmConstants;
while (*pList) {
pList = &(*pList)->next;
}
*pList = newConst;
return newConst->nr;
}
unsigned int getStrConstNr(char *val) {
CONSTANT *temp = asmConstants;
CONSTANT *newConst = NULL;
CONSTANT **pList;
// first try to find label in list
while (temp != NULL) {
if (temp->type == ZSTRING_CONST && strcmp(temp->val.str, val) == 0)
return temp->nr;
temp = temp->next;
}
// Constant has not been defined yet, so we create a new one.
newConst = NEW(CONSTANT);
newConst->nr = nextconst++;
newConst->type = ZSTRING_CONST;
newConst->val.str = val;
newConst->next = NULL;
// Link it in
pList = &asmConstants;
while (*pList) {
pList = &(*pList)->next;
}
*pList = newConst;
return newConst->nr;
}
/* The most boring function in the assembler */
void asmCODE(char *token) {
int intparam;
char *param;
if (strcmp(token, "nop") == 0) {
addCode(nopC);
} else
if (strcmp(token, "imul") == 0) {
addCode(imulC);
} else
if (strcmp(token, "ineg") == 0) {
addCode(inegC);
} else
if (strcmp(token, "irem") == 0) {
addCode(iremC);
} else
if (strcmp(token, "isub") == 0) {
addCode(isubC);
} else
if (strcmp(token, "idiv") == 0) {
addCode(idivC);
} else
if (strcmp(token, "iadd") == 0) {
addCode(iaddC);
} else
if (strcmp(token, "aadd") == 0) {
addCode(aaddC);
} else
if (strcmp(token, "goto") == 0) {
addCode(gotoC);
param = getToken(sourceFILE);
addPlug(param); /* label */
} else
if (strcmp(token, "ifeq") == 0) {
addCode(ifeqC);
param = getToken(sourceFILE);
addPlug(param); /* label */
} else
if (strcmp(token, "ifne") == 0) {
addCode(ifneC);
param = getToken(sourceFILE);
addPlug(param); /* label */
} else
if (strcmp(token, "if_acmpeq") == 0) {
addCode(if_acmpeqC);
param = getToken(sourceFILE);
addPlug(param); /* label */
} else
if (strcmp(token, "if_acmpne") == 0) {
addCode(if_acmpneC);
param = getToken(sourceFILE);
addPlug(param); /* label */
} else
if (strcmp(token, "if_icmpeq") == 0) {
addCode(if_icmpeqC);
param = getToken(sourceFILE);
addPlug(param); /* label */
} else
if (strcmp(token, "if_icmpgt") == 0) {
addCode(if_icmpgtC);
param = getToken(sourceFILE);
addPlug(param); /* label */
} else
if (strcmp(token, "if_icmplt") == 0) {
addCode(if_icmpltC);
param = getToken(sourceFILE);
addPlug(param); /* label */
} else
if (strcmp(token, "if_icmple") == 0) {
addCode(if_icmpleC);
param = getToken(sourceFILE);
addPlug(param); /* label */
} else
if (strcmp(token, "if_icmpge") == 0) {
addCode(if_icmpgeC);
param = getToken(sourceFILE);
addPlug(param); /* label */
} else
if (strcmp(token, "if_icmpne") == 0) {
addCode(if_icmpneC);
param = getToken(sourceFILE);
addPlug(param); /* label */
} else
if (strcmp(token, "ireturn") == 0) {
addCode(ireturnC);
} else
if (strcmp(token, "areturn") == 0) {
addCode(areturnC);
} else
if (strcmp(token, "return") == 0) {
addCode(returnC);
} else
if (strcmp(token, "aload") == 0) {
addCode(aloadC);
intparam = atoi(getToken(sourceFILE));
addInt16(intparam);
} else
if (strcmp(token, "astore") == 0) {
addCode(astoreC);
intparam = atoi(getToken(sourceFILE));
addInt16(intparam);
} else
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -