?? asm.c
字號:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Instruction Set */
#define LOADA 0X00
#define LOADB 0X01
#define LOADAI 0X02
#define LOADBI 0X03
#define NOP 0X04
#define STOREA 0X05
#define STOREB 0X06
#define ADDA 0X07
#define ADDB 0X08
#define COMPAI 0X09
#define COMPBI 0X0A
#define BLT 0X0B
#define BGT 0X0C
#define JUMP 0X0D
#define PRINTA 0X0E
#define BREAK 0x0F
#define MAX_LINE 1024
#define FALSE 0
#define TRUE (!FALSE)
#define ADDRESS_LENGTH 2
#define IMMEDIATE_LENGTH 1
#define ADDRESS_SPACE 65536
typedef enum {NONE, IMMEDIATE, ADDRESS} OPERAND_TYPE;
typedef int BOOL;
typedef struct
{
char* InstructionName;
OPERAND_TYPE Operand;
unsigned char MachineCode;
} INSTRUCTION;
static INSTRUCTION InstructionTable[] = {"LOADA", ADDRESS, LOADA,
"LOADB", ADDRESS, LOADB,
"LOADAI", IMMEDIATE, LOADAI,
"LOADBI", IMMEDIATE, LOADBI,
"NOP", NONE, NOP,
"STOREA", ADDRESS, STOREA,
"STOREB", ADDRESS, STOREB,
"ADDA", IMMEDIATE, ADDA,
"ADDB", IMMEDIATE, ADDB,
"COMPAI", IMMEDIATE, COMPAI,
"COMPBI", IMMEDIATE, COMPBI,
"BLT", ADDRESS, BLT,
"BGT", ADDRESS, BGT,
"JUMP", ADDRESS, JUMP,
"PRINTA", NONE, PRINTA,
"BREAK", NONE, BREAK };
typedef struct
{
char* Symbol;
int MemLocation;
int Line;
} SYMTAB_ENTRY;
typedef struct
{
SYMTAB_ENTRY Entry[1024];
int Count;
} SYM_T;
typedef struct
{
unsigned int RegA;
unsigned int RegB;
unsigned int PC;
int SR;
} REGISTERS;
INSTRUCTION* FindInstruction (char* Token)
{
int i = 0;
INSTRUCTION* Entry = NULL;
for (i = 0; i < sizeof InstructionTable / sizeof InstructionTable[0]; i++)
{
if (0 == strcmp (InstructionTable[i].InstructionName, Token))
{
Entry = &InstructionTable[i];
}
}
return Entry;
}
void InsertSymbol (char* Token, int MemLocation, SYM_T* SymTable)
{
SYMTAB_ENTRY* Entry;
Entry = &SymTable->Entry[SymTable->Count];
/* perform equivalent of strdup */
Entry->Symbol = malloc (strlen(Token) + 1);
if (NULL != Entry->Symbol)
{
strcpy (Entry->Symbol, Token);
}
SymTable->Count++;
Entry->MemLocation = MemLocation;
}
SYMTAB_ENTRY* FindSymbol (SYM_T* SymbolTable, char* Symbol)
{
int i = 0;
SYMTAB_ENTRY* Entry = NULL;
for (i=0; i< SymbolTable->Count; i++)
{
if (0 == strcmp (SymbolTable->Entry[i].Symbol, Symbol))
{
Entry = &SymbolTable->Entry[i];
break;
}
}
return Entry;
}
void ReadAssembly (char* Memory, int MemLocation, char* FileName)
{
FILE* Fp = NULL;
char Line[MAX_LINE] = {0};
int LineNo = 0;
char* Token = NULL;
char Seps[] = " ,\t\n";
SYM_T SymbolTable = {0};
BOOL IsOk = TRUE;
INSTRUCTION* Instruction = NULL;
SYMTAB_ENTRY* Symbol = NULL;
Fp = fopen ( FileName, "r" );
if ( NULL == Fp )
{
fprintf ( stderr, "cannot open file %s\n", FileName );
IsOk = FALSE;
}
/* go through each line */
while (IsOk && NULL != fgets (Line, MAX_LINE, Fp ))
{
LineNo++;
if ( '*' == Line[0] || '#' == Line[0] || '\n' == Line[0] )
{
/* discard comments */
continue;
}
/* parse the line */
Token = strtok (Line, Seps);
if (NULL == Token)
{
continue;
}
/* check to see if this a label, if so then add to the symbol table */
if (':' == Token[0])
{
Token++;
InsertSymbol (Token, MemLocation, &SymbolTable);
}
else
{
/* assemble the token into memory */
Instruction = FindInstruction (Token);
if (NULL == Instruction)
{
printf ("Error at line %d; Do not recognise instruction %s\n",
LineNo, Token);
IsOk = FALSE;
}
else
{
Memory [MemLocation] = Instruction->MachineCode;
MemLocation++;
if (IMMEDIATE == Instruction->Operand ||
ADDRESS == Instruction->Operand)
{
/* Get the operand */
Token = strtok (NULL, Seps);
if (NULL == Token)
{
printf("Error\n");
break;
}
}
/* We need to put one extra byte into memory */
if ( IMMEDIATE == Instruction->Operand)
{
Memory [MemLocation] = (unsigned char) strtol (Token, NULL, 16);
MemLocation++;
}
/* We need to put two extra bytes into memory */
if ( ADDRESS == Instruction->Operand)
{
Symbol = FindSymbol (&SymbolTable, Token);
/* make sure Symbol has already been defined */
if (NULL == Symbol)
{
printf ("Error at Line %d. Label %s not defined\n",
LineNo, Token);
IsOk = FALSE;
}
else
{
/* the machine is big endian, so store the high byte first */
Memory [MemLocation] = (Symbol->MemLocation >> 8) & 0xFF;
MemLocation++;
Memory [MemLocation] = Symbol->MemLocation &0xFF;
MemLocation++;
}
}
}
}
}
if (NULL != Fp)
fclose (Fp);
}
unsigned int LoadAddress (unsigned char* Location)
{
unsigned int Address;
Address = Location[0] << 8;
Address += Location[1];
return Address;
}
int Execute (unsigned char *Memory, REGISTERS* Reg)
{
unsigned int Address = 0;
unsigned int Instruction = 0;
unsigned int RegA = Reg->RegA;
unsigned int RegB = Reg->RegB;
unsigned int PC = Reg->PC;
int SR = Reg->SR;
unsigned char* Operand = NULL;
int Stop = FALSE;
Instruction = Memory[PC];
PC++;
Operand = &Memory[PC];
/* Decode the instruction instruction */
switch ( Instruction )
{
case LOADA:
Address = LoadAddress(Operand);
RegA = Memory[Address];
PC += ADDRESS_LENGTH;
break;
case LOADB:
Address = LoadAddress(Operand);
RegB = Memory[Address];
PC += ADDRESS_LENGTH;
break;
case LOADAI:
RegA = *Operand;
PC += IMMEDIATE_LENGTH;
break;
case LOADBI:
RegB = *Operand;
PC += IMMEDIATE_LENGTH;
break;
case NOP:
break;
case STOREA:
Address = LoadAddress(Operand);
Memory[Address] = RegA;
PC += ADDRESS_LENGTH;
break;
case STOREB:
Address = LoadAddress(Operand);
Memory[Address] = RegB;
PC += ADDRESS_LENGTH;
break;
case ADDA:
RegA += *Operand;
PC += IMMEDIATE_LENGTH;
break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -