Transcript for:
COMP1521 Week 2 Lecture 2 Assembly Data Management

[Music] all right good morning everyone i think we are ready to start can everyone hear me okay I can hear that echo again so excellent can I get a thumbs up online if um if you can hear me thumbs up can I get a thumbs up if you can't hear me is there any way of you they can hear excellent okay so welcome to your fourth lecture on um comp 121521 um so today we're going to be going back and looking at data a little bit again and then we're going to follow on to memory okay but before we begin another reminder that tomorrow we have C revision sessions hosted between 10:00 a.m and 12:00 p.m so where are they they're on Blackboard Collaborate so I know some of you have tutorials and labs that are already hosted on Blackboard Collaborate i know all about how that works um but for those who don't um in Moodle if you go to Moodle you'll find a link on there for Blackboard Collaborate and the help sessions will be listed there soon sorry I haven't created the the item there yet for these help sessions but they will be there soon and they will definitely be ready for tomorrow 10:00 a.m to 12:00 p.m um the general help sessions as well the schedule will be coming out soon and they will be starting on Monday so in today's lecture we're going to be recapping Monday's lecture talking about data and memory global variables specifically but then we're going to go on to arrays so 1D arrays we're even going to talk about 2D arrays which are twice as fun and then we're going to go on to strrus and strrus might seem a little bit scary at first but they're actually not too bad so recap accessing memory so to perform computations now our instruction set they can't the um computations can't operate directly on memory so we would first need to um load that memory into registers perform that calculation and then later on we might need to store the content of that register back into memory for use later on so I have a little recap recap exercise here for you um I'd like you all to get out Mipy web or whatever myipsy emulator you you prefer to use and code this up i will give you three minutes calling after one calling All right could I see a show of hands for who has finished no one has finished yet all right give me a few more minutes okay how are we doing now show our hands who's finished one two all righty i think we better move on um if you haven't finished the exercise I hope that you've had a good chance to think about it and how you would go about solving it and you're ready to watch some magic that I will be doing oh I'm going to spoilers okay so I'd like to try and start using the terminal i mentioned at the beginning that like a huge fan of the terminal um but we had some issues before where the terminal was a little bit fuzzy and thank you for whoever it was who posted in the the forum about how to use the command line in Windows i'm also a Linux guy so I'm not so familiar with Windows um so that seems to look okay excellent scratch two how's that okay vim is my favorite editor there's something I better mention about my editor i like to show non-printable characters here so that I know the difference between what eight spaces are and what a tab is so if you see some funny um characters like this in my window don't worry it is just a tab um okay the first thing I'm going to do is copy this over because I can't show both at the same time vim does not like to play with Windows all right I'll need to sort that out later on but we are getting there okay so let's comment all of this out and this is the program that we're going to be writing in assembly um we tend to flip things around here the data section goes at the bottom rather than up the top like in a C program so let's do a um dot data and a dotword oh not a dot word a dot bite b and we better get this lab a label letter seems pretty appropriate here okay so we have initialized our global global variable down here called letter okay so now we get to writing the actual text section we need our main function so what's the first thing that we do okay so we we load this global variable well the first thing we'll need to do we can't increment we can't decrement this global variable directly first thing we need to do is load it into a register so I'm going to do a little bit of magic here how about uh load bite because it is a bite we're going to load that into t0 and we're going to load from address zero but let's give it the letter offset okay so we're using the register zero as the address but we're giving it the letter offset so now we can load that bite directly okay what's the next thing we need to do need to decrement that bite okay how about we add I t0 minus one okay and then um because so to follow the C code here we should also store this back t0 back to address zero at offset letter okay and this becomes our letter minus minus are my um are my tabs causing problems no okay so we've done our letter minus minus next step we want to print that letter how do we print print character equals so we can look up in our MEIPS instruction uh MIPS guide under SIS calls print character number 11 okay so load so which registers does that need to go into so that's V 0 for the system call number print carrot okay and what is our argument so that's going to be letter we want to print the letter right so we could load this back from memory again but we still have that in our register T0 here so let's just move that um so into a Z t0 then we sis call put it on this Okay I always forget about this new line character let's add that one in as well copy and paste new line character better change the comment so we don't get confused and return zero another thing I often forget so that return value goes into v 0 and we want zero jump to return address that is our return zero all righty how does that look is that what everyone else got learning a few new magic tricks all right let's see how we go never seen that before all right all lines are a little bit long but that's okay okay so how do we run MIPY from the command line 1521 yes whoops yes thanks for picking that up thank you all right yes very good point so if we look at this program as a whole we don't need to do that right but when we when we start to get to more complex problems that programs then like the C code that we're trying to mirror is updating that that global variable so we're going to we would update it just in case there's some code later on that that did that or maybe we add that code later on that does it and we forget that all over the all over our code we assume that we didn't need to write the value back to that memory okay so 1521 mip and file was I got too greedy with my copy and paste all right and there we have it so I should have asked at the beginning what this code does okay so the global variable variable we initialize to be B we decrement that so that's going to go one before B which is A and then it prints the letter A and that's exactly what we got over here in um MIPY all right gonna stop here quickly ask if there are any questions about what's just happened here because we had the new way of using Mipy and um and global variables i think there were some questions on global variables earlier anyone at all all right let's move on then okay all right could I just have everyone in the the theater being quiet please thank you okay so last lecture we talked well we've been talking a bit about um the assembly directives for a while um but last week we focused on um how to reserve space in the data section so I I listed a few ways that you could do that and here we have a few more listed as well so the so recap the text section that defines where our that tells the assembler that everything coming after that directive is going to be our code section and the data says that everything after that is going to be our dot our data section so we have the space directive so what's special about dotspace yes great so it it allocates a number of bytes and um what's special about those bytes what do we need to consider sorry the line yes it was right underneath so space is our only way of initializing or sorry of allocating space that isn't initialized but depending depending on how we access this space will depend on how the alignment of that space needs to be so um so from last lecture if we're loading a word if this space becomes like an array of words then we would need to align that space to be um aligned with four bytes and if it was an array of half words it would have to be aligned to two bytes but if it's just being used as characters like over here we see a int 8 t so this means an 8 bit integer so in this case there would be no reason to align this but for the if we're allocate if these are going to be used as words the align directive below align to remember that argument there is um is a two to the power of what that value is so in this case we're aligning to four a four byte address and then we we talked about um the word directive for allocating a word but we have these shortcuts here for allocating arrays so if we have a word we can provide a commaepparated list and the equivalent in C there is to allocate an array um so in this case V and then the size of the array and then a commaepparated list of values in curly brackets and this is of course true for half as well and uh the next one byte um so this one this is one that we can't really do in C so we provide the value a colon and then the number of times that value is repeated and we of course have floats we've spoken a lot about ASIZ so in this example here it becomes clear like what the difference is why that zed is important so we have zed and asky and they define a a string or an array of characters and the zed on the end means that the assembler will automatically put that zero terminator on the end for us okay so let's focus on these examples where we're allocating arrays into memory because remember the first thing we're talking about in this lesson is arrays so how can we access the different elements in these arrays so over here we have well let's focus on this one numsword and then the component separated lists if we don't have a label to each of these elements how do we access the elements and I'm sure whenever you've seen an array there's usually a loop that accesses that array so how do we loop through them how do we loop through the elements okay so arrays um so this is an example of an array of one by elements okay so here we have some arbitrarily chosen um characters a ZB FG and in the middle here this is how it would look like in memories remember we look at memory as we can consider memory to be just a one array of um bytes so our first element of the array that happens to be at ox10 0 okay and in there is that letter A so the next letter in the array that's going to come next in in memory so that will be address ox101 and there we'll find the letter Z and so on and so on so next we have ox 102 which stores our B 103 stores our F 104 stores our G so the question is how do we access these all these elements how would we loop through it so if we have the address for the start of of the array how can I work out the address of A3 what do you think yes right first memory location plus um plus three so we're going from here starting at element zero one two three okay so keeping that in mind how do we work out what the address of some arbitrary element in this array is say the E element yes exactly so if I was two we would say starting from here + one and plus one again we get to the second element of this array okay things get a little bit more complicated when we're talking about four byte elements though so this is what a four byte element would look like initialized up here with the arbitrary digits 16 4 1 9 and two and the addresses here underneath that's a bit boring we're starting at ox100 again then these would then increment by four each time because each element is four bytes wide so we have ox 100 104 108 10 110 i shouldn't call it 10 but I've got a bad habit of of reading it out as 10 um so in this case how do we work out the address of a three yes exactly yes so we take the starting element so which is where our label will be directing us and we can't just add three because each element is four bytes long so we need to add three * 4 okay and again for the i element it would be i * 4 so if we our label is pointing to the first element and if we had i is 2 it would be 2 * 4 is 8 so that would be um o x10 0 + 8 is o x108 and of course note that if i is zero 0 * 4 is zero so um we would stay at that first element okay so summing that up so for the character array we have the address of an arbitrary element of that array is equal to the address of A plus I whatever that whatever element number we want but if we're looking at a integer array that's four bytes wide so the element of the array that we're after would be the address of a plus i * 4 and in general the address of an element will be equal to the address of the array plus the index that we're after times the size of an element so note here I'm using size off so that's something that we can use in C as well to find out exactly what the size of an element is okay so an example using um using an array and a for loop to go over that array let's work through this oh it doesn't like my intense pasting tense all right let's make sure this compiles gcc array bytes all right excellent that's exactly what what we wanted to see okay so if I copy array bytes to array bytes simple now we work on this okay so we need to switch this to um to simplified C right okay so first we turn the for loop into a while loop so in i outside here let's say i equals z i'm going to put the i ++ down here before I forget because I do tend to forget that and now we can just say while lost it there we go okay so let's just check quickly that this behaves exactly the same as our um our initial C code no it doesn't that looks better all right excellent it's the same okay so the next step we need to turn our while into an if that means setting up some labels loop in it loop condition i know this will be the loop increment loop oh technically this is the loop end okay but we don't need this anymore anyway okay so if And we switch that around go to loop end go to loop con all right self review i equals Z greater than go to loop bend flip that around that looks good to me doesn't look good to me well it doesn't look good to the compiler all right that looks better all right excellent it's exactly the same so I've converted my C code to um to simplified C made sure that it works exactly the same as the original C and now this becomes a really um becomes really easy to well easier to change this um simplified C into assembly so let's get started by just copying that simple to array bytes s so we'll leave these C files around so that we can refer back to them so maybe if we modify the original C code we would then follow through and make the appropriate updates in the simplified C and then we would map that to the the assembly that's frustrating all right so here is our C code all commented out so that we have something to refer to while we're writing the assembly so again the first thing we want to do well we don't need that one okay so here's our global memory that Yes oh wow that's horrible all right sorry no colors anymore i'll see what I can do about that uh okay so our global array throw that down the bottom here i don't want to call it a All right let's let's call it let's call it array because then we'll get confused in the C code just leave it as a okay and that's a dot bite okay by so we've got comma separated list here so this becomes an array and now to our code so dot text main in T0 oh we still need this loop in it so how do we set I to zero how do we initialize LI i is in T0 loop condition so we need to change this to assembly um branch greater than or equal h that's probably okay so we're looking at t0 and we are looking at size of a what's the size of a we can't do that in assembly so um 245 surely I've made a mistake here but let's run with it all right okay so now we need to load the character print the character so load word we're going to use the same trick as before element in T1 so I don't forget we're loading it to 2 T1 a offset from zero okay 11 okay so for this SIS call we need to load into v 0 uh print char and we need to load into the argument no we don't we need to move into the argument where did I store the value element in t1 called t1 this call and hopefully I don't get in trouble with my copy and paste again we want a print char this time load immediate space not sure if there's much point in updating these comments but you can't because you can't really see them they go off the end of the screen but I guess I'm in good habit so I'm going to do it anyway and then we have the looping um almost did it again someone called me out in the forum for doing this we can't use goto where else have we used go to that's the last one b lip condition um I ++ where is I stored well it's in T1 add I T1 let's leave it in T1 and we're incrementing and we'll put that in a comment what have we forgotten okay so at the end of this loop we need to print the new line as well so we can just update this to new line sys call return zero almost forgot that again what happens if you forget the the return zero it's just going to fall off the end and start executing um whatever is after there mip helpfully tells you that oh you didn't your code there wasn't initialized so I will fail here and tell you that something went wrong so I had a case where um I had memory there I had memory after my code section i was programming an assembly believe it or not or not and I had memory after my code section and it happened to be the last um the last function in my assembly and there was you know the rest of that code section there was initialized with zeros and what do you think the instruction that maps to the zero that maps to zero the encoding zero does i'm going to cheat do nothing zeros so I got to the end of my program and I went okay do nothing all right all right and eventually it failed somewhere like how did it get there what's it doing over there and yes it was because it failed much earlier but I didn't have my return zero or a return in general and it just kept executing so um v 0 is zero J R done that one this one was done here all right and I'm sorry there's no colors maybe I can put the colors back in i'll work that out later all right how are your eyes did I make any mistakes yes how many marks you're deducting sorry shouldn't the loop increment be adding Yes great thank you for that oh that might have saved me a bit of debugging so that should be t0 instead of T1 i was incrementing the element instead of instead of incrementing our loop condition so that would have gone on forever as well hand up the back yes ah very good point thank you so we need a a real register that's going to keep track of this index for us wow we already have a register that's keeping track of that index for us d0 all right any other marks deducted i hope that's all another mark sorry um why are we using inside here windows why are we using t0 in the increment okay so I left this lovely comment up the top here so t0 is holding our um our increment variable it's holding our value for i so so this was our original code um so we were let's go back further actually okay so we have this loop here using i as the um the value that we're incrementing and um yes so we're incrementing over here because it's a for loop all right I think I'm ready to submit my assignment i'm early so I can always submit again if I you know go to sleep and in the morning I go I forgot to return a I forgot to print that new line character yes how did that happen what happened there they're all like that [Music] there we go thanks for picking up that as well i hope that the auto test would have picked that up because I think I would have gotten zero for this assignment right if those auto auto tests weren't there to check that what I was doing was seen all right 1521 Hooray unaligned access this is one that got past the auto marks right it's a bite not a word right so we've gotten that typical underlined access we've probably read the first one then we've incremented by one to move to the next bite and then it said you can't do an underlined access so we have fixed that up now whoops all right excellent so thanks for all your help for that um question yes allows us to just so add the tens yes so we're taking the address provided in T t0 but we're adding this offset of a okay and if you have trouble getting your head around that you could rewrite that to include to first load maybe I'll do that quickly now okay we would want to do that right up here let's say load address put in T2 A okay okay and then what we'd have to do here is do we have another I'm just going to grab the next available temporary register i'm not going to try and optimize this we would add put that in T2 uh T3 T2 and D0 okay and then we just get rid of the A here uh and we need to use T3 sorry um so what what we're effectively doing here is at the beginning of the loop we're loading that um address in a register then throughout the loop each on each of our loop iterations we add the value of I to that loop to that address before we load the bite from that address so I had I had load word in here okay and that was a bug on on my part right we're adding So we're adding one to the address each time so it's going to be so it will um perform an underlined uh read of a word but the bug here was that I was loading a word when I really meant to load a bite so once I fix that up we shouldn't be getting the underlined access again excellent that one worked full marks for that one no corrections all right ah time flies well time yeah time flies when I've got you guys here with me i think we're just about have time for a break is this a good time okay so I'm going to run through this next example now um so this one is exactly the same as the previous one you might not have noticed the difference but this in this case where um we have an array of integers instead of an array of um instead of an array of bytes and we'll take a break after this okay so I'm going to skip a few steps here i hope that's okay with you so what do we need to change in this program to turn it into an array of um of words So dot bite changes to word values need to change as well of course okay and we need to change this back to a load word instead of a load bite okay but remember if we're using words now um we can't just increment by one in fact we can't use that trick before where we we took the the loop counter and we just used that as the offset to our label we can't do that anymore because we now need to increment by four each time so I kind of like that I went back and adjusted this to um use a register for the address okay so what I need to change here um so instead of adding um adding I what do I need to do how do I need to adjust this yes four times I yes so my cheat sheet up the top which is Yeah so T0 is I where are we going to keep it t3 hey we're multiplying so I is T0 by Will that take an immediate i don't think it will let's see [Music] looks like it will all right so we're storing that in T3 so we need to add Okay so we're storing see I get so lost when I don't have this comment up the top address in T2 okay so we're adding to the address T3 which was the loop counter multiply by four so I think this will be all good is anyone going to deduct any marks for me yes um I don't believe so because it's Let's give it a go i believe there was just a C directive i wish there was though oh it doesn't know what it is nope unfortunately we cannot maybe I'll keep digging and find find out if there's some way of doing that oh something's going wrong here okay let's have a quick look at the code again thank you yes deducting marks again this needs to be I'm not going to remove that i'm going to say print int and print int is pretty sure that's one it's definitely not that all right let me double check yep in definitely is one i haven't changed these yet though don't want to change that one all right there we go okay so not a big deal wasn't a big deal just had that um thanks for pointing that out um I was still using print char for the integer numbers and if we go to the integer numbers themselves these are all non-printable characters so they all just appear as nothing on the terminal all right any questions on that all right let's take a 5m minute break there guys so back at um 5 12 discussion exploded it's just pressure i turn all these All right let's get started all right everyone let's get started again um so in the last lecture pulled out a big slide this I see a few people getting confused about how we store and and load memory so these were all the different forms that loading from memory can take so we had T1 here which takes which provides the address of the um in this case the store t1 provides the address and we provide zero here as the offset so this is like the standard way of representing a store and in this case specifically a store bite but we can emit the zero in front the offset in front and we can just have the brackets there provide that um provide the address in the register itself okay another form we can use is just provide the the address directly sorry the the label directly so we don't need a register at all there and um if we provide the the label we can also add an offset to that label and the assembler will automatically do the maths for us so this is pretty useful if if we want to access a specific index of an array the problem is when we're accessing array an array we're generally doing that in a loop or at least the index that we want to access is not a constant um then so so that's the issue with that method um and the method here that I was using today the um the register becomes the offset and the label there becomes the starting address so X here is the is a label that represents an offset yes up the very back here goes in the opposite direction unlike other commands like get in the right yes so it is the opposite um the weird thing as well is that it's the same for for load and store so the register that we're so the memory is always on the the right hand side so if we're storing we're storing some register to some memory address and if we're loading we're loading some memory address to some register because it's just the store that's different then where the target is the memory on the right hand side all right so just jumping back to our words example real quick um I forgot to mention this this dial here has anyone seen this before you have the empty brackets for the array i thought this was very in line with um with what we're talking about in terms of um arrays and their sizes and size of elements okay so we don't actually need to put a number in there for how big this array is the C compiler will work that out from the number of items that we put in the initializer okay but then we have this problem how do we know how big the array is someone could come in here and just change the the size of the the array so that's why in this for loop our loop condition here is the size of a so that's the entire size in bytes of the array and then the size of star a that's where so remember an array can be treated like a um sorry the the a here is like a pointer to the beginning of the array okay so when we dreference A we're looking at an element in that array A so if we take the size of the array in bytes and divide by the size of an element in the array we get the number of elements in the array another way to rewrite this I can't rewrite this so size of the array divided by size of the first element of the array that would work as well but even though it's the same when we program we like to program in a way where the reader can more easily understand what's going on and to me this says we want specifically the first item of the array and to me this says the size an element of the array they're the same but this is more of an arbitrary element just in terms of reading it like both of these methods are pointing to the first element of the array um it's just about how it looks to the reader to um communicate your intent here all right so now we're on to pointer arithmetic okay so in C adding one to a pointer increases it by the size of the type it points to so that makes it easy to use pointer arithmetic to iterate through an array right so um so in this case here we have a character pointer and if we go sorry a character pointer called p and if we say p++ that's going to advance to the next item in that array or it's going to advance by the size of the that data type um which would be one for the int that's four bytes so of course the Q++ will advance by four bytes and for the double eight bytes so advance by by eight bytes okay so this is really convenient at NC but in fortunately in assembly this is not a trick that we can use so everything's like a everything's in bytes so we need to always know the size of the underlying data type and add the correct amount to it okay so in the style guide pointer arithmetic avoid pointer arithmetic using array in use array indices instead so why is this i think the simplest way to explain it is well first of all you can get lost as to where your pointer points to if you're always keeping the start of the array and then calculating an offset becomes really easy to reason about where your program is what's what it's doing but the other issue is if you start using this method you lose your loop counter so when you're debugging how nice is it to be able to go oh I equals to zero so I'm on the first iteration of this loop or I equals 5 I'm on the fifth iteration of this loop so once you're using this method you now need to come in and say oh this pointer is now pointing to this location okay what what was the beginning of the array okay so which loop iteration am I at but it does lead to some a lot more elegant um assembly code so this is the way we'd write a program in um using pointer arithmetic and for the sake of time I might move on and leave this as as an exercise to the reader because we need to move on to 2D arrays twice as fun as 1D arrays so RAM is really just a 1D array and a 2D array is really represented in memory in memory um with each row next to each other okay so in the top left here you can see what a 2D array might look like we have columns of the array uh we have rows of the array and it's nice to think about it in this form but RAM memory is just a sequence of bytes so what happens is this gets unfolded and and pres and put linearly in memory okay so we need to map our so we now have two indexes right we have the column and the row so we need to map our two indexes to the appropriate offset in this linear bit of memory okay so this is very similar to um what we were doing before so the offset of the start of the relevant row becomes the row number times the number of columns and of course don't forget we need to multiply by the size of the of an element right because we need to talk in bytes not in um in indexes and then once we found the row the column would be um or the memory address of the column would be the column times the size of an element again so if we put these together to find the memory address of any item in this 2D array we would take the row number multiply by the number of columns in this array then add the column and multiply all of that um to account for the size of each element okay so who's had a great look at the course website by now no one okay so on the course website there's loads of resources recommend going through it um so I haven't been posting my live code because we have some really comprehensive code examples here right they're written much better than anything I can hack up in a lecture some of my my live code is um based on these examples but yeah there's these are much better than anything I can hack up quickly in a lecture so this example that I'm going through here it's taken directly from that list of code examples let's paste anyway do as I say windows all right m flag it's not so great bit of lag i just want to check that this is going to look online look okay to our streaming friends i think it's okay okay so first of all GCC good compiles hey okay so this is what this program does it prints a little flag for us okay so so if we are to Okay so if we are to convert this to a myth program what's our first step okay always try and go to the um simplified C first that'll make it easier to translate i think once you've had a lot of practice at this you probably be able to write the assembly code directly um or go from C code to assembly but for now we like that intermediate step um I think the best part of that intermediate step is that you can make sure that your program is still going to um perform in the same way okay so that's our original C code let's copy flags to flag simple okay so all that can stay the same oh we got two for loops now what do we do well let's start with the inner for loop okay so first we need to turn this for loop into a while loop so int um call equals zero while co is less than n coals don't forget the col++ can't tell you how many times I've forgotten that okay now we can get rid of our for loop okay so let's keep working on this while loop here um we need to turn that into an if so we first need our labels uh loop call in it loop call con forget this label last time loop call body loop call ink Loop call end all right so this becomes an if i don't want to forget this like last time go to loop call con and this becomes if call greater than equal to n calls Okay so that's our first loop before I go on how about we make sure that I haven't done something silly and that we still work flag simple i've done something silly loop end use but not defined all right excellent still working the same i've done one loop time for the next loop okay so I'm going to How did that even work that shouldn't be in there okay so we do have a issue looks like it's in our rows okay so because we've turned the while loop into an if that um curly bracket got left behind and the curly bracket actually belongs to this one right all right excellent back on track okay so now if I have any bugs I can assume that it's going to be in the row loop and my column loop is completely fine don't need to look at that anymore okay so column loop i'm not so confident anymore i'm going to do this carefully int row row equals zero and that becomes our loop row in it and we have our loop row con oops this so we don't we don't have that while so we're switching to while first so I guess let's leave that out for now and of course I forgot my row++ but other than that I think that looks pretty good doesn't look very good at all but that looks much better not so much there we go all right now that we have our for loop as an if and there's a question out the back um that looks pretty boring though but at least you can read it all right so is that better excellent so the question was to to change the colors because it looked horrible okay so we have our while loop we've tested that that makes it uh that that works as expected now we change that to an if so loop row in it loop row con if switch these around and we'll go to the end then we have the body and all the way down here we have loop call row ink cond so there is a pattern here for the the labels right so as you go through it you become pretty good at knowing which labels to put in and it becomes pretty easy oh my my LRO ink doesn't have a Loopro con at the end of it the only issue then becomes making sure that all your labels are unique where was that 46 okay i might bring my own keyboard with me next time i keep tripping over these keys 53 so that is because we don't need that anymore all right still works yes still on track now we have our C code our simple simplified C code come on just clean it up a little bit all right let's start um changing this into myips assembly copy flag simple to flags what happened there all right excellent so here is our C code in our assembly file um already commented out and sorry um is there a question i know there's a question coming up the back all right all right so let's take our data our global variables and put them into a data segment these colors are kind of convenient you can't see my special characters that represent that this is a tab instead of spaces so at least they won't go in get in your way um that's okay i'll see if I can just choose some brighter colors for for next week flag okay so how are we going to represent our flag so you will see how this flag here in C was really nicely um written in the code here so we could have just thrown all of these in one single big long line in the C and chain them together but instead um whoever programmed this decided to split it up into separate rows in the C code itself so we're going to do the same thing so these are bytes all right that looks pretty good and we don't have to worry about all the curly brackets getting in the way of how how um good this looks maybe we should actually represent this as ASKI but of course we wouldn't use ASKIZ because we don't have a null terminator here okay these defines are going to be useful but we need to make them into assembly defines we don't have standard IO i hope that you're using better um title comments than this but let's leave that like that and start to work on our data section on our code section i'll I'm going to skip the comments no I'm gonna shoot myself in the foot if I forget that let's see how we go okay so first comment um row in t0 col in t1 t1 okay so this becomes uh let's do a bit different how about move t0 branch greater than greater than or equal and where does where is rows t0 and rows loop row end i can't help myself but put in these comments it's a good habit to get into okay so now we have our in column which we don't really need this becomes move t01 [Music] okay I'm going to save this bit till the end okay so increment add I which one is column in T1 t1 one oh there's still more oh there's not that much more let's do this one last as well where is Ro T0 okay so how do we print an um new line character alli sys call number is v 0 argument is print char and then we provide our character Okay so that's all done now we have the tricky part how are we going to get our character well we're going to have to load a bite uh we got to load it somewhere where are we going to load it from let's do that trick of flag uh what's our offset going to be let's put that in T2 t2 holes i think that deserves its own line so you might notice I don't really like to program linearly i like to do the easy bits first so we still need to todo T2 what let's get the boiler down so we're loading the this bite that we want to print into T3 um we'll need to do a sys call and the sys call we need is print char what happened there ch is 11 okay but why are we loading into T3 let's just load into T A Z unnecessary step right we have to move that into a Z just to print it anyway all right we're done all right let's do a search for todos just to make sure I didn't leave anything in there oh there we go all right so what is T2 that is col outer one is row so row time n rows plus col times size of element it's my pseudo code okay the size of our element is one one because we're talking about bytes so let's just leave it at that so can I do mull T2 which one holds the rows t0 maybe the I don't think null can take an immediate value but let's see if the assembler will automatically put in the right code for me okay so we're multiplying these things but we still need to add the column to the end where is the column store T1 does that look good is anyone going to take marks off me no one's game too all right let's try it that doesn't look right undo all right 1521 nipsy flag s T1 what was T1 meant to be i think that was just meant to be nope that was meant to be T1 because we want to add on the column number how many times have I said it this lesson uh V 0 0 all right this is not quite right i wonder what's going wrong here i think our indexes might be off so how do we calculate our indexes we got the right number of rows okay [Music] okay t0 is our row sorry it's funny call body so we have row is in t0 so we want to multiply our row by the Okay yes thank you that come from the discussion or that came from you perfect that was my only problem and thank you so much for helping me out with that saving a bit of time um right any questions on that i know we're pretty far into the lecture so far five minutes thanks for the warning okay so again this example of flag.c is in that um the code section of the course website and they probably implement implemented it a little bit different to me um you might want to have a look at that and just you know compare the differences think about which one might be better which style you you find easier to read which one has fewer instructions or how how you could implement this with fewer instructions okay so the final part of the lecture today is on strrus these look pretty scary right but they're actually quite simple how we address these so the strus like arrays but each element in this array has a different offset so unfortunately we can't just take an index and multiply that by some offset by some size for each element here it has a different size it'll change the way we calculate the offset but generally when we're accessing a strct um we're not looping over it we want to access a specific member of the strct we don't want to access member number something so we can use um fixed offsets here to work out where these members live in memory okay so we have int z ID here so we're imagining a um a strct that represents a student and which um classes they're taking so int z ID that's going to be at offset zero in the strct okay and how big is an int that's four bytes so our next offset will start at four and the next member here is it's a this strct has arrays in it but hey we know how big this array is it's 20 so when we want to know the offset of the next member of the array we just add 20 so the next one will be 24 and again another array of characters of size 20 so we add 20 again our next offset will be 44 which is an int so um we add four to that to find the next one and we end up at offset 48 48 okay so how big is this strct then so what I'm getting at is this last member here char alias 10 so this is 10 bytes and that's that won't give us an alignment of um of four bytes if we were to have um these strcts put in sequentially in memory right the next strct would have an alignment error of two so we'd have to put the the dotted line so in this case um so down the bottom the values that we're assigning to this strct we might have for the Z ID an integer um the first name a string of characters last name a string of characters with padding at the end after the null terminator program and int again and an alias for this person all right so what did we learn today so um we did a bit of recap on myips so loading and storing data and pointers so we looked at arrays 1D and 2D and we looked at strrus and in our next lecture we are going to cover functions in myips and I think that's the last thing to cover in terms of your MIP's assembly programming so we'll finally get to learn to use functions all right so again um if you're having any troubles please reach out forum is best place you can post questions there others can answer you can start a friendly discussion and if you have admin related questions please email cs1521 at cssec.unw.edu.auu and if you are still having trouble reading MIP's assembly AI has trouble reading that as well on the right we have a tiger with a MIPS assembly background all right thank you everyone i finished a little bit too early cheers