online mips assembler _ alan j

12
A H a A MIPS Assembler v0.20 ALAN HOGAN’S PROJECT FOR CSE 230 AT ASU Source Code Seen enough? Use Program . <?php /* HOGAN, ALAN * Project 3 * CSE 230 Aviral Shrivastava * alan hogan -at- gmail dot com * * PLEASE SEE THIS FILE IN ACTION at http://alanhogan.com/asu/assembler.php **/ /* Notes: * * post "input" / print $output * * This program makes liberal use of Regular Expressions. If you are examining * or editing this file, please first become familiar with regular expressions, * (specifically, the Perl/PCRE engine). * * Essentially this program works by preparing & transforming MIPS instructions, * which in this stage are each represented by one or more Line objects, * as necessary and assigning them line numbers, then looping thraugh them * again, this time outputting them and calculating any addresses * needed for branch and jump instructions. * */ /******** Todo Transform pseudo branches - Opera problems resolved. Do not use "&nbsp;" within textareas. See: http://www.webdesignfo t=28727 *****/ $debug = ""; define('ASSEMBLER_VERSION', '0.20'); //Types of instructions define('TYPE_UNASSIGNED', 0); define('TYPE_COMMENT', 1); define('TYPE_R', 2); define('TYPE_I', 3); define('TYPE_LA_FIRST', 3.1); define('TYPE_LA_THIRD', 3.2); define('TYPE_J', 4); define('TYPE_SYSCALL', 5); define('TYPE_LABEL', 6); define('TYPE_INVALID',-1); //For .data directives define('DATATYPE_ASCIIZ', 25); //Regex pattern for a register define('REGEX_REGISTER', '((\$zero)|(\$[a-z][a-z0-9]))'); //Where instructions start define('ADDRESS_START',0x00400000); //note, by default this will print integer/decimal forma //Data stored here define('DATA_ADDRESS_START',0x00c00000); function mem_dechex($dec){ return sprintf("%08x", $dec); } class Line { public $inputLineNumber = 0; public $originalCode = "";

Upload: salloum18

Post on 16-Dec-2015

4 views

Category:

Documents


0 download

TRANSCRIPT

  • 6/14/2015 OnlineMIPSassembler|AlanJ.Hogan

    http://alanhogan.com/asu/assembler.php?source 1/12

    AlanHoganat

    AlanHogan.com

    MIPS Assembler v0.20ALAN HOGANS PROJECT FOR CSE 230 AT ASU

    SourceCode

    Seenenough?UseProgram.

  • 6/14/2015 OnlineMIPSassembler|AlanJ.Hogan

    http://alanhogan.com/asu/assembler.php?source 2/12

    public$lineType=TYPE_UNASSIGNED;public$label="";public$function="";public$args="";public$memAddress=0;publicfunctionassemble(){global$debug;$output="";if($this->lineType==TYPE_LABEL){$output.=mem_dechex($this->memAddress).":label>";}elseif($this->lineType==TYPE_R||$this->lineType==TYPE_I||$this->lineType==TYPE_J||$this->lineType==TYPE_SYSCALL||$this->lineType==TYPE_LA_FIRST||$this->lineType==TYPE_LA_THIRD){$output.="\t".mem_dechex($this->memAddress).":";}

    if($this->lineType==TYPE_R){$output.=r_handler($this->function,$this->args);}

    if($this->lineType==TYPE_I){$output.=i_handler($this->function,$this->args,$this->memAddress);}

    if($this->lineType==TYPE_J){$output.=j_handler($this->function,$this->args,$this->memAddress);}if($this->lineType==TYPE_SYSCALL){if($this->function=='syscall')$output.="0000000c";}if($this->lineType==TYPE_LA_FIRST){$tempAddr=get_address_of_data(trim($this->args));if($_POST['debug_on'])$debug.="1[".$this->args."]Addressofdata:$tempAddror".dechex($tempAddr)."\n";//$tempAddr=floor((1.0*$tempAddr)/(2^16));//rightleft16$tempAddr=$tempAddr>>16;//rightleft16if($_POST['debug_on'])$debug.="1*Leftsixteenbitsofdata:".dechex($tempAddr)."\n";$output.=i_hex(0x9,0,register($this->function),$tempAddr);}if($this->lineType==TYPE_LA_THIRD){$tempAddr=get_address_of_data(trim($this->args));if($_POST['debug_on'])$debug.="3[".$this->args."]Addressofdata:$tempAddror".dechex($tempAddr)."\n";$tempAddr=(int)hexdec(substr(sprintf("%04x",$tempAddr),4,4));//getridofhighbitsif($_POST['debug_on'])$debug.="3*Rightsixteenbitsofdata:$tempAddror".dechex($tempAddr)."\n"$output.=i_hex(0x9,register($this->function),register($this->function),$tempAddr);}if($this->lineType==TYPE_INVALID){$output.=";UNRECOGNIZEDINSTRUCTION";}if($_POST['concise_off']||($this->lineType!=TYPE_UNASSIGNED&&$this->lineType!=TYPE_COMMENT))$output.="\t;inputLineNumber}>{$this->originalCode}"."\n";return$output;}}

    functionregister($register){//Returnsregisternumberfromname;e.g.$s1->17switch($register){case'$zero':return0;break;case'$gp':return28;break;case'$sp':return29;break;case'$fp':return30;break;

  • 6/14/2015 OnlineMIPSassembler|AlanJ.Hogan

    http://alanhogan.com/asu/assembler.php?source 3/12

    case'$ra':return31;break;case'$at':return1;break;default:$matches=array();if(preg_match('/^\$(?[a-z])(?\d)$/i',$register,$matches)){if($matches['letter']=='v')return$matches['number']+2;if($matches['letter']=='a')return$matches['number']+4;if($matches['letter']=='t'&&(int)$matches['number']

  • 6/14/2015 OnlineMIPSassembler|AlanJ.Hogan

    http://alanhogan.com/asu/assembler.php?source 4/12

    preg_match('/\s*(?P'.REGEX_REGISTER.'),\s*(?P'.REGEX_REGISTER.'),\s*(?P'.REGEX_REGISTER.')\s*/i',$args,$matches);returnr_hex($opcode,register($matches['rs']),register($matches['rt']),register($matches}functionr_shift_hex($opcode,$args,$funct){$matches=array();preg_match('/\s*(?P'.REGEX_REGISTER.'),\s*(?P'.REGEX_REGISTER.'),\s*(?P-?\d+)\s*/i',$args,$matches);returnr_hex($opcode,0,register($matches['rt']),register($matches['rd']),(int)$matches}functionr_handler($function,$args){switch($function){case'add':returnr_reg_reg_reg_hex(0,$args,0x20);break;case'sub':returnr_reg_reg_reg_hex(0,$args,0x22);break;case'subu':returnr_reg_reg_reg_hex(0,$args,0x23);break;case'and':returnr_reg_reg_reg_hex(0,$args,0x24);break;case'nor':returnr_reg_reg_reg_hex(0,$args,0x27);break;case'or':returnr_reg_reg_reg_hex(0,$args,0x25);break;case'slt':returnr_reg_reg_reg_hex(0,$args,0x2a);break;case'jr':returnr_hex(0,register($args),0,0,0,0x08);break;case'sll':returnr_shift_hex(0,$args,0x0);break;case'srl':returnr_shift_hex(0,$args,0x2);break;default:return";UNSUPPORTEDRFORMATINSTRUCTION'$function$args'";}}

    functioni_reg_reg_imm_hex($opcode,$args){global$debug;$matches=array();if(!preg_match('/\s*(?P'.REGEX_REGISTER.'),\s+(?P'.REGEX_REGISTER.'),\s+(?P[-]?\d+)\s*/i',$args,$matches))$debug.="Parseerror,i_reg_reg_imm_hex:opcode$opcodeargs$args\n";//$debug.="i_reg_reg...says:opcode$opcode,args$args,rs{$matches['rs']},rt{$matches['rt']},imm{$matches['imm']}\ni_hex".i_hex($opcode,register($matches['rs']),register($matches['rt']),(int)$matches['imm'])."\n";//debugreturni_hex($opcode,register($matches['rs']),register($matches['rt']),(int)$matches[}functioni_memop($opcode,$args){global$debug;$matches=array();if(!preg_match('/\s*(?P'.REGEX_REGISTER.'),\s*(?P\d+)\((?P'.REGEX_REGISTER.')\)\s*/i',$args,$matches))$debug.="Parseerror,i_memop:$opcode$args\n";returni_hex($opcode,register($matches['rs']),register($matches['rt']),(int)$matches[}

    functioni_branch($opcode,$args,$myAddr){global$debug;$matches=array();if(!preg_match('/\s*(?P'.REGEX_REGISTER.'),\s*(?P'.REGEX_REGISTER.'),?\s*(?P[-_a-z0-9]+)\s*/i',$args,$matches))$debug.="Parseerror,i_branch:$opcode$args\n";$relAddr=(get_address_from_label($matches['label'])-($myAddr+4))/4;if($relAddr==0)return";COULDNOTFINDLABEL'{$matches['label']}'";returni_hex($opcode,register($matches['rs']),register($matches['rt']),$relAddr);}functioni_handler($function,$args,$myAddr){switch($function){case'addi':returni_reg_reg_imm_hex(0x8,$args);break;case'addiu':returni_reg_reg_imm_hex(0x9,$args);break;case'andi':returni_reg_reg_imm_hex(0xc,$args);break;case'ori':returni_reg_reg_imm_hex(0xd,$args);break;case'sw':returni_memop(0x2b,$args);break;case'lw':returni_memop(0x23,$args);break;case'lbu':returni_memop(0x24,$args);break;case'lhu':returni_memop(0x25,$args);break;case'sb':

  • 6/14/2015 OnlineMIPSassembler|AlanJ.Hogan

    http://alanhogan.com/asu/assembler.php?source 5/12

    returni_memop(0x28,$args);break;case'sh':returni_memop(0x29,$args);break;case'beq':returni_branch(0x4,$args,$myAddr);break;case'bne':returni_branch(0x5,$args,$myAddr);break;default:return";UNSUPPORTEDIFORMATINSTRUCTION'$function$args'";}}

    functionj_handler($function,$args,$myAddr){global$debug;$opcode;switch($function){case'j':$opcode=0x2;break;case'jal':$opcode=0x3;break;default:return";UNSUPPORTEDJFORMATINSTRUCTION'$function$args'";}$matches=array();if(!preg_match('/\s*(?P[-_a-z0-9]+)\s*/i',$args,$matches))$debug.="Parseerror,j_mama:$opcode$args\n";$jAddr=get_address_from_label($matches['label'])/4;if($jAddr==0)return";COULDNOTFINDLABEL'{$matches['label']}'";returnj_hex($opcode,$jAddr);}

    functionget_address_from_label($label){global$debug,$lines;foreach($linesas$lineObj){if($lineObj->label==$label)return$lineObj->memAddress;}$debug.="Couldnotfindlabel'$label'\n";return0;}

    ///////Functionsfor.asciiz,"lalabelname"...

    classData{public$data,$memAddress,$type,$label,$itemBytes;privatestatic$bytesUsed=0;//accessorpublicfunctionbytesUsed(){returnself::$bytesUsed;}publicstatic$dataAddressStart=DATA_ADDRESS_START;//todo:Isthisthebestwaytoimplementthis?publicstatic$dataItems=array();publicfunction__construct($type,$label,$data){//Constants:DATATYPE_XXX,e.g.DATATYPE_ASCIIZ$this->type=$type;$this->label=$label;$this->data=$data=make_string_printable($data);switch($type){caseDATATYPE_ASCIIZ:$this->memAddress=self::$dataAddressStart+self::$bytesUsed;$bytes=strlen($data)+1;while($bytes%4)$bytes++;self::$bytesUsed+=$bytes;$this->itemBytes=$bytes;break;}self::$dataItems[]=$this;}publicfunctionassemble(){if($this->type==DATATYPE_ASCIIZ){$output=";".$this->label."\n";for($words=0;$wordsitemBytes>>2);$words++){$output.=sprintf("%08x",$this->memAddress+4*$words).":\t";for($i=0;$i=strlen($this->data))$output.="00";else$output.=sprintf("%02x",ord(substr($this->data,$i+4*$words,1)));}$output.="\t;\t".decode_printable_string(substr($this-

  • 6/14/2015 OnlineMIPSassembler|AlanJ.Hogan

    http://alanhogan.com/asu/assembler.php?source 6/12

    >data,$words*4,4));//\t{$this->data}:$output.="\n";}return$output;}}}//Data

    functionget_address_of_data($label){global$debug;$dataItems=Data::$dataItems;foreach($dataItemsas$dataObj){if($dataObj->label==$label)return$dataObj->memAddress;}$debug.="Couldnotfinddatalabeledas'$label'\n";return0;}

    //Forasciiz...convert\t,\n,etcfunctiondecode_printable_string($string){returnstr_replace(array("\n","\t","\r"),array('\n','\t','\r'),$string);}functionmake_string_printable($string){returnstr_replace(array('\n','\t','\r'),array("\n","\t","\r"),$string);}

    //Forarray_walkfunctiontrim_self(&$string){$string=trim($string);}

    /////////////////////////////////////actualparsing/////////////////////////////////////

    if(strlen($_POST['input'])){//Processinput!$input=$_POST['input'];if(get_magic_quotes_gpc()){$input=stripslashes($input);}//converttoarroyoflines$inArray=explode("\n",$input);array_walk($inArray,'trim_self');////ConverttoanarrayofLineobjects//$lines=array();$dataItems=array();$matches=array();$counter=0;//linesininputcode$memAddress=ADDRESS_START;/////BEGINFOREACH:Lineobjectcreation,pseudocodetranslation,.datahandlingforeach($inArrayas$line){$lineObj=newLine();//Saveoriginalcode&linenumber$lineObj->inputLineNumber=$counter;$lineObj->originalCode=$line;/////replacepseudocodewithrealinstructions//litoaddi/oriif(preg_match('/(?P(\s*)(\w+:)?(\s*))li(\s+)(?P\$[0-9a-zA-Z]+),(\s+)(?P-?\d+)(?P(#|\s)+.*)?/iu',$line,$matches)===1){$line="{$matches['front']}".($_POST['li_to_ori']?($matches['imm']

  • 6/14/2015 OnlineMIPSassembler|AlanJ.Hogan

    http://alanhogan.com/asu/assembler.php?source 7/12

    //movetoaddif(preg_match('/(?P(\s*)(\w+:)?(\s*))move(\s+)(?P\$[0-9a-zA-Z]+),\s*(?P\$[0-9a-zA-Z]+)(?P(#|\s)+.*)?/iu',$line,$matches)===1){$line="{$matches['front']}add{$matches['dest']},\$zero,{$matches['src']}{$matches['end']}";}//Todo:Branches//Determinewhatkindofalineitisif(preg_match('/^\s*((?P[-_a-z0-9]+):\s*)?(?P(?P[a-z]+)(?P\s+([-_\$a-z0-9,\t]*)(?P\d+\('.REGEX_REGISTER.'\))?\s*)?)?(?P\s*#.*)?\s*$/i',$line,$matches)){if(array_key_exists('label',$matches)&&strlen($matches['label'])){if(array_key_exists('function',$matches)&&strlen($matches['function'])){//Labelandinstruction$tempObj=newLine();$tempObj->label=$matches['label'];$tempObj->inputLineNumber=$lineObj->inputLineNumber;$tempObj->originalCode=$lineObj->originalCode;$tempObj->memAddress=$lineObj->memAddress=$memAddress;$tempObj->lineType=TYPE_LABEL;$lines[]=$tempObj;}else{//Justalabel$lineObj->label=$matches['label'];$lineObj->memAddress=$memAddress;$lineObj->lineType=TYPE_LABEL;}}if(array_key_exists('function',$matches)&&strlen($matches['function'])){$lineObj->memAddress=$memAddress;$lineObj->function=$matches['function'];$lineObj->lineType=functionType($matches['function']);if($_POST['debug_on'])$debug.="\$lineObj->lineType:{$lineObj->lineType}($line)\n";if(array_key_exists('args',$matches)&&strlen($matches['args'])){$lineObj->args=trim($matches['args']);}//Correctionsforla.//Essentiallyturnintothreeinstructions:for//la$t0dataname//itbecomes://addiu$t0,$zero,[hi16bitsofdataaddr]//sll$t0,$t0,16//addiu$t0,$t0,[low16bitsofaddr]$tmatches;if(preg_match('/^\s*((?P[-_a-z0-9]+):\s*)?(?P(?Pla)(?P\s+(?P'.REGEX_REGISTER.'),\s+(?P[-_a-z0-9]+)))(?P\s*#.*)?\s*$/i',$line,$tmatches)){$tempObj=newLine();$secondObj=newLine();//$tempObj->label=$matches['label'];$tempObj->inputLineNumber=$secondObj->inputLineNumber=$lineObj->inputLineNumber;$tempObj->originalCode=$secondObj->originalCode=$lineObj->originalCode;$tempObj->memAddress=$memAddress;$secondObj->memAddress=$memAddress+4;$lineObj->memAddress=$memAddress+8;$memAddress+=8;$tempObj->lineType=TYPE_LA_FIRST;$tempObj->function=trim($tmatches['register']);//NOTE:Notstandard!!$tempObj->args=trim($tmatches['datalabel']);$secondObj->lineType=TYPE_R;$secondObj->function='sll';$secondObj->args=$tmatches['register'].",".$tmatches['register'].",16";

  • 6/14/2015 OnlineMIPSassembler|AlanJ.Hogan

    http://alanhogan.com/asu/assembler.php?source 8/12

    $lineObj->lineType=TYPE_LA_THIRD;$lineObj->function=trim($tmatches['register']);//NOTE:Notstandard!!$lineObj->args=trim($tmatches['datalabel']);$lines[]=$tempObj;$lines[]=$secondObj;}}

    }elseif(preg_match('/^\s*\.[a-z]+(\s+[-_a-z0-9]+)?\s*$/i',$line,$matches)){//failedpreg_matchforfunctions...type?continue;}elseif(preg_match('/^\s*((?P[-_a-z0-9]+):\s*)(?\.asciiz\s+)"(?P[^"]+)"\s*$/i',$line,$matches)){//failedpreg_matchforfunctions&type...data?$lineObj->lineType=DATATYPE_ASCIIZ;$dataItems[]=newData(DATATYPE_ASCIIZ,$matches['label'],$matches['data']);continue;//todo:f'real?}else{//failedpreg_match$lineObj->lineType=TYPE_INVALID;}if($lineObj->lineType==TYPE_R||$lineObj->lineType==TYPE_I||$lineObj->lineType==TYPE_LA_THIRD||$lineObj->lineType==TYPE_J||$lineObj->lineType==TYPE_SYSCALL){$memAddress+=4;}$lines[]=$lineObj;$counter++;//todo:check}//foreach$inArrayas$line//LoopthruandprinteachLine,appropriatelycalculating//addressesforjumpthrugetLineNumber()function$output="";reset($lines);foreach($linesas$line2)$output.=$line2->assemble();//theyhavetheirownnewlines

    //Nowdataif(count(Data::$dataItems)){$output.=";\n;\tDATAINMEMORY\n";foreach(Data::$dataItemsas$dataItem){$output.=$dataItem->assemble();}}

    //END}

    /*Compactform;samecode.For"Panribbon"*/if(!function_exists('get_ancestral_directory_called')){functionget_ancestral_directory_called($dirName,$descendent='.'){$folder=explode(DIRECTORY_SEPARATOR,realpath($descendent));$path='';for($i=0;isset($folder{$path.=$folder[$i];$path.=DIRECTORY_SEPARATOR;if($folder[$i]==$dirName)break;}return$path

    //ASUInclude(ASU/Schooltheme)require_onceget_ancestral_directory_called('asu').'asuinclude.php';printasuinclude_top();?>OnlineMIPSassembler|AlanJ.Hogan

  • 6/14/2015 OnlineMIPSassembler|AlanJ.Hogan

    http://alanhogan.com/asu/assembler.php?source 9/12

    MIPSinputPleaseenterMIPScodebelowtoseetheassembleroutput.AsubsetofMIPSisimplemented.(OnlyguaranteedtoworkwiththeAckermannfunction:phpprint'Reset';>.)Commentsshouldstartwith#.Or,view

  • 6/14/2015 OnlineMIPSassembler|AlanJ.Hogan

    http://alanhogan.com/asu/assembler.php?source 10/12

    #jumptoLABEL_DONEjLABEL_DONE

    LABEL_ELSE:#Thisblockmaybeabittricky!###################################

    #Save"m"topreserveitforthesecondackermanncalladd$s0,$a0,$zero

    #calltoacker(m,(n-1))addi$a1,$a1,-1jalAckermannFunc#returnvaluewillbeusedverysoon!

    #calltoacker(m-1,acker(m,(n-1)))#Takethe"m"wesavedanddecrementittobethenew"m-1":)addi$a0,$s0,-1add$a1,$v0,$zerojalAckermannFunc

    #jumptoLABEL_DONEjLABEL_DONE

    LABEL_DONE:#ALREADYloadedthereturnvalueregister$v0withresult.

    #restoreregistersusedbythisfunctionlw$s0,4($sp)#restorereturnaddresslw$ra,0($sp)#restorestackpointeraddi$sp,$sp,8

    #returnfromthisfunctionjr$ra

    .text

    .globlPrint

    #print:Printamessage.#Preconditions:#1stparameter(a0)m#2ndparameter(a1)n#3rdparameter(a2)value#Postconditions:#Printsthe"Ackermann(m,n)=value"onthescreen.

    Print:

    addi$sp,$sp,-4#makespaceonstacksw$a0,0($sp)#preservefirstparameterm;

    la$a0,msg1#loadaddressofmsg1li$v0,4#loadthe"printstring"syscallnumbersyscall

    lw$a0,0($sp)#loadfirstparameter=mli$v0,1#loadthe"printinteger"syscallnumbersyscall

    la$a0,comma#loadaddressofcommali$v0,4#loadthe"printstring"syscallnumbersyscall

    move$a0,$a1#loadsecondparameter=nli$v0,1#loadthe"printinteger"syscallnumbersyscall

    la$a0,msg2#loadaddressofmsg2li$v0,4#loadthe"printstring"syscallnumbersyscall

    move$a0,$a2#loadthirdparameter=valueli$v0,1#loadthe"printinteger"syscallnumbersyscall

    la$a0,endl#loadaddressofendlli$v0,4#loadthe"printstring"syscallnumbersyscall

    lw$a0,0($sp)#restorefirstparameter

  • 6/14/2015 OnlineMIPSassembler|AlanJ.Hogan

    http://alanhogan.com/asu/assembler.php?source 11/12

    addi$sp,$sp,4#restorestackpointer

    jr$ra#return

    .globlmain

    #main:Testthetowersfunction.

    main:addi$sp,$sp,-16#makespaceonstack.sw$ra,0($sp)#preservereturnaddress.sw$s0,4($sp)#preserveregisterss0throughs2sw$s1,8($sp)#aswemayclobberitinmainsw$s2,12($sp)

    la$a0,prompt_m#firstparameter=promptli$v0,4#loadthe"printstring"syscallnumbersyscall

    li$v0,5#loadthe"readinteger"syscallnumbersyscallmove$s0,$v0#m=s0=valuereturnedinv0

    la$a0,prompt_n#secondparameter=promptli$v0,4#loadthe"printstring"syscallnumbersyscall

    li$v0,5#loadthe"readinteger"syscallnumbersyscallmove$s1,$v0#n=s1=valuereturnedinv0

    #Ackermannparametersetupmove$a0,$s0#firstparameter=mmove$a1,$s1#secondparameter=n

    jalAckermannFuncmove$s2,$v0#Ackermannvalue=s2=valuereturned

    #Printparametersetupmove$a0,$s0#firstparameter=mmove$a1,$s1#secondparameter=nmove$a2,$s2#

    jalPrintli$v0,0#returnvalueformain

    lw$ra,0($sp)#restorereturnaddresslw$s0,4($sp)#restoreregisterss0throughs3lw$s1,8($sp)#beforeexitingmainlw$s2,12($sp)addi$sp,$sp,16#restorestackpointer

    jr$ra#returntoOperatingSystem

    .data

    prompt_m:.asciiz"m="prompt_n:.asciiz"n="msg1:.asciiz"Ackermann("msg2:.asciiz")="comma:.asciiz","endl:.asciiz"\n"')));//ternary/print?>

  • 6/14/2015 OnlineMIPSassembler|AlanJ.Hogan

    http://alanhogan.com/asu/assembler.php?source 12/12

    SourceCodeSeenenough?