Sei sulla pagina 1di 12

6/14/2015

OnlineMIPSassembler|AlanJ.Hogan

Alan
Hogan
at
MIPS Assembler v0.20

AlanHogan.com

AL AN H OGAN S P ROJEC T F O R C SE 2 30 A T AS U

SourceCode
Seenenough?UseProgram.

<?php
/*HOGAN,ALAN
*Project3
*CSE230AviralShrivastava
*alanhogan-at-gmaildotcom
*
*PLEASESEETHISFILEINACTIONathttp://alanhogan.com/asu/assembler.php
**/
/*Notes:
*
*post"input"/print$output
*
*ThisprogrammakesliberaluseofRegularExpressions.Ifyouareexamining
*oreditingthisfile,pleasefirstbecomefamiliarwithregularexpressions,
*(specifically,thePerl/PCREengine).
*
*Essentiallythisprogramworksbypreparing&transformingMIPSinstructions,
*whichinthisstageareeachrepresentedbyoneormoreLineobjects,
*asnecessaryandassigningthemlinenumbers,thenloopingthraughthem
*again,thistimeoutputtingthemandcalculatinganyaddresses
*neededforbranchandjumpinstructions.
*
*/
/********
Todo
Transformpseudobranches

-Operaproblemsresolved.Donotuse"&nbsp;"withintextareas.See:http://www.webdesignforums.
t=28727
*****/
$debug="";
define('ASSEMBLER_VERSION','0.20');
//Typesofinstructions
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.datadirectives
define('DATATYPE_ASCIIZ',25);
//Regexpatternforaregister
define('REGEX_REGISTER','((\$zero)|(\$[a-z][a-z0-9]))');
//Whereinstructionsstart
define('ADDRESS_START',0x00400000);//note,bydefaultthiswillprintinteger/decimalformat
//Datastoredhere
define('DATA_ADDRESS_START',0x00c00000);
functionmem_dechex($dec){
returnsprintf("%08x",$dec);
}
classLine{
public$inputLineNumber=0;
public$originalCode="";
http://alanhogan.com/asu/assembler.php?source

1/12

6/14/2015

OnlineMIPSassembler|AlanJ.Hogan

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).":<$this->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;//rightleft16
if($_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));//getridofhighbi
if($_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;<input:{$this->inputLineNumber}>{$this>originalCode}"."\n";

return$output;
}
}
functionregister($register){
//Returnsregisternumberfromname;e.g.$s1->17
switch($register){
case'$zero':
return0;break;
case'$gp':
return28;break;
case'$sp':
return29;break;
case'$fp':
return30;break;
http://alanhogan.com/asu/assembler.php?source

2/12

6/14/2015

OnlineMIPSassembler|AlanJ.Hogan

case'$ra':
return31;break;
case'$at':
return1;break;
default:
$matches=array();
if(preg_match('/^\$(?<letter>[a-z])(?
<number>\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']<8)
return$matches['number']+8;
if($matches['letter']=='s')
return$matches['number']+16;
if($matches['letter']=='k')
return$matches['number']+26;
if($matches['letter']=='t')
return$matches['number']+16;
}
}
}
functionfunctionType($name){
//Takesnameoffunctionandreturnstype
switch($name){
case"add":
case"and":
case"jr":
case"nor":
case"or":
case"slt":
case"sll":
case"srl":
case"sub":
case"subu":
case"addu":
returnTYPE_R;break;
case"addi":
case'addiu':
case"andi":
case"beq":
case"bne":
case"ori":
case"lw":
case"sb":
case"sw":
returnTYPE_I;break;
case"j":
case"jal":
returnTYPE_J;break;
case"syscall":
returnTYPE_SYSCALL;break;
default:
returnTYPE_INVALID;
}
}
functionr_hex($opcode,$rs,$rt,$rd,$shamt,$funct){
returnsprintf("%08x",bindec(
substr(sprintf("%06b",$opcode),-6)
.substr(sprintf("%05b",$rs),-5)
.substr(sprintf("%05b",$rt),-5)
.substr(sprintf("%05b",$rd),-5)
.substr(sprintf("%05b",$shamt),-5)
.substr(sprintf("%06b",$funct),-6)
));
}
functioni_hex($opcode,$rs,$rt,$immediate){
returnsprintf("%08x",bindec(
substr(sprintf("%06b",$opcode),-6)
.substr(sprintf("%05b",$rs),-5)
.substr(sprintf("%05b",$rt),-5)
.substr(sprintf("%016b",$immediate),-16)
));
}
functionj_hex($opcode,$address){
returnsprintf("%08x",bindec(
substr(sprintf("%06b",$opcode),-6)
.substr(sprintf("%026b",$address),-26)
));
}
functionr_reg_reg_reg_hex($opcode,$args,$funct){
$matches=array();
http://alanhogan.com/asu/assembler.php?source

3/12

6/14/2015

OnlineMIPSassembler|AlanJ.Hogan

preg_match('/\s*(?P<rd>'.REGEX_REGISTER.'),\s*(?
P<rs>'.REGEX_REGISTER.'),\s*(?
P<rt>'.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<rd>'.REGEX_REGISTER.'),\s*(?
P<rt>'.REGEX_REGISTER.'),\s*(?P<shamt>-?\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<rt>'.REGEX_REGISTER.'),\s+(?
P<rs>'.REGEX_REGISTER.'),\s+(?P<imm>[-]?\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
returni_hex($opcode,register($matches['rs']),register($matches['rt']),(int)$matches[
}
functioni_memop($opcode,$args){
global$debug;
$matches=array();
if(!preg_match('/\s*(?P<rt>'.REGEX_REGISTER.'),\s*(?P<imm>\d+)\((?
P<rs>'.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<rs>'.REGEX_REGISTER.'),\s*(?
P<rt>'.REGEX_REGISTER.'),?\s*(?P<label>[-_a-z09]+)\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':
http://alanhogan.com/asu/assembler.php?source

4/12

6/14/2015

OnlineMIPSassembler|AlanJ.Hogan

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<label>[-_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;
//accessor
publicfunctionbytesUsed(){returnself::$bytesUsed;}

publicstatic$dataAddressStart=DATA_ADDRESS_START;//todo:Isthisthebestwaytoimpleme
publicstatic$dataItems=array();

publicfunction__construct($type,$label,$data){//Constants:DATATYPE_XXX,e.g.DATATYPE_
$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;$words<($this>itemBytes>>2);$words++){
$output.=sprintf("%08x",$this>memAddress+4*$words).":\t";
for($i=0;$i<4;$i++){
if(($i+4*$words)>=strlen($this->data))
$output.="00";
else
$output.=sprintf("%02x",ord(substr($this>data,$i+4*$words,1)));
}
$output.="\t;\t".decode_printable_string(substr($thishttp://alanhogan.com/asu/assembler.php?source

5/12

6/14/2015

OnlineMIPSassembler|AlanJ.Hogan

>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,etc
functiondecode_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_walk
functiontrim_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,.datahandling
foreach($inArrayas$line){
$lineObj=newLine();
//Saveoriginalcode&linenumber
$lineObj->inputLineNumber=$counter;
$lineObj->originalCode=$line;

/////replacepseudocodewithrealinstructions
//litoaddi/ori
if(preg_match('/(?P<front>(\s*)(\w+:)?(\s*))li(\s+)(?
P<dest>\$[0-9a-zA-Z]+),(\s+)(?P<imm>-?\d+)(?P<end>(#|\s)+.*)?/iu',
$line,$matches
)===1){
$line="{$matches['front']}"
.($_POST['li_to_ori']?($matches['imm']
<0?'addi':'ori'):'addi')
."{$matches['dest']},\$zero,{$matches['imm']}
{$matches['end']}";
if($_POST['li_to_ori']&&$matches['imm']<0){
$debug.="Warning:Converting'li'to'ori'inthiscasewouldnothavethe"
."desiredeffect.Theimmediate"
."valueisnegative,butresultingregistervaluewillbeincorrect"
."duetodifferentbitstringlengthsandthefact'ori'doesnot"
."sign-extend.Wewilluse'addi'instead."
."Line:".$lineObj>inputLineNumber.",immediatevalue:{$matches['imm']}\n";
}
}
http://alanhogan.com/asu/assembler.php?source

6/12

6/14/2015

OnlineMIPSassembler|AlanJ.Hogan

//movetoadd
if(preg_match('/(?P<front>(\s*)(\w+:)?(\s*))move(\s+)(?
P<dest>\$[0-9a-zA-Z]+),\s*(?P<src>\$[0-9a-zA-Z]+)(?P<end>
(#|\s)+.*)?/iu',
$line,$matches
)===1){
$line="
{$matches['front']}add{$matches['dest']},\$zero,{$matches['src']}
{$matches['end']}";
}
//Todo:Branches

//Determinewhatkindofalineitis
if(preg_match('/^\s*((?P<label>[-_a-z0-9]+):\s*)?(?
P<instruction>(?P<function>[a-z]+)(?P<args>\s+([-_\$a-z0-9,\t]*)(?
P<address>\d+\('.REGEX_REGISTER.'\))?\s*)?)?(?P<comment>\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<label>[-_a-z0-9]+):\s*)?(?
P<instruction>(?P<function>la)(?P<args>\s+(?
P<register>'.REGEX_REGISTER.'),\s+(?P<datalabel>[-_a-z0-9]+)))(?
P<comment>\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";
http://alanhogan.com/asu/assembler.php?source

7/12

6/14/2015

OnlineMIPSassembler|AlanJ.Hogan

$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<label>[-_a-z0-9]+):\s*)(?
<type>\.asciiz\s+)"(?P<data>
[^"]+)"\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
//Nowdata
if(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();
?>

<title>OnlineMIPSassembler|AlanJ.Hogan</title>
<linkrel="stylesheet"type="text/css"href="mips.css"/>
<?php
printasuinclude_headToContentTitle('<strong>MIPSAssembler</strong>'
.'<spanstyle="fontweight:normal">v'.ASSEMBLER_VERSION.'</span>',
'AlanHogan&rsquo;sprojectforCSE230atASU');
?>
<?php
if(!array_key_exists('source',$_GET)){
?>
http://alanhogan.com/asu/assembler.php?source

8/12

6/14/2015

OnlineMIPSassembler|AlanJ.Hogan

<?phpif(strlen(trim($debug))){?>
<divclass="debugInfo"><?phpprintnl2br(htmlentities($debug));?></div>
<?php
}

if(strlen($output)){
print'<h3>AssemblerOutput</h3>
<divclass="code">'.nl2br(htmlentities($output)).'</div>'
.'<p>Youmaywanttopastetheassembleroutput,above,into<ahref="simulator.php">MIPh
theonlineMIPSsimulator</a>.MIPhpSisthesisterprojecttothisassembler.
</p>';
}
?>

<h3>MIPSinput</h3>
<p>PleaseenterMIPScodebelowtoseetheassembleroutput.AsubsetofMIPSisimplemented.(On
phpprint'<ahref="'.$_ENV['SCRIPT_URL'].'"title="ResettoAckermannfunction">Reset</a>';
>.)Commentsshouldstartwith#.Or,
view<?phpprint'<ahref="'.$_ENV['SCRIPT_URL'].'?
source"title="Viewsourcecodeforthispage">sourcecode</a>';?
>.Seealso:<ahref="simulator.php">MIPhpS,
theonlineMIPSsimulator</a>.</p>
<?phpprint'<formaction="'.$_ENV['SCRIPT_URL'].'"method="post">';?>
<textareaname="input"id="mips_input"style="width:99.8%;height:39em;">
<?php
print(
(strlen($input)>1)
?str_replace(array(/*'',*/"\t"),array(/*'&nbsp;',*/''),
htmlentities($input))
:str_replace(array(/*'',*/"\t"),array(/*'&nbsp;',*/''),
htmlentities(
'########################################################
#Ackermann\'sfunctionimplementationusingMIPSassembly
#Cinterface:
#intAckermannFunc(intm,intn)
########################################################
.text
.globlAckermannFunc
#Preconditions:
#1stparameter($a0)m
#2ndparameter($a1)n
#Postconditions:
#resultin($v0)=valueofA(m,n)
#wearegoingtouse$s0asatemporaryregisterstostoremsometimes
AckermannFunc:
#makespaceonstack
addi$sp,$sp,-8
#preserveregistersusedbythisfunction
sw$s0,4($sp)
#preservereturnaddress
sw$ra,0($sp)
#movetheparameterregisterstotemporary-no,onlywhennec.
LABEL_IF:#checkwhetherm==0
#ifnotthenbranchtoLABEL_ELSE_IF
bne$a0,$zero,LABEL_ELSE_IF
#codefor"result=n+1"
addi$v0,$a1,1
#jumptoLABEL_DONE
jLABEL_DONE
LABEL_ELSE_IF:
#checkwhethern==0
#ifnotthenbranchtoLABEL_ELSE
bne$a1,$zero,LABEL_ELSE
#needtocallA(m-1,1)
#soinitiate$a0,$a1withm-1and1
addi$a0,$a0,-1
addi$a1,$zero,1
#callAckermannFunc
jalAckermannFunc
#Returnvaluealreadyin$v0
http://alanhogan.com/asu/assembler.php?source

9/12

6/14/2015

OnlineMIPSassembler|AlanJ.Hogan

#jumptoLABEL_DONE
jLABEL_DONE
LABEL_ELSE:#Thisblockmaybeabittricky!
###################################
#Save"m"topreserveitforthesecondackermanncall
add$s0,$a0,$zero
#calltoacker(m,(n-1))
addi$a1,$a1,-1
jalAckermannFunc
#returnvaluewillbeusedverysoon!
#calltoacker(m-1,acker(m,(n-1)))
#Takethe"m"wesavedanddecrementittobethenew"m1":)
addi$a0,$s0,-1
add$a1,$v0,$zero
jalAckermannFunc
#jumptoLABEL_DONE
jLABEL_DONE
LABEL_DONE:
#ALREADYloadedthereturnvalueregister$v0withresult.
#restoreregistersusedbythisfunction
lw$s0,4($sp)
#restorereturnaddress
lw$ra,0($sp)
#restorestackpointer
addi$sp,$sp,8
#returnfromthisfunction
jr$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#makespaceonstack
sw$a0,0($sp)#preservefirstparameterm;
la$a0,msg1#loadaddressofmsg1
li$v0,4#loadthe"printstring"syscallnumber
syscall
lw$a0,0($sp)#loadfirstparameter=m
li$v0,1#loadthe"printinteger"syscallnumber
syscall
la$a0,comma#loadaddressofcomma
li$v0,4#loadthe"printstring"syscallnumber
syscall
move$a0,$a1#loadsecondparameter=n
li$v0,1#loadthe"printinteger"syscallnumber
syscall
la$a0,msg2#loadaddressofmsg2
li$v0,4#loadthe"printstring"syscallnumber
syscall
move$a0,$a2#loadthirdparameter=value
li$v0,1#loadthe"printinteger"syscallnumber
syscall
la$a0,endl#loadaddressofendl
li$v0,4#loadthe"printstring"syscallnumber
syscall
lw$a0,0($sp)#restorefirstparameter
http://alanhogan.com/asu/assembler.php?source

10/12

6/14/2015

OnlineMIPSassembler|AlanJ.Hogan

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)#preserveregisterss0throughs2
sw$s1,8($sp)#aswemayclobberitinmain
sw$s2,12($sp)
la$a0,prompt_m#firstparameter=prompt
li$v0,4#loadthe"printstring"syscallnumber
syscall
li$v0,5#loadthe"readinteger"syscallnumber
syscall
move$s0,$v0#m=s0=valuereturnedinv0
la$a0,prompt_n#secondparameter=prompt
li$v0,4#loadthe"printstring"syscallnumber
syscall
li$v0,5#loadthe"readinteger"syscallnumber
syscall
move$s1,$v0#n=s1=valuereturnedinv0
#Ackermannparametersetup
move$a0,$s0#firstparameter=m
move$a1,$s1#secondparameter=n
jalAckermannFunc
move$s2,$v0#Ackermannvalue=s2=valuereturned
#Printparametersetup
move$a0,$s0#firstparameter=m
move$a1,$s1#secondparameter=n
move$a2,$s2#
jalPrint
li$v0,0#returnvalueformain
lw$ra,0($sp)#restorereturnaddress
lw$s0,4($sp)#restoreregisterss0throughs3
lw$s1,8($sp)#beforeexitingmain
lw$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
?></textarea>
<br/>
<inputtype="checkbox"name="concise_off"<?
phpprint($_POST['concise_off']?'checked="checked"':'');?
>id="checkco"/>
<labelfor="checkco">Showblanklinesinoutput(ignoredbydefault)
</label>
<br/>
<inputtype="checkbox"name="debug_on"<?
phpprint($_POST['debug_on']?'checked="checked"':'');?
>id="checkdb"/>
<labelfor="checkdb">Verbose/debugmode</label>
<br/>
<inputtype="checkbox"name="li_to_ori"<?
phpprint($_POST['li_to_ori']?'checked="checked"':'');?
>id="check_ori"/>
<labelfor="check_ori">Use<code>ori</code>(not<code>addi</code>)for<code>li</code>
</label>
<br/>
http://alanhogan.com/asu/assembler.php?source

11/12

6/14/2015

OnlineMIPSassembler|AlanJ.Hogan

<inputtype="submit"name="assemble"value="Assemble"/>
</form>
<?php
}else{
?>
<h3>SourceCode</h3>
<p>Seenenough?<?
phpprint'<ahref="'.$_ENV['SCRIPT_URL'].'"title="Resettousablemode">UseProgram</a>';
>.</p>
<?php
print'<divstyle="border:1pxsolidblack;color:black;fontfamily:monaco,\'LucidaConsole\',monospace;background:#eeenone;padding:.6em;fontsize:105%;">'.highlight_file(__FILE__,true).'</div>';
}
printasuinclude_finished();
2015AlanJ.Hogan.

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

Contactmewithanyquestionsorcorrections.
NotethatthiswebsiteisthatofastudentandisnotanofficialASUproduction.

12/12