Data Transfer in Registers
index1 = 0 // initial position in input string
index2 = 0 // initial position in output string
firstChar = 1 // set firstchar to 1 to change case of nextletter
while input[index1] isnotzero do
currentChar = input[index1]
ifcurrentCharisnotspace
ifcurrentCharis a letter
iffirstChar == 1 then
currentChar = uppercase(currentChar) // convert to uppercase
endif
endif
firstChar = 0 // nextcharis no longer a firstchar
else
firstChar = 1 // nextcharafter a spaceis a firstchar
endif
output[index2] = currentChar // savecharacter in output
index2 = index2 + 1 // advance to next output position
index1 = index1 + 1 // advance to next input position
endwhile
output[index2] = 0 // saveend of string in output
BM assemblyProgram
MOV [input] -> R1 // load input stringaddress
MOV [output] -> R2 // load output stringaddress
MOV 1 -> R3 // firstchar = 1
MOV 1 -> R4 // constant 1 forincrements
MOV nofirst -> R5 // address of nofirstlabel
MOV -32 -> R6 // valueused to convertfromlower to upper
loop: MOV [R1] -> R7 // load characterfrom input
MOV 0 -> R0 // compare charwithzero
JMPEQ endloop, R7 // endtheloopifthecharisend of string
MOV +32 -> R0 // compare withspace
JMPEQ else, R7 // ifcharacterisspace, go to else
MOV "A" -> R0 // forcomparingwith A
JMPLT R5, R7 // ifcharis< 'A' it'snotletter
MOV "Z" -> R0 // forcomparingwith Z
JMPLE R5, R7 // ifcharis<= 'Z' it's a letter, no need to up
MOV "a" -> R0 // forcomparingwith a
JMPLT R5, R7 // ifcharis< 'a' it'snotletter
MOV "z" -> R0 // forcomparingwith z
JMPGT R5, R7 // ifcharis> 'z' it'snot a letter
MOV 0 -> R0 // load 0 forcomparison
JMPEQ nofirst, R3 // iffirstcharis 0, skip
ADDI R7, R6 -> R7 // convertfromlower to uppercase
nofirst:
MOV 0 -> R3 // firstchar = 0
JMP endif // go to nextchar
else:
MOV 1 -> R3 // it's a space, firstchar = 1
endif:
MOV R7 -> [R2] // savecharacter in output
ADDI R2, R4 -> R2 // increment position in output string
ADDI R1, R4 -> R1 // increment position in input string
JMP loop // repeatloop
endloop:
MOV R7 -> [R2] // saveendingzerocharacter in output
HALT // endtheprogram
input: DATA 80 // initialaddress of input string
output: DATA C0 // initialaddress of output string
80: DATA "i2cs assignment 2" // test input
Description
Whentheprogramis run, theregistersstartchanging and theprogramadvancesfrom position 00. Aftera fewsteps, thememorystarting at address C0 isfilledwiththecharactersfromthefirststring, withtheinitialcharactersbeingchanged to uppercase. WhentheprogramreachestheHaltinstruction, the output stringiscorrectlygeneratedstartingat address C0 in memory. Thenumber of instructionsusedbytheprogram to achievetheresultis: 331. The figure belowis a screenshot of theprogramafterbeing run.

Thefollowing figure shows thememorycontentsfromaddress C0, whereit can be seenthatthestring “I2cs Assignment 2” isgeneratedcorrectlybytheprogram.

Technicaldescription
Thefollowingregisters are used in theprogram:
R0 → used to load valuesforcomparisons.
R1 → current input stringaddress, it has theaddressinput[index1] shown in thealgorithm
R2 → current output stringaddress, it has theaddress output[index2] shown in thealgorithm
R3 → firstcharvalue, it’sthefirstChar variable in thealgorithm
R4 → always has theconstantvalue 1, it’sused to do increments
R5 → address of nofirstlabel, it’sused to makeconditionaljumps
R6 → always has theconstantvalue -32, it’sused to convertlettersfromlower to uppercase
R7 → it’sthecurrentcharacter, corresponds to currentChar in thealgorithm
Themainloopwiththelabel “loop” corresponds to the “while” cycle in thealgorithm,
Theelselabel in thecodecorresponds to the “else” part in thealgorithm. The “nofirst” labelcorresponds to the position of “firstChar = 0” inthealgorithm. Thatis, the position afterthefirsttwoendif’s in thealgorithm. The “endif” in thecodecorresponds to thelastendif of thealgorithm, it’sthepartthatisexecutedifthecurrentcharacteris a space. Finally, the “endloop” label in thecodecorresponds to the position afterthe “endwhile” in thealgorithm.
Thememoryisaccessedusingindirectaddressing. In thecode, theregister R1 (R2 forthe output) holdstheaddress of thememory to be accessed, thevalue at this position isloadedusingtheexpression [R1] → register (orwrittenusingregister → [R2]).
Relationshipbetween machine code, assemblylanguage and a high-levellanguage
The machine codeisthelowestrepresentation of anexecutableprogram, itnormallyiswritten in binary and it can be directlyexecutedbythe machine. Theassemblylanguageis a layerabovethe machine code and allowsus to use textormnemonicsinstead of binary to write a program, howevertheinstructionsavailable in assemblyfollowthe machine codeveryclosely and sincetheycan’t be executeddirectlybythe hardware, theymust be translated to machine codeusingan “assembler”. Thehigh-levellanguagesgoanotherabovetheassemblylanguage and allowus to use abstract data types and control structuresbeyondwhatisavailable at the machine level. Theseimprovementsallowus to createcomplexprogramswithouthaving to thinkabouttheconstraintsimposedbythe machine code. Just as in theassemblylanguage case, theprogramswritten in a high-levellanguagecannot be understoodbythe machine so theymust be translated to machine codebeforethey can be executed. In this case, a specialprogramcalled a “compiler” isrequired to translatethehigh-levelcode to machine levelcode.
One of theapproachesthatcould be used to develop a compilerfor a computerthatinitiallycouldonly be programmed in machine codeis to writefirstanassembler in machine code, thecompilercouldthen be written in assemblylanguage and be assembled to machine codeusingthe machine codeassembler. Anotherapproachcould be to use a different machine to develop a “crosscompiler”. Thiscrosscompilerwould run in a different machine and thegeneratedexecutableswillcontain machine codeforthe machine wewant to use.