Skip to content

Instantly share code, notes, and snippets.

@sencagri
Last active May 1, 2018 18:16
Show Gist options
  • Save sencagri/882256222422425dbc8d7c13b3ef1031 to your computer and use it in GitHub Desktop.
Save sencagri/882256222422425dbc8d7c13b3ef1031 to your computer and use it in GitHub Desktop.
assembler
import re
import os
from instructionSet import instructionSet
# program counter
pc = 100
# jump list
colonList = list()
# var list
varList = list()
# param list
param = list()
# result list
output = list()
varOutput = list()
# delimiter characters used for splitting line
delimiter = "(,)|( )"
# global değişken olan program counter değerini fonksiyonlar içersinde arttırmak için kullanılan fonksiyon
def incrementPC():
global pc
pc = pc + 4
# verilen sayıyı istenilen bit genişliğinde ikinin complementi şekline getiren fonksiyon
def to_twoscomplement(bits, value):
value = int(value)
if value < 0:
value = ( 1<<bits ) + value
formatstring = '{:0%ib}' % bits
return formatstring.format(value)
def decodeParameters(stringPart):
# split edimiş instruction içerisinde instruction harici item ler üzerinde gez
for par in stringPart[1:]:
# register value
par = par.rstrip()
# R veya immediate value değerini al
if str.startswith(par, "R") or str.startswith(par, "#"):
paramDigit = par[1:];
param.append(paramDigit)
continue
# eğer ldr veya str gibi memory operasyonları yapacak ise köşeli parantezlerden parse yap
if str.startswith(par, "["):
pb = str.find(par, "[") + len("[")
par = par[pb:]
if str.startswith(par, "R"):
pb = str.find(par, "R") + 1
par = par[pb:]
param.append(par)
continue
if str.endswith(par, "]"):
pe = str.find(par, "]")
par = par[:pe]
findVar = [item for item in varList if item[0] == par]
if len(findVar) > 0:
findVar = findVar[0]
pcOfVar = findVar[1]
param.append(pcOfVar)
continue
# parametre bir jump list içeriyor mu kontrol et
isVar = [item for item in colonList if item[0] == par]
if len(isVar) > 0:
# this is a 1 parameter instruction
isVar = isVar[0][1]
param.append(isVar)
def extractVars_asm2bin(inData):
global pc
prevLine = inData[0]
globalname = ""
globalFound = False
colonFound = False
# tüm satırları gezmeye başla
for line in inData:
line = str(line)
# halen uzunluğu 0 olan satır varsa pas geç
if len(line.strip()) == 0:
continue
# eğer satır comment satırı ise pas geç
if line[0] == ";":
continue
# programın başlayacağı nokta globalname değişkeninin içerisinde tutuluyor eğer bulunur ise program counter arttırılmayacak
if str.find(line,globalname):
globalFound = True
# global başlama noktası mı diye kontrol et
if str.find(line, ".global") > -1:
posg = str.index(line, ".global") + len(".global")
globalname = line[posg:]
# eğer satır değişken tanıtılmak için kullanılmış ise prevLine değişkeninin içersinde hangi değişken olduğunun değeri tutuluyor oradan değişken adını al
# program counter değerini de yanına koy varlist listesinin içine append et
# ek olarak birden fazla değer memory ye eklenmiş olabileceğinden kaç tane eklenmiş ise program counter değerini o kadar arttır
if str.find(line, ".word") > -1:
pos = str.index(prevLine, ":")
varName = prevLine[:pos]
varList.append([varName, pc])
pos =str.find(line, ".word") + len(".word")
values = line[pos:]
values = str.replace(values, "\n", "")
values = re.split(", | ", values)
values = list(filter(None, values))
values = list(values)
for val in values:
varOutput.append(to_twoscomplement(32, int(val)) + os.linesep)
lenVal = len(values) -1
pc += lenVal*4
# eğer sıçrama noktası bulundu ise colonlist listesine ekle
if str.find(line, ":") > -1:
pos = str.find(line, ":")
colName = line[:pos]
colonList.append([colName, pc])
# colon buldu ise program counter değerini arttırma çünkü bir instruction değil
if str.find(line, ":") > -1:
colonFound = True
if globalFound and colonFound == False and str.find(line, globalname) == -1:
incrementPC()
colonFound = False
prevLine = line
# tüm işlemler bittiğinde program counter değerini tekrardan 100 yap
pc = 100
def dec_asm2bin(inData):
for line in inData:
processLine_asm2bin(line)
def b_br_ins(insBinary):
par = to_twoscomplement(26, param[0])
return insBinary.replace("mmmmmmmmmmmmmmmmmmmmmmmmmm", par)
def com_ins(insBinary):
val = int(param[1]) - pc -4
par = to_twoscomplement(19,val)
insBinary = insBinary.replace("mmmmmmmmmmmmmmmmmmm", par)
par = param[0]
par = to_twoscomplement(5, par)
insBinary = insBinary.replace("nnnnn",par)
return insBinary
def addi_addiu_ins(insBinary):
par = to_twoscomplement(5,param[0])
insBinary = insBinary.replace("nnnnn", par)
par = to_twoscomplement(5,param[1])
insBinary = insBinary.replace("mmmmm", par)
par = to_twoscomplement(12,param[2])
insBinary = insBinary.replace("dddddddddddd", par)
return insBinary
def cmp_ins(insBinary):
par = to_twoscomplement(5, param[0])
insBinary = insBinary.replace("nnnnn", par)
par = to_twoscomplement(6, param[1])
insBinary = insBinary.replace("dddddd", par)
return insBinary
def ldr_str_ins(insBinary):
par = to_twoscomplement(12, param[2])
insBinary = insBinary.replace("mmmmmmmmmmmm", par)
par = to_twoscomplement(5, param[1])
insBinary = insBinary.replace("nnnnn", par)
par = to_twoscomplement(5, param[0])
insBinary = insBinary.replace("ddddd", par)
return insBinary
def three_ins(insBinary):
par = to_twoscomplement(5, param[1])
insBinary = insBinary.replace("nnnnn", par)
par = to_twoscomplement(5, param[0])
insBinary = insBinary.replace("mmmmm", par)
par = to_twoscomplement(5, param[2])
insBinary = insBinary.replace("ddddd", par)
return insBinary
def str_ins(insBinary):
par = to_twoscomplement(5, param[0])
insBinary = insBinary.replace("mmmmm", par)
par = to_twoscomplement(5, param[1])
insBinary = insBinary.replace("nnnnn", par)
return insBinary
def putParams(insName, insBinary):
# buradaki tüm fonksiyonlar alınan parametreleri yerine koyuyor
if insName == "B" or insName == "BR":
insBinary = b_br_ins(insBinary)
elif insName == "EQ" or insName == "NE" or insName == "GE" or insName == "GT" or insName == "LE" or insName =="LT":
insBinary = com_ins(insBinary)
elif insName == "ADDI" or insName == "ADDIU":
insBinary = addi_addiu_ins(insBinary)
elif insName == "CMP":
insBinary = cmp_ins(insBinary)
elif insName == "LDR" or insName == "STR":
insBinary = ldr_str_ins(insBinary)
elif insName == "STR":
insBinary = str_ins(insBinary)
else:
insBinary = three_ins(insBinary)
return insBinary
def processLine_asm2bin(line):
endPos = len(line)
if endPos > 0:
# check if comment added
commentIndex = str.find(line, ";")
if commentIndex > -1:
endPos = commentIndex
# copy only to the semicolon pos
stringPart = line[:endPos]
if len(stringPart) > 0:
# check if line is jump point, if so add colonName to list then exit
colonIndex = str.find(stringPart, ":")
if colonIndex > 0:
colonName = stringPart[:colonIndex]
#colonList.append([colonName, pc])
return
# split by delimiter character
stringPart = stringPart.replace("\n", "")
#stringPart = [s.strip(',') for s in stringPart]
stringPart = re.split(delimiter, stringPart)
stringPart = list(filter(None, stringPart))
# search first string in instruction list
candidateInst = stringPart[0]
candidateRes = [item for item in instructionSet if item[0] == candidateInst]
# we found the instruction
if len(candidateRes) > 0:
insBinary = candidateRes[0][1]
insName = candidateRes[0][0]
paramSize = 0;
decodeParameters(stringPart)
if len(param) > 0:
insBinary = putParams(insName, insBinary)
param.clear()
incrementPC()
output.append(insBinary + os.linesep)
# programın başlangıç noktası indata parametresi ile kullanıcının yazdığı veriler geliyor,
def runAssembler(inData):
# gelen veriyi satır satır hale getir
inData = inData.splitlines()
# satırlar arsında boşluk var ise temizle
inData = list(filter(None, inData))
extractVars_asm2bin(inData)
# decode etme işlemine başla
dec_asm2bin(inData)
return output + varOutput
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment