Transcript for:
COMP1521 Week 1 Lecture 2 MIPS Assembly Programming Overview

[Music] excellent all right so good morning everyone sorry about the weather not much i can do about that but welcome could i have everyone be quiet please guys thank you so welcome to your second lecture of comp again if you are in the wrong room this is your chance to sneak out quietly all right before we start um i had an email come in from a student who found this uh computing engineering uh research resource page very useful and i've been asked to share this with you if you're particularly if you're a compend student um this is going to be part of the lecture slides so i'm not going to going to go into great detail here but it just gives you some information about purchasing personal machines and how to structure your degree okay so c revision and recursion um labs in week two so we have those scheduled now for 10:00 a.m till 2 till 12:00 p.m in week 2 um so these will be via blackboard collaborate and we're not going to do a ticketing system this time so let's see how it goes i hope that the it doesn't get too overcrowded otherwise we'll have to go with a ticketing system next time make you book that session um so the content in these in these revision sessions will be c revision recursion lab style based questions um but you can also get help with your regular lab week um lab for week one if you are struggling okay so in today's lecture we're going to do a recap of what last lecture was all about what we covered there uh we're going to talk about system calls we're going to talk about style the style that you should be using going to touch on that simplified c so i will be explaining what simplified c is and um we'll be talking about mip control because sequential execution well linear execution in a linear program is not very interesting okay so big disclaimer the code that i'm writing in lectures um then don't usually use the best style so i'm trying to hammer something out as quickly as possible to make the best of your time and um normally when i'm programming i come and do the uh or clean up the comments later so when i'm programming first up i'll leave comments for today me and then i'll go back through and for future me i'll extend those comments so that in the future i'll still be able to understand what i was thinking back then all right so um for for uh good guides on um how to uh for um documentation on the style that we'll be expecting for both c and assembly we have links on the course website and other good resources are your tutor the solutions lab solutions and the assignment resources we give you so recap of our last lecture i know we got cut a little bit short but we will cover what we missed today um so we explored the different types of storage and memory the process of loading programs into ram for execution um the different program segments so we talked about code which is typically called the text section or text section the data section what do you think that's called the dot data section and then the heap and the stack which dynamically grow when the program while the program is executing um i touched on hexodimal number representation um we talked a lot about machine instructions so remember these are unique to the instruction set architecture of the cpu so the different the different um companies that make the the different chips they all have a different instruction set architecture they're all what they deem to be the most um power efficient or the the fastest the most most powerful so they all have different instruction set architectures examples would be uh x86 this is typically your intel or amd cpus in your laptops or your desktops um mips which um is used in some routers arm so arm is um they don't actually make computer chips or cpus they design the cpu and then they lease that to the companies that make it you might have heard of exinemos you've heard of apple so they're leasing the the arm um cpu um so the new the new macs will have an arm cpu there that isn't so the applications that are built for the intel cpu won't be able to run on your mac cpu you need to rebuild those with a different compiler uh we talked about assembly language and we started to look at mip's emulation using mipy web i did mention some others but i'm just going to focus on mip web here because that's what we'll be using during the lectures so a little bit more about registers um so registers are like a little array of memory that sits right into the cpu it's built into the cpu um so it's so it has a very small number of entries in this array right and you can see here on the left column here these are numbered these are you could think of these as an index into this array of registers but a lot of these registers have special purposes so we do prefer to use symbolic names for these registers so for example reg um the the first register register number zero we give that the name zero and that's special because whenever we write to this register it um it won't change its value it always reads at zero and that helps to optimize the cpu architecture i won't go through all of these but um eight registers 8 to 16 or this with the symbolic names of t0 to t7 is what we'll mostly be using today but we'll also be using um a z and v 0 um and i'll explain more about their purpose later on oh and of course the ra return address so back to mipy where we left off last time so i hope everyone has mipy web out okay so almost all of our computations happen between the registers rather than with memory so we're stuck um with these registers so can i have everyone um punch up this program in mipsy web please or follow along with me here we go so the first thing we need is some starting point for our program li is the instruction to load an immediate so we want to load that into t0 and the value was two and just because i'm beginning at mipsy i'm going to put in load 2 into t0 next one is 3 into t1 load immediate t1 number three hash for the comment load three into t1 and we want to multiply those so mull is the instruction for multiplying t2 t what was the zero and one multiply t0 by t1 whoops store in t2 so how many of you have gotten up to that step yet maybe you're um how many of you are up to that step maybe you're faster typer than me i can't unfortunately look at the slides and the and my uh and mipsy web at the same time show hands who's ready to go on who's got that in there few people all right so now that we have this in mipsy web we save it of course we can actually look at what this gets um compiled into the machine code so over here we have the address which is nicely in hexodimal so it's easier for us to decode and the instruction as well right generally we don't worry about what this instrument what this sorry the machine code is um but it is there if we'd like to look at what that actually is so then it disassembles it okay so that means it it will show us what that machine code actually corresponds to so you'll notice oh and it also helpfully helpfully puts on the right hand side um the assembly instructions that we entered to generate this machine code so you can see here that it's used the add i instruction instead of the li instruction add immediate instead of load immediate okay so the reason for that is that because we have this zero register loading a number and putting it into a register or loading an intermediate putting it into the a register is exactly the same as adding a number to zero and storing that in a register so we don't actually need the li instruction but when we're programming it when we're programming it is um if i were to put add i in there and use the zero register that could be pretty confusing to whoever is going to be reading my code so we always prefer to use the li instruction where the purpose is to load a value into a register all right um so those are called pseudo instructions where do we i've got it on the next window so if we look at l i these these um instructions are so difficult to to search for because they have such short names but because there's so few of them and it's a well- definfined set it makes it a lot quicker to type so here we go so li is a pseudo instruction there's quite a few pseudo instructions here so this just means that this there's no machine code for this instruction this um instruction will get broken down into um one to three machine code um or other instructions that perform the exact same operation okay so from here we can step through our program and i recommend with your first few programs stepping through will give you a really good understanding of what's actually happening with your code and in the cpu all right so we're about to execute the first line of machine code so here we're doing the the i'm going to say li 2 into t0 so on the right hand side we have a list of the regist registers that we're currently using and it's helpfully highlighted here the um t0 and the number two so very clearly we have loaded the number two into t0 yes i think too far too far okay so if i step again okay the next instruction we're loading three into um t1 and you can see over here our use registers on the right um is helpfully highlighted um that t1 has changed and it is now the number three next instruction we're multiplying t0 and t1 storing the result in t2 you can see t2 has updated to be the number six 2 * 3 is six so our program is working as expected all right and if we step again what happens could not find the instruction at um 4000000 c that's because we don't have an instruction there we didn't write an instruction there so when we're writing assembly um we have no guards to make sure that we don't do anything silly like this the problem here is that um once we execute these instructions the cpu just wants to move on to the next instruction but there's nothing there there's no there's no there's not even a notion of um marking that a function or that the code has ended all right so an exercise for you i'll give you a little moment to do this yourself so code this up in mipsy web um set 10 uh set t0 to 10 set t1 to 7 subtract t1 from zero and from t0 and store in t2 and then add five to t2 okay who's got the correct answer in t2 one two three four few people still working on it all right let's see what i can come up with oh my comments are going to become out of date that's the problem with comments sometimes okay how are we going now does everyone got the correct answer all right where are people having trouble do they just need more time yes sorry right good question so add i so the question is what is the difference between add and add i so the difference is that add i operates on an in on an immediate value which gets encoded into that instruction but the add instruction operates only on registers so if i were to do add um add i would need to have two registers here for example let's use some different ones t6 t i use the same ones t2 t3 okay does that make sense i'll i'll be touching on that a little bit later anyway okay so because [Music] the but thanks for mentioning that because you made me realize that i had a little bug in my code so so yes add i the last argument there will be a a constant value that will be added into the register but for the add instruction we have a register that provides that value to be added how's everyone going yes still works sorry when you really okay so mipsy or the assembler is probably smart enough to go "that's not a register that's a constant i'm gonna put the right instruction in there for you that's sorry yes i guess so oh that's interesting so first we load so if we use add first we load five we use add i to load that constant in and put it in a special register and then we add that register in yes so i is adding a con of add is just adding exactly yes because the cpu needs needs to know whether it should um use a circuit to select a register or use a circuit to take a value from the instruction itself okay so the only thing missing from my program is this instruction here i want to subtract and how do i find out how to subtract whoops that's not the right instruction so this is where having the the mips documentation um next to you all the time is very helpful because you can very quickly go and just look up the the instructions so we want to subtract so it's probably called sub something so we have a few options here okay so this one we want to subtract rs from well we want to subtract rt from rs and store the result in rd so this is the order of the arguments that we need but you'll find it's generally the the target register is first and then the operation uh the registers used for the operation generally don't need to worry too much about the encoding on the left here but if you're super keen to learn then you can have a look at how all these instructions get encoded into machine code so sub sub because we are subtracting from registers was there a sub eye we don't have a sub eye so if we want to subtract we need to do some little tricks there okay so stepping through where are we it only shows the compiled program so let's reset okay so first instruction t into t0 uh 10 into t0 7 into [Music] t1 three um sorry then we subtract t1 from t0 so that gives us with three and the last instruction we add five to the result 3 + 5 is eight did everyone get the same result all right excellent all right let's move on okay so an overview of the assembly syntax so generally there's a onetoone mapping so you've seen today there's not always a onetoone mapping sometimes our assembly instruction gets converted into one or more different um assembly instructions okay all right and i've just covered all that okay so what do the mix instructions look like i showed so you'll see a number of um encodings here for the instructions themselves but there's really just three different types of encodings so we have the r type which is the register type so these instructions operate only on registers um and we have the i type the immediate type so there we have registers that are operating the sorry the operation is on both registers and a constant value or an immediate value and um the j type so we're going to get into this type a little bit later in this lecture but they are the jump type instructions so it's just one register and um a memory address or a constant value okay so for so um each instruction provides an an operation so whether it's a subtraction or an addition or multiply okay and that we refer to as the op code and then we have um zero or more operands to that so the thing to operate over so that would be the registers or the constant values okay but how can we io because if our cpu isn't able to communicate with the outside world it's not a very useful program is it so this is where the fun part of mipy comes in so none of our instructions that we have access to can access or interact with the outside world like printing or scanning so instead we request the operating system to perform these tasks on our behalf so the process of this is called a system call so the operating system can operate um privileged instructions and um and can can and usually provides like device drivers so that it can communicate with devices so mipy will simulate a very basic operating system for us so we have a set of a very set of simple system calls that we can um use to ask the operating system to help us out with a task but we'll be exploring real system calls later on in the course so the common uh myipsy system calls we have print f but note here that print f um only takes an integer at this point okay we don't provide a string and a format and all that we have just print f with an integer we call this print int um so you can see in this next column here every system call is given a number okay and that number when we want to make a system call gets put into this special register v 0 and some of these system calls um we need to provide an argument like if we want to print an integer we need to know what integer to print so those arguments go into a z okay and a system call such as scanf which again we can't give it a a format string we just say scan an integer so that would be system call number five no arguments of course but our result gets put back to us in v 0 so there's a few more here but those are the oh i should give print print f with a um percent c and scan f with a percent c i mentioned here so that of course is for um printing a character or reading in a character and you'll notice they have different system call numbers in a real operating system you'd probably want to batch these together and just say this is for writing stuff to terminal but in mipsy for simplicity and to make it more easier for you to use then um we have um broken them down into other system calls into separate system calls so there's some more advanced system calls just touching on them we have we can print float values we can um read in float values we have some operating some system calls there for files but they're probably only going to be used for challenge exercises in cop 1521 oh and a worthy mention they are again in the um mip's documentation here okay so you don't need to memorize these you will have this document in the exam okay so let's try and print out the number 42 what is special about the number 42 yes excellent yes hitchhiker's guide to the galaxy okay so um so i'll have you follow along on your mipsy web so we specify which system call we can want in v 0 okay so for print int it is system call number one so li v01 specify the arguments so we're printing an integer so we better load the number 42 into our argument register a z and then we transfer execution to the operating system and we um to do that we use the sys call instruction what's going on with me today okay so has everyone done that okay so for v 0 we wanted the number system call number i'm going to i'll do it right i'll look at i'll look at the mit documentation not my slides all right print int is number one one all right and the value we want to print was 42 who can forget the meaning of everything sys call save decomp let's step through it okay so v 0 becomes one a z becomes 42 and in this io window down the bottom you can see that the number 42 has been printed okay but i know what you've all been told about these magic numbers here we should not be using them so how about we define print int equals 1 and then instead we can say print int here and when we're reading our code we don't have to keep referring back to the myips documentation we can straight away see here that this is going to make a print in system call so stepping through yes we still print the number 42 right what about printing the string hello comp 1521 we haven't written our first program until we've written some sort of hello world program right so how would we do that okay so you don't have to follow with me this time but we have a system call here print character so print character equals what was the number 11 okay and what do we print first h for hello okay so we can as the constants that we put into the assembler we can use the character notation as well so all we have to do is we need some more copy and paste magic that one was correct jeez this is tedious isn't it five where are we at two one don't forget the exclamation mark don't forget the new line character all right what happens h e l l o comp 5 2 1 that's quite a mess though right all this copy and paste you should know by now we we don't like to copy and paste we don't like to duplicate code surely there's got to be an easier way of doing this right we have another system call here called print string okay so what if we use that one instead print string what number was that um before print then we shouldn't need all of this right oh this is going to be so much nicer all right but what is our argument in this case okay so print the null terminated array of bytes referenced by a0 to the console as an aski string so what does that mean okay so we want to add some data to our program right and then we want to put in a1 a reference to that data okay so um implicitly here the code that we're writing now is getting put into the code section or text section and we use this directive to be very explicit about where we want this code to go okay for anything that isn't in the text section we would want that to go into the data section so we put a data directive there to say everything below here is going to be going into the data section of the program okay but now we need to put our string in there right but this isn't this isn't quite right we can't just write our string in there how do we refer to that string how do we um end up having the address of that string put into a1 for the s into a z sorry for the system call so in what we need oh we need to tell it what how it's stored as well include aski z okay so the asky zed tells us that um well tells the assembler that what's about to come is a an asy string okay and this zed is incredibly important can't stress enough how important it is this means that the string that you are providing is going to be null terminated okay and i'm sure there'll be at some point you'll be forgetting to put in this tiny little zed and uh when you try and print a screen string what happens if there's no null terminator everything gets printed because this system call will only stop once it sees that uh null terminator okay but how do we refer to that to this string that we've now put into the data section we use a label okay that's how we just define a label just like our main up there doesn't like me label welcome message something i've forgotten oh can anyone see what i've forgotten i think one person can he's got a big smile on his face i see all right so save just jump back yep no more warnings all right or errors so we step through now oh we can see our data section as well this is what our data section looks like okay so this is the um the hexodimal representation on the left and the characters that those hex hexodimal numbers represent and this is our data segment okay so stepping through there we go all at once code is so much cleaner and we've used the data section for storing this wealth message okay so putting strings um printing strings and the data segment so we need to define our string in the data section okay then we pass the address of our string to our system call in a0 and we need to use the data directive so that we can create global data in our program we need to use the asis z directive so that we can define a string and give the string a label and then we need to use the la to load the address of the string oh did i oh wow i did not do that learn something new every day could use la for load address la in that case is cheating we want the reader to know exactly what we're doing to understand exactly what we're doing oh yes li and la okay so so li is loading a constant value right but la is loading the address of something okay sorry well it you don't it doesn't really know what the value of that is until the very end right so it creates all the the um the machine code and at the very last step it needs to link up these addresses to the location in memory where these things were actually put and guess what this stage is called link linking phase yes all right okay so we have another example here i'll give you a chance to do this one on your own though oh we'll do it together um follow along with me can't copy and paste that all right let's put that in there for now so that we don't have to look at this slide all the time so we have our main all right a in t 0 b in t1 print a number enter a number all right so we need a message here do asky z okay number prompt a where are we ah that's fine okay so after printing this prompt to enter a number we need the scanf system call another definition okay we want reading values read int which is number five so into v 0 we have read int what's the argument to this system call oh well if we're not sure we can always check the theips um theips guide read int was it salt okay here we go arguments so reading values so the arguments for readint so no arguments but we have a return value in v 0 okay so we go straight to system call result will be in v 0 but that's a special register right that's going to be used all of the time so the first thing we want to do is move the data out of that register put it into the right spot t 0 v 0 that will do a little bit of copy paste here prompt b and that will go into t1 need to make sure we update our comment and the prompt for b is it's up the top there enter another number okay why don't we use these as comments that's much more helpful isn't it okay so our next step we need to print another message dot aski asky don't forget the zed the average is we can't put the percent d in there because it doesn't understand um format strings so we'll leave it at that oh but now we have this code here so we wanted to do a a + b / two okay so first we need to add those two numbers that we read in where are we going to put put the result well once we've added them together we don't need them anymore right we can put them wherever we want but why don't we just use reuse t0 so add so not the add i because we're adding registers together so we're going to put the result in t0 uh t0 t 0 t1 okay so now we've added them together we need to divide it by two how are we going to divide it by two oh we'll look at our um mip's documentation again our instructions why don't we start by typing div for divide and we have a number of options here okay so which one would fit us best unsigned or signed well let's use the unsigned okay but these instructions in fact all of these instructions they don't accept an immediate value right the difference so one of them is unsigned and one of them is um signed division so a so we will get into number representations later in the in the course but know and you can have an unsigned integer and you can have an integer right and how they are treated can be slightly different okay okay so first we need to load two into a register don't need t t1 anymore ld l i okay and then we can replace this two with t1 okay so we've computed our our argument to print f which would replace this percent d now we have to print the integer so li i v 0 print int li l i we don't need to do that we need to move why is that complaining uh we need to move our integer is in t0 so we need to move that to [Music] r0 okay and then we can sis call what's going on with all this thread instruction given incorrect arguments what did i miss something i'm not seeing oh that's interesting see if div helps us that's interesting i will need to look into what was going on there they look like the same formats to me all right uh so where are we is that still a true error the label this is defined multiple times it is indeed that looks better all right so if we step through this enter a number so on the right hand side you'll see that the bar down the bottom has gone green so it's waiting for input from us 10 okay now we keep stepping enter another number that was the prompt next and next few instructions okay now it's waiting for input uh five the average is seven and then we crash and we lose our output oh no how about we finally stop these crashes right so what's happening we we are going off the end of the our instructions right so in this main function that we were translating into myips we had a return zero yes sorry why are we using move for the line 33 so i'll talk about line 22 first so move here is used because when we're using the system call to read an integer the operating system is putting that the result into v 0 and v 0 is going to be reused later on so we need to get the data out of that register as quickly as possible or we will lose it uh in the case of this one here print int we're taking our result in t0 and we're moving that into the argument register for this system call okay and then we we issue the system call and the operating system goes right what was in v 0 okay that's a print int what was in a z okay that's the integer i wanted to print there are optimizations that you could make here of course like i believe you can put the result here straight into a z then we don't need this step but um i really recommend that when you're programming in myips you do so in such a way that it's easy for you to understand um don't try and make any crazy optimizations yes instead of what sorry um sorry i don't quite understand your question so okay so if we were to put la here so this wants to load an address into a register okay so that would be expecting t0 to be an address right but t0 is the integer that we wish to print or was it a different a different one that you okay great so for move we're just taking one register and we're copying it to another register okay back to the return zero so we we want to define or we want the program to do something when it gets to the end of this rather than just fall off the end so we will load into b 0 or is it v 0 or is it a z i forget that and then we jump to register ra i always forget whether it's must be v 0ero right load immediate okay so this will stop our program from falling off the end we load our return value and then we jump to the return address that was stored in ra for us and we'll be talking about the um these jump instructions in just a minute if we step okay so now that we have that in place the the meaning of line 36 okay so so i'm getting a little bit ahead of myself so the point of this is bad me return zero the point of this is we want to return zero from our main right so the first thing we need to do is load the value zero into this special register that is reserved for our uh return value you'll notice that for the uh the read int the integer that was read appears in v 0 as well so we load our return zero into v 0 and then we tell our program to jump to um to the to the um return address that was provided to us okay we'll we'll cover that more later on so i don't want to go into too much detail there um but right so now that we have done that we can actually run this program and not worry about it crashing so enter a number seven another number eight they weren't very interesting numbers run five and 15 okay the average is 10 i think we might be struggling for time i have to speed up again okay so were there any questions on that yes it doesn't allow you to enter any numbers okay so remember that these are there's two stages in your program one is to print the number and sorry there there is the system called to print the number and then there is the system call to read the number so i suspect that your system call for sorry the system call for printing the prompt is working but the system call to read the number has not yet been executed sorry the exact same code as me i think just try hitting step a couple more times and that bar might uh go green for you all right so quick recap of the assembly language i'll just rush through this really quickly so li for loading an immediate value into a register la for loading an address into a register typically um provided as a label move is for copying a value from one register and putting it in another register labels we append the label with a um with a colon and they will represent a um a memory address okay comments start with a hash use plenty of them to help you understand what your code the code that you have just written is doing and the directives we have just covered as zed for um for providing a a string um the text section which is your code section data for your data section and we have also looked at constants instead of using these magical system call numbers that we are we're not going to remember as we're reading the code we'd like to use these um these constant definitions a bit like hash defines okay so on to the next okay so so far our programs only actually i think this might be a good time for a break all right let's take five minutes everyone oh maybe i should leave for everyone i'll make it available later there is a section for live there's some chance i had something like this instructions so that is on the website documentation all right everyone let's get back to it okay so so far so far our programs only execute linearly okay um how can we conditionally execute code how can we loop over code because that's what makes a program really interesting right so in mip we have branch instructions so um so we have conditional branch instructions sorry so they're in the form if some condition is true jump to some offset in your code okay and we also have an unconditional branch instruction too so this is where we just jump to a an address okay so there's no conditional there so it doesn't matter so it's not dependent on anything we will always jump to the address that's been given so you'll notice that we have as an argument here an offset and an address so thankfully we can use labels for providing these okay otherwise we would need to continuously update these offsets um as our code changes okay but before we get into using these branch instructions i'd like to talk a little bit about simplified c so translating c code directly into myips is very challenging okay so what we want to do is we want to simplify this c code first translate it into simplified c so that each line of our simplified c can map to one mip's instruction so we can then compile our our simplified c and make sure that it still works the same way as our original c and then we can get to work translating each line of our simplified c into mips code mips assembly code okay and there's a trick that we hid you hid from you in 1511 for very good reasons so in c go to allows jumping to any arbitrary label in your c program okay forget the curly brackets don't have to worry about those anymore so this means we can effectively jump around while in a program however we wish okay so what will this code do yes yes it'll keep printing you are getting sleepy because after we print that go to sleep the label for sleep is up here we print it again go to sleep again so this will be an infinite loop here is it is it obvious from this code that that's an infinite loop okay so with great power comes great responsibility so jystra wrote a paper on just how dangerous use of the the go-to statement is because you can literally jump anywhere in your c program okay so that makes your program next slide so don't use this in your actual c programs because the go-to makes the programs very difficult to read and follow okay so if we go back to that example you can imagine this is a very simple example and we have one go-to in there if you have go-tos all over the place it starts become really difficult to work out where the code is branching okay so go to makes it hard for the compilers to optimize the code as well and in general just don't use the go-to statements without good reason okay so we'll use this we will we use it in this course only for writing simplified c to translate into myips because once we get to assembly we need to use those labels and the go-tos um so in terms of simplified c how would we simplify an if else case okay so we have our if statement here and um okay so we'll remove our curly brackets and we'll have a go to there for the condition okay and we'll have a label at the end to tell it where so that way you can tell it where to go to okay the conditional inside the if as well we have simplified okay so we create a temporary uh variable here that performs this complicated n modulo2 operation and then our conditional is based on the result of that comparison okay start okay so now we can write it in mips i think we will skip that step i will leave that all as an exercise for you okay have equivalent so in terms of style for your myips code so have equivalent c code as inline comments if possible you saw me doing that a little bit today so that we could map the original c code to the assembly that i was writing okay huge recommendation indent with eight wide tabs what does that mean so whenever you enter a tab that gets replaced with um with spaces and eight wide means that your tabs will be show up as if there were eight spaces okay generally we don't in uh we don't indent to show structure because then we end up it it becomes very difficult to follow um we just use the um so we use no indenting for the loops um or if statements so oh sorry yeah we sorry we don't indent to show the structure instead we we just indent the we don't indent the labels so it becomes really clear where all the points at which our program will jump becomes and then it starts to become clear where these loops are loops or conditionals are so i mentioned this before for for this course focus on readability of your code you don't want to be in the last minute before submitting your assignment trying to find some some bug in your code because you made some micro optimization that reused the register or removed one line of assembly um so make sure that your code is readable so if you have a problem you can it's very clear where that problem could be okay so more complex conditionals here so if we have this if that has two conditionals instead of just one how would we simplify that how would we write simplified c okay we can actually split this into two goto statements and spaghetti wherever we want to go so if it's if milk age is greater than 48 then we go to milk replace otherwise we continue and then we have another condition there if the milk level is less than 10 we also replace the milk so you can see that chaining these two branches together um is like provides the that logic of the or between these two cases okay so what about if we have the and um conditional what if we have and well the and can just be converted to an or using de morgan's law so uh for de morgan's law we replace the operator with a the and for an or but then we have to not the conditionals and also not the result okay a little bit complicated but um you'll see in a moment so this and case here this x is greater than or equal to zero would be your a and this x is less than or equal to 100 would become your b so when we um convert this to when we simplify this and or when we remove the and um we need to invert the conditional so instead of greater than or equal to zero that becomes x is less than zero and instead of x is less than or equal to 100 that becomes x is greater than 100 so we've flipped it upside down we've taken the knot of each of those okay but then there was still this outside knot here and we've handled that by flipping the conditions around so whatever we had in the else statement now goes into the the um not the else part and whatever was in the like right after the if will go into the else part else part so we switch that around all right so i'll get you to have a have a go at this one let's turn this into simplified c only please right how did you all go crystal clear all right i'm going to use my favorite editor notepad while i use my favorite editor mixie zoom in nice we make it bold okay so this was our simplified c well sorry our original c so we need a label here um epilogue condition met oh not met and condition map okay and we split apart this if otherwise we go to condition not and then we can get rid of the else and here go to so when we're using the gotos we need to be really careful that we don't just let one section of our code overrun into the next se section of code so that was a bug i almost had i almost put in here i forgot that after we' executed the condition met code we need to skip over the condition not met code otherwise going to execute both of them so go to epilogue semicolons okay is that what everyone else got yes right so in the condition not met after we finish executing that that just kind of falls onto the next instruction it just kind of rolls over so that will automatically start executing at the epilogue anyone else so the answer will be in the slides if you need it later on um but there is a slight optimization here that can be made so does anyone see what that might be okay so why we check these two conditions yes go exactly yes so we have these these if statements that send us off to somewhere else and then um after we execute those if if statements we go go somewhere else again so why not just put everything that we were going to execute right under there i didn't explain that very well so all this condition not met code condition not met can come straight after the ifs and we kind of swap them all around like this right so after the if statements we handle the condition not met operations then we go to the epilogue and then we define what the operations are for when the condition is met and we execute the code for that i'm not big screen okay what about this one this one's slightly trickier to my favorite that's why i'm in a okay so in this case define our epilogue condition met condition not met condition met okay don't forget we need to go to the epilog here otherwise we'll also execute the condition not met code i'm sure that you'll forget to do that at some point okay and now it's just this if statement that we need to manage right so clearly we have if y is less than 10 go to condition met so what do we do with the rest there so now yes oral if y is less than or equal to 50 go to condition very close we not met that's right net okay and one more simple little problem okay we're now looking at zed instead of w uh instead of y but now that i mentioned w we do the same here so reversing the less than so reversing the less than inverting the less than we have greater than or equal to i much prefer putting it that way around okay so we have inverted the conditional and we're now jumping to the the alternate um the alternate branch of the if statement are there any questions on that yes doesn't mean um so we've handled all the conditions of the good question i believe we've handled all these conditions now and that we can just fall through to the condition there let's double check my cheat sheet yes we can so we've handled all the not cases i believe that's where it's come from we've handled this special condition met case and we've handled the not cases so we can fall through straight to the condition met okay this is going to be on the exam so if there are any questions it's going to be part of your assignment as well all right but we we have we'll have labs to support you there'll be u practice exercises and all of that okay so moving on to loops so for simplified c we really just want to use be using these if statements just like the branch state branch instructions that we get in mips so the for loops well we can easily break those down into while loops which is simpler than a for loop and the while loops we can break down into if and go to statements it's just that instead of going to code later in your program you'll be going to code earlier in your program so then you'll go back and loop through so the general structure is that we have a loop in it where we initialize everything for the loop we have the loop condition so when do we exit the loop the loop body what's this loop going to do and the loop step which we tend to forget in while loops how do we go to the next stage in the loop normally i ++ and then the loop end okay where's this end of the loop so for going from a for loop to a while loop we've brought that initial condition out right then we have the y loop and never forget that i++ otherwise your program will be running forever okay and then from there we get to this very simple thing on the right hand side okay okay when i said simplified c i didn't mean it looks nicer i meant we're using um less features of the language so that we can more easily can translate it to assembly okay so here is our init here so one thing to keep in mind is that these labels need to be unique right so if you have a loop you want to give it some descriptive label as to what the loop is okay i i to 10 is not so fantastic but it was the best i could come up with with a loop that was completely taken out of context for for everything so we have some loop some unique identifier in it loop some unique identifier con for the condition um loop identifier for the body loop identifier step for the step and for the end as well so here we initialize it here we check the condition and what happens if we fail the condition we go to the end of the loop in the body we do all the fantastic stuff that this loop was designed to do and in the step we move to the next stage of the loop normally incrementing i and of course don't forget to go back to the loop condition without that this doesn't become a loop all right so exercise for you sum of squares convert this to myips okay what's the first step we first need to go to simplified c i really don't want to use notepad let me move this out of the way i don't understand because it was quite easy to increase the font last time right there it is all right and i apologize uh it would be much nicer to have some syntax highlighting here i will work out what's going on with the terminal um so that i can we've had problems with the terminal it being fuzzy and that for the people watching online but notepad seems okay but i'll work something out for next time okay so first thing we need to do is turn this for loop into a while loop that's quite easy into i i equ= 1 while don't need the initializer still need the loop condition move the increment i = i + 1 oh yes okay so what's the next step we'll put in our labels loop sum squares end what's this one anyone what do we call this sorry start not quite it's the loop step right this is where we increment i and move on to the next iteration of the loop what do we call this part close body this one anyone anyone on sorry condition mhm or let's call it con for short all right and one more label in it that's where we initialize tempting to call it start right one other thing that we want to do when we turn this into simplified c let's separate the declaration of sum and the initialization of sum is everyone happy with that so oh wow what happened there let's clean some of this up let's clean it all up all right we will leave the the return zero in here so that we don't forget it later we don't need a data section at all for this one so let's make this code nice and maintain maintainable and remove all the clutter okay so let's start with some comments sum in t0 i in t1 okay so if we ever forget what all these registers are doing they're um we've got a comment up the top that tells us what the purpose of each of these registers is okay sum equals zero ldi whoops li [Music] t0 and there's our c code there so that we can always look at what this this assembly code is doing okay then we have our loop in it oops one oh no i forgot the while i still have to convert the while to an if don't i so the while becomes if i it's a nice easy um condition on its own okay but this is a while loop right so while this condition is true we want to fall through and keep doing stuff so we're more interested when it's not true so let's look at i is greater than 100 instead of i is less than or equal to 100 and we go to loop some squares end okay and that's what we can replace our while with right so back in mipy let's replace that so what's the instruction for i is greater than 100 branch greater than did i get that right um so we have a number of branch greater than but that's the one that i wanted um this one oh this is the one that i wanted sorry the other one takes an extra register so branch greater than uh so t1 100 let's leave that over there okay the body not getting much interaction today so who wants to have a go at the body okay well first we need i times i oh five minutes left first we need i times i so mole where are we going to put it let's put it in t2 because we still need the sum and we still need i so let's put it in t2 and i is in t1 up the top in the comment multiply with itself okay but we don't want just want to multiply i by itself we need to add that to the sum so add i not add i and the sum is what was sum oh it's up in top in the comment t0 isn't that handy and we will be adding t2 so add t2 with the sum t okay yeah we're accumulating just to make that clear sum already clear in the comment above all right the step how do we do the step some of you might have been thinking oh why did i put i= i + 1 why didn't i just put i ++ right sorry add and then one that's a good try but no we we can't actually do that in assembly we need to be explicit and say that to whoops we can't be that explicit that's why i expanded it to i= i + 1 so that the mips would even more closely resemble my c code okay and the loop end we don't need that in there okay yes oh well spotted at yes thank you so much i might have spent forever debugging this yes i did tell you guys that you would probably forget this and i've forgotten it myself yes we need to go back up to loot some squares con that's really embarrassing straight after i tell you guys you're going to forget it i forget it was there anything else i forgot can i'm i'm just going to say i'm putting these in here so that just to test you guys in the lectures yes go to online 12 sorry um okay so we've got the goto in here so we're checking the loop condition and then we're going to the end if that loop condition fails sorry that's right we don't it's implied in this instruction um but you this is why we write tests people this should be greater than or equal to right oh no greater than 30 seconds all right i think we have to leave it there unfortunately for today i just had a couple more slides to go through but we can cover those next time um do i have this code no i better post this code so the code for the sum 100 squares