Beispiel #1
0
/*
 * This fucntion commit the second step of the program.
 * adding addresses to the three symbol tables.
 */
void secondStep()
{
	int memIdx = 0, labelAddress = 0;
	IC = 0; DC = 0; lineNumber = 0;
	QUE_setPtrToHead();
	while(strcmp(QUE_getLabel(),"NULL") != 0 && memIdx != -1)
	{
		if((labelAddress = getLabelAddress(QUE_getLabel(), labelTABLE)) != -1){
			memIdx = setLabelAddressInMemory(memIdx, labelAddress); /* update label address on memory*/
			QUE_setIsExtern(FALSE);
		}else{
			if(getLabelAddress(QUE_getLabel(), externTABLE) == -1)
				fprintf(stderr, "\n[line %d]: the label %s is not exists on file ",QUE_getLine(), QUE_getLabel());
			else{
				QUE_setIsExtern(TRUE);
				if(mem[QUE_getLine() + 1].fieldNum == 3 && mem[QUE_getLine() + 1].cml.label.addr == 0){
					mem[QUE_getLine() + 1].cml.label.era = 1;
					memIdx = QUE_getLine() + 2;
					QUE_setLine(QUE_getLine() + 1);
				}else{
					mem[QUE_getLine() + 2].cml.label.era = 1;
					memIdx = QUE_getLine() + 3;
					QUE_setLine(QUE_getLine() + 2);
				}
			}
		}
		QUE_getNext();
	}
	seAddressEnEX(entryTABLE);
	seAddressEnEX(externTABLE);
}
Beispiel #2
0
void Assembler::replaceLabels(){
	for(int i=0; i<alignedProgram.size(); i++){
		ProgramAtom atom = alignedProgram[i];
		if(atom.type == DIRECTIVE_INSTRUCTION){
		//Modified replacement
			string mnemonic = parser.extractFirstToken(atom.token);
			mnemonic = parser.toLower(mnemonic);
			bool isBranch = parser.tokenIsBranchInstructionName(mnemonic);
			bool isJump = parser.tokenIsJumpInstructionName(mnemonic);
			vector<string> instructionTokens = parser.tokenizeInstruction(atom.token);
			if(isBranch || isJump){
				string lastToken = instructionTokens[instructionTokens.size() - 1];
				if(!tokenIsInLabelDB(lastToken)){
					//EXCEPTION
					string error = ERROR_UNRECOGNIZED_LABEL;
					string offendingToken = lastToken;
					addException(AssemblerException(*atom.programLine, error, offendingToken));
					continue;
				}
				virtualAddr labelAddr = getLabelAddress(lastToken);
				virtualAddr instructionAddr = atom.addr;
				virtualAddr immediateVal = 0;
				if(isBranch){
					int32_t offset = labelAddr - instructionAddr - 4;	//pc still increments by 4 on branches
					offset >>= 2;
					immediateVal = (virtualAddr)offset;
				}else if(isJump){
					immediateVal = (labelAddr & 0x0FFFFFFF) >> 2;
				}
				string immediateString = parser.literals.getHexLiteralString(immediateVal);
				instructionTokens[instructionTokens.size() - 1] = immediateString;
				string newInstructionString = parser.combineInstructionTokens(instructionTokens);
				alignedProgram[i].token = newInstructionString;
			}else{
Beispiel #3
0
/*
Function that updates the label of the operand and it's value from table of signs
Input: 
	Operand struct
	RunStatus struct
	integer line Number
Output: True if it was able to update the address , FALSE otherwise
*/
int updateOperandLabelAddress(Operand *op, RunStatus *runStatus, int lineNum)
{
	int labelAddress;
	int dataAddress;
	unsigned int startValueData;

	if (op -> type == DIRECT) /*Label is taken from "tag table"*/
	{
		labelAddress = getLabelAddress(runStatus , op, 1);
		if (labelAddress == -1)
		{
			printf("ERROR: Line #%d, Label \"%s\" doesn't exist.\n", lineNum+1, op->str);
			runStatus -> errNum ++;
			return FALSE;
		}
	}
	else if ( op -> type == DYNAMIC)
	{
		labelAddress = getLabelAddress(runStatus , op, 0);

		if (labelAddress != -1) /*Parsing the dynamic range*/
		{
			/* Getting the value depends on cell type (data / command)*/
			if (runStatus -> finalLabelArray[labelAddress].isData)
			{
				dataAddress = runStatus -> finalLabelArray[labelAddress].memAddress - runStatus -> ic - FIRST_MEM_ADDR;
				startValueData = runStatus -> dataArray[dataAddress];
			}
			else
			{
				startValueData = getIntFromWord(runStatus -> finalLabelArray[labelAddress].word);
			}
			
			/* Parsing the specified range*/
			op -> val = getRequiredBitsFromLabel(startValueData, op -> up, op-> down);
		}
		else 
		{
			printf("ERROR: Line #%d, Label \"%s\" doesn't exist.\n", lineNum+1, op->str);
			runStatus -> errNum ++;
			return FALSE;
		}
	}
	
	return TRUE;
}
uint32_t handleBranch(Assembler *assembler, char **tokens) {
    CondCodes cond = mnemToCondCode(&tokens[0][1]);
    uint32_t address = isalpha(tokens[1][0]) ?
                       //address starts with a char so is a label
                       getLabelAddress(assembler, tokens[1]) :
                       //else it's a numeric value
                       getValue(tokens[1]);
    uint32_t offset = calcOffset(assembler, address, true);

    return genBranch(cond, offset);
}
Beispiel #5
0
/**
 * This function checks if the label stands on standards. if it doesn't - the function prints error note.
 * ln - the last line.
 * returns TRUE if the label is fine, otherwisr - FALSE.
 */
int isLabelOK(line ln)
{
	int flag = 0;
	if(strcmp(ln.word, "NULL") == 0)
		return FALSE;
	if(!isalpha(ln.word[0]))
		fprintf(stderr, "\n[line %d]: First character of label must be a letter", lineNumber);
	else flag++;
	if(strlen(ln.word) > maxStringLength)
		fprintf(stderr, "\n[line %d]: The label length is longer than the maximum available (%d)",lineNumber, maxStringLength);
	else flag++;
	if(isRegister(ln.word))
		fprintf(stderr, "\n[line %d]: The name of the label %s is equal to register. YOU CANNOT USE THIS NAME", lineNumber , ln.word);
	else flag++;
	if(getLabelAddress(ln.word, labelTABLE) != -1)
		fprintf(stderr, "\n[line %d]: The label %s is already exists on program", lineNumber ,ln.word);
	else flag++;
	if(flag == 4)
		return TRUE;
	return FALSE;
}
Beispiel #6
0
//Post-processing
void Assembler::pseudoInstructionReplace(){
	for(int i=0; i<alignedProgram.size(); i++){
		ProgramAtom atom = alignedProgram[i];
		string line = atom.token;
		if(atom.type == DIRECTIVE_INSTRUCTION){
			string mnemonic = parser.extractFirstToken(atom.token);
			mnemonic = parser.toLower(mnemonic);
			if(parser.tokenIsPseudoInstructionName(mnemonic)){
				int pseudoInstructionNumber = parser.getPseudoInstructionNameNumber(mnemonic);
				int numInsertedLines = parser.getPseudoInstructionNumberOfLinesToInsert(mnemonic);
				vector<string> tokenizedInstruction = parser.tokenizeInstruction(line);
				switch(pseudoInstructionNumber){
					//TODO: add exceptions for incorrect number of instruction arguments
					case 0:
						{
							//bge	$reg1, $reg2, label
							if(tokenizedInstruction.size() != 4){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string labelName = tokenizedInstruction[3];
							string line1 = "slt\t$at, " + registerName1 + ", " + registerName2;
							string line2 = "beq\t$at, $zero, " + labelName;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
					case 1:
						{
							//bgt	$reg1, $reg2, label
							if(tokenizedInstruction.size() != 4){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string labelName = tokenizedInstruction[3];
							string line1 = "slt\t$at, " + registerName2 + ", " + registerName1;
							string line2 = "bne\t$at, $zero, " + labelName;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
					case 2:
						{
							//ble	$reg1, $reg2, label
							if(tokenizedInstruction.size() != 4){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string labelName = tokenizedInstruction[3];
							string line1 = "slt\t$at, " + registerName2 + ", " + registerName1;
							string line2 = "beq\t$at, $zero, " + labelName;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;

						}
						break;
					case 3:
						{
							//blt	$reg1, $reg2, label
							if(tokenizedInstruction.size() != 4){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string labelName = tokenizedInstruction[3];
							string line1 = "slt\t$at, " + registerName1 + ", " + registerName2;
							string line2 = "bne\t$at, $zero, " + labelName;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
					case 4:
						{
							//clear	$reg
							if(tokenizedInstruction.size() != 2){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string line1 = "add\t" + registerName1 + ", $zero, $zero";
							alignedProgram[i].token = line1;
						}
						break;
					case 5:
						{
							//la	$reg, label
							if(tokenizedInstruction.size() != 3){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string labelName = tokenizedInstruction[2];
							if(!tokenIsInLabelDB(labelName)){
								//EXCEPTION
								string error = ERROR_UNRECOGNIZED_LABEL;
								string offendingToken = labelName;
								addException(AssemblerException(*atom.programLine, error, offendingToken));
								continue;
							}
							virtualAddr labelAddr = getLabelAddress(labelName);
							virtualAddr msb = labelAddr >> (SIZE_BITS_VIRTUAL_ADDR / 2);
							virtualAddr lsb = labelAddr & 0x0000FFFF;
							string msbHex = parser.literals.getHexLiteralString(msb);
							string lsbHex = parser.literals.getHexLiteralString(lsb);
							string registerName = tokenizedInstruction[1];
							string line1 = "lui\t" + registerName + ", " + msbHex;
							string line2 = "ori\t" + registerName + ", " + registerName + ", " + lsbHex;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
					case 6:
						{
							//li	$reg, imm
							if(tokenizedInstruction.size() != 3){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string immediateString = tokenizedInstruction[2];

							//EXCEPTION
							//TODO
							uint32_t immediateVal;
							try{
								immediateVal = parser.literals.getLiteralValue(immediateString);
							}catch(InvalidTokenException &e){
								string error = ERROR_INVALID_IMMEDIATE_LI;
								string offendingToken = immediateString;
								addException(AssemblerException(*atom.programLine, error, offendingToken));
								continue;
							}
							virtualAddr msb = immediateVal >> (SIZE_BITS_WORD / 2);
							virtualAddr lsb = immediateVal & 0x0000FFFF;
							string msbHex = parser.literals.getHexLiteralString(msb);
							string lsbHex = parser.literals.getHexLiteralString(lsb);
							string registerName = tokenizedInstruction[1];
							string line1 = "lui\t" + registerName + ", " + msbHex;
							string line2 = "ori\t" + registerName + ", " + registerName + ", " + lsbHex;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;

						}
						break;
					case 7:
						{
							//move	$reg1, $reg2
							if(tokenizedInstruction.size() != 3){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string line1 = "add\t" + registerName1 + ", " + registerName2 + ", $zero";
							alignedProgram[i].token = line1;
						}
						break;
					case 8:
						{
							//neg	$reg1, $reg2
							if(tokenizedInstruction.size() != 3){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string line1 = "sub\t" + registerName1 + ", $zero, " + registerName2;
							alignedProgram[i].token = line1;
						}
						break;
					case 9:
						{
							//not	$reg1, $reg2
							if(tokenizedInstruction.size() != 3){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string line1 = "addi\t" + registerName1 + ", $zero, -1";
							string line2 = "xor\t" + registerName1 + ", " + registerName1 + "," + registerName2;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
						/*
						PUSH:
						sub $sp,$sp,4
						sw $t2,($sp)

						POP:
						lw $t2,($sp)
						addiu $sp,$sp,4
						*/
					case 10:
						{
							//push	$reg
							if(tokenizedInstruction.size() != 2){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string line1 = "sub\t$sp, $sp, 4";
							string line2 = "sw\t" + registerName1 + ", 0($sp)";
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
					case 11:
						{
							//pop	$reg
							if(tokenizedInstruction.size() != 2){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string line1 = "lw\t" + registerName1 + ", 0($sp)";
							string line2 = "addi\t$sp, $sp, 4";
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
					case 12:
						{
							//peak	$reg
							if(tokenizedInstruction.size() != 2){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName = tokenizedInstruction[1];
							string line = "lw\t" + registerName + ", 0($sp)";
							alignedProgram[i].token = line;
						}
						break;
					case 13:
						{
							//rem

						}
						break;
					case 14:
						{
							//sge

						}
						break;
					case 15:
						{
							//sgt

						}
						break;
					default:

						break;
				}
				i += numInsertedLines;
			}else{

			}
		}else{

		}
	}
}