package Ġven us . linker Ċ Ċ import Ġven us . assembler . Assembler Error Ċ import Ġven us . ris cv . Memory Segments Ċ import Ġven us . ris cv . Program Ċ import Ġven us . ris cv . inst s . dsl . re loc ators . Re locator Ċ Ċ /** Ċ Ġ* ĠDescri bes Ġhow Ġto Ġre locate Ġa Ġgiven Ġinstructions Ċ Ġ* Ċ Ġ* Ġ@ param Ġre locator Ġthe Ġre locator Ġto Ġuse Ċ Ġ* Ġ@ param Ġlabel Ġthe Ġtarget Ġlabel Ċ Ġ* Ġ@ param Ġoffset Ġthe Ġbyte Ġoffset Ġthe Ġinstruction Ġis Ġat Ċ Ġ*/ Ċ data Ġclass ĠRe location Info ( val Ġre locator : ĠRe locator , Ġval Ġoffset : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlabel : ĠString , Ġval Ġlabel Offset : ĠInt ) Ċ Ċ /** Ċ Ġ* ĠDescri bes Ġhow Ġto Ġre locate Ġdata Ġbytes Ċ Ġ* Ċ Ġ* Ġ@ param Ġoffset Ġthe Ġbyte Ġoffset Ġin Ġthe Ġdata Ġsegment Ċ Ġ* Ġ@ param Ġlabel Ġthe Ġtarget Ġlabel Ċ Ġ*/ Ċ data Ġclass ĠData Re location Info ( val Ġoffset : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlabel : ĠString , Ġval Ġlabel Offset : ĠInt ) Ċ Ċ /** Ċ Ġ* ĠA Ġsingleton Ġwhich Ġlinks Ġa Ġlist Ġof Ġprograms Ġinto Ġone Ġprogram . Ċ Ġ* Ċ Ġ* Ġ@ see ĠLinked Program Ċ Ġ*/ Ċ object ĠLink er Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠLinks Ġtogether Ġthe Ġgiven Ġlist Ġof Ġprograms . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThis Ġconsists Ġof Ġseveral Ġsteps : ĊĠĠĠĠ Ġ* ĠĠĠĠĠ Ġ- ĠCollect Ġall Ġthe Ġlabels Ġin Ġeach Ġprogram . ĊĠĠĠĠ Ġ* ĠĠĠĠĠ Ġ- ĠKeep Ġtrack Ġof Ġall Ġthe Ġinstructions Ġwhich Ġneed Ġto Ġbe Ġre located . ĊĠĠĠĠ Ġ* ĠĠĠĠĠ Ġ- ĠAppend Ġall Ġthe Ġinstructions Ġtogether . ĊĠĠĠĠ Ġ* ĠĠĠĠĠ Ġ- ĠAppend Ġall Ġof Ġthe Ġdebugging Ġinfo Ġtogether . ĊĠĠĠĠ Ġ* ĠĠĠĠĠ Ġ- ĠAppend Ġall Ġof Ġthe Ġdata Ġsegments Ġtogether ĊĠĠĠĠ Ġ* ĠOnce Ġthe Ġabove Ġis Ġdone , Ġall Ġthe Ġappropriate Ġre location Ġis Ġperformed . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġpro gs Ġa Ġlist Ġof Ġprograms Ġwhich Ġwill Ġbe Ġlinked ĊĠĠĠĠ Ġ* Ġ@ return Ġa Ġ[ Linked Program ] Ġwhich Ġcan Ġbe Ġused Ġin Ġthe Ġ[ ven us . simulator . Simulator ] ĊĠĠĠĠ Ġ* Ġ@ todo Ġrefactor Ġthis Ġinto Ġmultiple Ġfunctions ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġlink ( pro gs : ĠList < Program >): ĠLinked Program Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlinked Program Ġ= ĠLinked Program () ĊĠĠĠĠĠĠĠ Ġval Ġglobal Table Ġ= ĠHashMap < String , ĠInt >() ĊĠĠĠĠĠĠĠ Ġval Ġto Re locate Ġ= ĠArrayList < Re location Info >() ĊĠĠĠĠĠĠĠ Ġval Ġto Re locate Data Ġ= ĠArrayList < Data Re location Info >() ĊĠĠĠĠĠĠĠ Ġvar Ġtext Total Offset Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġdata Total Offset Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( prog Ġin Ġpro gs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( label , Ġoffset ) Ġin Ġprog . labels ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstart Ġ= Ġif Ġ( offset Ġ>= ĠMemory Segments . STATIC _ BEGIN ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata Total Offset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtext Total Offset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlocation Ġ= Ġstart Ġ+ Ġoffset ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( prog . is Global Label ( label )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprevious Value Ġ= Ġglobal Table . put ( label , Ġlocation ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( previous Value Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠAs sembler Error (" label Ġ$ label Ġdefined Ġglobal Ġin Ġtwo Ġdifferent Ġfiles ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( label Ġ== Ġ" main ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlinked Program . start PC Ġ= Ġlocation ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprog . inst s . forEach ( linked Program . prog :: add ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprog . debug Info . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlinked Program . dbg . add ( Program Debug Info ( prog . name , Ġit )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprog . data Segment . forEach ( linked Program . prog :: addTo Data ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( re locator , Ġoffset , Ġlabel , Ġlabel Offset ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġprog . re location Table ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlocation Ġ= Ġtext Total Offset Ġ+ Ġoffset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm code Ġ= Ġlinked Program . prog . inst s [ location Ġ/ Ġ 4 ] ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( label Ġ== Ġ"") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre locator ( m code , Ġlocation , Ġlabel Offset ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Address Ġ= Ġprog . labels . get ( label ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( to Address Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĠTODO : Ġfix Ġthis Ġfor Ġvariable Ġlength Ġinstructions Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre locator ( m code , Ġlocation , Ġto Address Ġ+ Ġlabel Offset ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* Ġneed Ġto Ġre locate Ġglobally Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Re locate . add ( Re location Info ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre locator , Ġlocation , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlabel , Ġlabel Offset )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( offset , Ġlabel , Ġlabel Offset ) Ġin Ġprog . data Re location Table ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Address 0 Ġ= Ġprog . labels . get ( label ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlocation Ġ= Ġdata Total Offset Ġ+ Ġoffset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( to Address 0 Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Address Ġ= Ġto Address 0 Ġ+ Ġlabel Offset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlinked Program . prog . overwrite Data ( location , Ġto Address . to Byte ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlinked Program . prog . overwrite Data ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocation Ġ+ Ġ 1 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( to Address Ġshr Ġ 8 ). to Byte ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlinked Program . prog . overwrite Data ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocation Ġ+ Ġ 2 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( to Address Ġshr Ġ 1 6 ). to Byte ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlinked Program . prog . overwrite Data ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocation Ġ+ Ġ 3 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( to Address Ġshr Ġ 2 4 ). to Byte ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* Ġneed Ġto Ġre locate Ġglobally Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Re locate Data . add ( Data Re location Info ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocation , Ġlabel , Ġlabel Offset )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtext Total Offset Ġ+= Ġprog . text Size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Total Offset Ġ+= Ġprog . data Size ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfor Ġ(( re locator , Ġoffset , Ġlabel ) Ġin Ġto Re locate ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Address Ġ= Ġglobal Table . get ( label ) Ġ?: ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠAs sembler Error (" label Ġ$ label Ġused Ġbut Ġnot Ġdefined ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm code Ġ= Ġlinked Program . prog . inst s [ offset Ġ/ Ġ 4 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġre locator ( m code , Ġoffset , Ġto Address ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfor Ġ(( location , Ġlabel ) Ġin Ġto Re locate Data ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Address Ġ= Ġglobal Table . get ( label ) Ġ?: ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠAs sembler Error (" label Ġ$ label Ġused Ġbut Ġnot Ġdefined ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlinked Program . prog . overwrite Data ( location , Ġto Address . to Byte ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlinked Program . prog . overwrite Data ( location Ġ+ Ġ 1 , Ġ( to Address Ġshr Ġ 8 ). to Byte ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlinked Program . prog . overwrite Data ( location Ġ+ Ġ 2 , Ġ( to Address Ġshr Ġ 1 6 ). to Byte ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlinked Program . prog . overwrite Data ( location Ġ+ Ġ 3 , Ġ( to Address Ġshr Ġ 2 4 ). to Byte ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġlinked Program ĊĠĠĠ Ġ} Ċ } Ċ