 Hey guys, we'll come back skits on series. This is not the average episode This is a new new branch and I use that term loosely around comes up people a new branch off the tree of skits on Not an episode. It's a lab. So I'll talk about what that means in a moment. The topic today is going to be Kramer's rule. What's Kramer's rule? It's the way you can solve systems of equations and we're gonna implement Kramer's rule to solve a physical example a real-life structural analysis problem From scratch in x86 assembly. So if that interests you You can watch otherwise you can leave so Up until now in this series. We've done Exclusively episodes episodes are basically just us developing These library functions and these like elf headers and stuff to lay the groundwork for future software that we're gonna write And I have huge plans for this series And we have multiple different examples per episode looking at the same type of Concept from different angles and doing different things and it's been very enjoyable for me to make these different examples And all the code has been available. It's all on the soy hub suppository, but there's been no live programming This however is a lab video meaning It's gonna be a one-off executable We're gonna be leveraging and synthesizing content that we've already covered We're going to be using functions from our previous episodes we're going to be just using them to solve some particularly useful problem and we're gonna have a single main example per video and The code will be available, but the difference here is that we're gonna implement this in real time So I'm gonna do like live programming in assembly that you guys can follow along not live streamed But just in real time you can follow and the reason for this is because I was talking to somebody Over DMs a few weeks ago and they were saying even though they have they probably have a way more experience than me in programming And even in assembly it felt like they didn't really Know how to or how they would go about programming something from scratch in assembly like they would know how to use in line assembly They know what the instructions do they know kind of they know way more than me about anybody watching probably About the stuff, but they wouldn't know how to go about starting something from scratch And this series has all been about You know programming in assembly from scratch. We even have you know thrown away the linker I mean everything here is entirely from scratch So I figured hey, why don't we just make some videos once in a while every you know five or ten videos Maybe maybe a little bit less Or we just synthesize old content and we just implement something from scratch That's kind of fun and quick and one-off and we can kind of show that yeah You can program things in assembly by itself without see without in line assembly without other crap like that And you can make valuable software without having to use You know see or anything else so it's that's the reason for this little bit of a video here And also it's easier for me to make this video because I don't have to spend you know a full week um Developing multiple examples and all library functions and stuff. It's easy for me once in a while Just to take a take a load off and just implement something simple and and go through the theory behind it So today's topic is Kramer's rule and so I didn't know anything about that. I asked Mandarke I think isn't a Mandarke what it was and he says yeah, it's a method to solve a linear systems, so pretty much I mean if you're an engineer or a physicist or Math you you already recognize that pretty much everything is just a linear system and needs to be solved Electrical engineering mechanical engineering aeronautical engineering Everywhere you look it's all linear systems always has been and even when it's not linear you make assumptions To boil it down to a approximate linear system, and then you solve that That's the general approach to solving almost every problem that I've ever been exposed to in engineering and just Plug it into a linear equation solver and then and then go And so the good thing about Kramer's method or Kramer's rule or whatever you want to call it Is that it's very simple to understand simple to implement It's very elegant in my opinion and it has a very cool Geometric definition that relates very well to what linear algebra is I think the one problem about linear algebra is like at least when I was taught it in You know high school and in as you did middle school in the United States And in college like they don't teach it from a geometric perspective They teach it from like algebra like equations, and that's so bad because People don't know what it means like they don't recognize that like what a vector really is like when you're solving the system equations You're solving for you know scaling of vectors, right? But people don't internalize that until they get much older and if they do it all and so I think it's a shame that we Don't spend enough time, you know explaining geometric Understandings of these things. I think geometry is the coolest thing so the one problem with Kramer's rule is that it's not it's not efficient computationally. In fact, you're you're basically Doing things that you don't need to do in order to solve a linear system Like you're trying to solve for an unknown by going through a process that it would have been easier Just to solve for the unknowns in a different way But it you know sit that being said it is pretty interesting how it works geometrically It's very nice and honestly who cares about computational expense if it's so fast, you know for equations for it means systems of like n equals Zero equations. That's easy one equation two equations three equations even four equations I think you could do this by hand in a testing period for a college class like it's not unrealistic to solve n equals four systems of equations in my opinion so Yeah, for those things I think Kramer's rule was awesome I think it's intuitive and easy to remember and it's the algorithm is just so simple and straightforward It has an awesome geometric understanding that I think it warrants People knowing about so that's why I'm making this video. So when it comes down to Kramer's rule, it's basically just Parallelograms Parallelograms What is that? It's like a diamond shape like a rhombus, but the the two opposite sides are parallel so it's like a rectangle, but it can be skewed off to the side and You look here the area of a parallelogram is the same as the area of a rectangle Just the base times the height and why that works is because basically you just take this little edge piece and put it over here And there you go a rectangle, right? So that's why that works but the cool thing about it about these shapes is that the area is Only a function of base and height the angle doesn't matter And so basically let's say you you increased h by a factor of three well Then the area would increase by a factor of three exactly and if you increase the Base this length here by factor of pi the area would go every would go up by a factor of pi exactly Not approximately exactly. That's how it's defined. I'm not well. This is what it is And the other thing is that the skew doesn't matter so this angle here It doesn't make a difference I can have another parallelogram as long as the base and height are the same This parallelogram here has exactly the same area because the base is the same This value here is the same as this value here and the height is the same this value here matches this value here so the areas of the same not The skew doesn't matter. Okay long story short the angle here doesn't make a difference to the area and those two things are extremely important and that's the entire basis for Kramer's rule if you Know if you understand this you already understand the full the full way to solve these equations Now determinants are just a trick to compute the area So if you don't have base and height because remember these are kind of things that you wouldn't have like we're talking about Equations here. You don't know I mean, what does it what does it even mean? What is the base and the height? There's no meaning to that so typically what you'll have instead is you'll try to generate the area or compute the area with You know regards to the side length or the sides of the parallelogram So let's say this side and this side Basically, if you take the two vectors that define those two sides You can see here the bottom one. I've called that You know exit the X length is a and the Y length is B And so this column vector is just this side Vector of the parallelogram in a similar way, you know this side length here That's just the the X dimension is C and the Y dimension is D And so that's just this column vector and so basically if you take the determinants Which is just some kind of fancy thing of Those know the set of column actors that define the sides of this parallelogram or even in 3d. They have another equivalent shape in 3d In higher dimensions You basically get the area or the volume or whatever else in higher dimensions. It's called of this shape So in 2d you take these two two by two column vectors Take the determinant of that and that will give you it will spit out the area of this yellow shape Which I'm calling a in pink And the cool thing is is that the algorithm that you may have been taught already You probably were for determinants of a two by two or three by three matrix You know in this case it would be you know this diagonal minus this diagonal is what they teach you to do So ad minus BC that is the same as if you were to look at the Parallogram and then figure out the components of this area So this full rectangle here is The width is a plus c and the height is b plus d and so the width of the entire shape is this And then if you were to look at the constituent parts of this shape You have you know two squares of size or two rectangles. There's a of size BC. That's this you have two triangles of size DC so that's this one and this one and if you were to put them together that would be DC similarly you have a B Triangle two of them and add together. That's a rectangle of size a B And then you have the middle middle shape here is just recalling it a and if you solve for a and you do all the The checking here you can pause the video and take a look. It's the same So the definition that were that you've been taught for determinants ad minus BC is the same as the geometric Understanding that you'd had if you just drew a rectangle with the Parallogram inside and then just figured out how big the pink region is So cool and that extends to higher dimensions to 3d 4d 12d, etc. I think if I'm wrong about that, I'm sorry I lied to you Okay, great now Systems of equations so and this is where like I think it's important that we learn about the geometry We talk about the geometry because Like I think what is when I was taught we were taught this in there like an algebraic sense Like what what this equation means algebraic Lee? I think that's terrible I think that's like that's like throwing kids under the bus like you don't let them learn with it What the actual definition is mean kids? I mean, I don't know. I feel like maybe you can relate People are better at understanding geometric things like even the dumbest person, you know even dumber than me Understands like spatial things and I think like if you just illustrate things spatially it Connects way better with people's, you know thought process than if you just do with symbols I think symbols are kind of cringe. Anyway, so the idea is If you have a system of equations, which is typically written out like this a x equals b So a is a is like I said coefficient matrix So here I've drawn a 2 by 2 1 with the elements a 1 1 a 1 2 a 2 1 a 2 2 X is a vector of unknown. So these are what you're trying to solve for these are like the What yeah, what you try to solve for I guess is the best way to put it and then the right-hand side vector here B again is just in this case that two elements of known values And so the idea is you have some equation in this case. It would be a 1 1 x 1 plus a 2 1 x 1 equals b 1 and Then you'd have a 1 2 x 2 plus a 2 2 x 2 equals b 2 Or you can draw it out like this you take the first column vector times x 1 second column vector times x 2 and that sum is the Resultant now. I think this should be this should be taught geometrically. So here's how this looks, right? this ultimately is just two vectors that you can visualize as sides of a parallelogram and Yeah, so in this case the the blue column vector here is on the bottom and the pink one is on the left side But you know, whatever they happen to come out to be with if you plug in chocolate the values in whatever they happen to be gives you the shape of your parallelogram and the idea is What values of x 1 and x 2 can scale this side and This side not respectively. I said them backwards, but such that the sum of those two scaled vectors is This b 1 b 2 vector here So What's what what sum of? What values x 1 x 2 would you have to scale? This side by and this side by such that when you were to sum up all of the scaled versions of those vectors You would get you'd point to where b is pointing That's what simplifications are and we don't teach them like that, but we should I hope that made sense And so the cool thing is is basically here's another drawing of that basically so if if this side here was just the second column vector here Right, that's this side length and You scale that by x 2 now that points here And the idea is to pick an x 2 such that if you were to add This one and this one together you would point to where the b vector is pointing And so yeah, you're scaling both sides or if you had a three-dimensional Problem you'd have all three sides or you know n dimensions you'd have n You have a vector of length n that you're scaling by n different Unknowns add them together and that has to point to where the right-hand side is pointing so it's This is the equations. You're just trying to figure out what scale factors I need for all my different column vectors to point where the resultant is pointing That is not taught. I don't think in any productive way Anywhere I've seen it taught it's not been taught like that But it should be so in this sense solid linear system is just determining the scale factors in this case called x 1 And x 2 for the parallelogram sides, which is the columns of this matrix So that when you sum up you get the agnol B Cool now, how does Kramer's rule leverage this kind of geometry? Well, the thing is this goes back to that left-hand side thing that I drew before Where we said right here that the area of the parallelogram it scales Linearly with both base and height So if I just change the height Or the base The area increases by that factor. So if I doubled the height the area doubles as well Or ultimately the base if I double the base that it doubles as well an area. And so the idea is The area of this pink parallelogram Which is just so let me let me rephrase that so this side length here is Just a 1 2 a 2 2 that's the vector of this side of the parallelogram if I scale that by x 2 It goes here Now if the base of this triangle or parallelogram the the bottom here That is unchanged that value is always going to be that column vector And so the the the concept here is that the area of the pink shape is just x 2 Times the area of the yellow shape It's in a different sense this red Parallogram which by the way is defined with one of the sides as the the right-hand side vector is The same area so the area of the pink shape is x 2 times the area of the yellow shape But the area of the red shape is the same as the area of the pink shape And why is that it's because the skew doesn't matter remember that from before The angle here doesn't make a difference if I don't change b or h the area doesn't change And so back down here You can see the base is the same for both the red and the pink shapes It's the same value and the height is the same as well The height is from here to here Or from here to here and those are the same value so the area of red equals the area of pink and Those areas are just x 2 times the area of yellow. And so the idea is That you can basically write those Equivalences here so the area of yellow times x 2 is the area of the other two each and then I can Solve or I can compute the areas using the determine to determine it so Basically remember the determinant of the matrix with the column vectors of the size of the parallelogram is the area of the parallelogram And so here you can see the area of the yellow one is just the determinant of the original matrix a 11 a 21 a 12 a 22 determinant of that times x 2 will be the area of the pink and the red The area of the red one remember again the area of the parallelogram is Just the determinant of the column vectors which are the sides of the shape so in this case the bottom is the same Side as it was before this is the original Bottom here is the new bottom. It's the same now the left side remember it used to be a 12 a 22 Now the left side is actually this Which is b 1 b 2 and so instead of having you know a 1 2 a 2 2 which is here We have b 1 b 2 here as the left side of our parallelogram and so we just plug that in here and so now you can see we have an equation with Just determinants that we can use to solve for x 2 and This is what it is basically you just solve for x 2 there you just divide this Determinant or this area by this area right the ratio of the red shape over the area of the yellow shape Is the unknown value x 2 and this is the same thing for x 1 and x 3 x 4 x 5 if you had that high order problem, it would be the same So the way this works is you can see on Wikipedia. There's a you know just versus the synced algebraic definition With with the equation ax equals b basically the ith unknown So x 1 x 2 x 3 x 4 is just take the determinant of the coefficient matrix a If you replace the ith column of a with the column vector b the right hand side vector b And then you just divide that new determinant matrix The determinant of the new matrix by the determinant of the original matrix That gives you the coefficient The scale factor x i So all you have to do to solve for the coefficients is be able to substitute in rows or columns of matrices into each other Which is what ai is and then Evaluate the determinants and in our case we're going to use three by three determinants, which Is this and you may have learned this there are different ways to represent this, you know Geometrically you may have been taught like something like this and this you know, etc That's fine. You may have been taught cofactors. I don't know what any of that stuff means But basically all you have to do is take the elements in these positions Either for a two by two or three by three matrix And then evaluate them algebraically like this and you'll get the determinant And so we're going to implement this in assembly in a few minutes cool And now for our example and I could have picked an example for electrical engineering I could have picked one for this is a structural engineering problem. I could have picked one in finance I could have picked one in physics. I could have picked a thousand different examples. Um, this is just what came to me on google And here's how we're going to use kramer's rule You know for a useful piece of software and the question here is Solve or I guess the instruction is solved for the internal forces f1 f2 f3 in these members here f1 f2 f3 in the truss And so if you if you know statics you can just solve for the resultant Reaction forces here are one and r2 at points one and two based off an input loading of a hundred Newtons or whatever n stands for maybe neptunes. That's pretty heavy Um Yeah, so in my case, I just solved for r1 and r2 using you know moment and force equilibrium So I took the moment about point two is that it was equal to zero um, and then Based off the geometry here. This is a 30 60 90 triangle. I computed that the reaction forces were a certain value Let me go through that really quick. So A 30 60 90 triangle, you know for those if you don't know now you do that The short side is just half the hypotenuse. So if this side here was one Then this side here would be two Similarly, this is also a this big one's also a 36 90 triangle. And so in this case The short side being two the hypotenuse would actually be this value here would be four So what that means is basically that this reaction One is four times further than the input load A hundred newtons from point two So the moment equilibrium in order for that to not be rotating about point two You would need r1 to be one fourth what the input force was so in this case r1 is 25 newtons upwards And then by taking the sum of forces in the y direction, you know that 100 down 25 up, you know that you have to have 75 up at this point So r1 equals 25 r2 is 75 with that The question is now can we solve for f1 f2 and f3? The answer of course is yes But you have to do to do that you need to be able to generate three equations that involve all these three unknowns You can't leave any out Because if your equations don't involve f3 you won't be able to solve for f3 And so in this case I've taken the sum of the forces about point three which is at the top So it had that hundred newtons downward force as well as the internal force in number one and number two at their corresponding angles Some of the forces in the x and y direction Signing cosine here you can see just taking the force contributions in each direction In the x you just have f1 and f2 pushing in the x direction. That's this way y direction you also have the input loading And so here you can see the two equations about point three and then for These two equations actually you could use these two equations to solve for f1 and f2 you have two equations here And you have two unknowns f1 and f2 So you could solve for f1 and f2 with just these two equations But I want to solve for all three at the same time. And so we're going to generate a third equation This equation has to have all f3 otherwise we can't solve for f3. And so I took the force equilibrium about Point one which was at the bottom right of that figure here down here And in the x direction you have both f2 and f3 acting and you only have cosine 30 Fraction of f2 acting in that direction. And so here's the third equation and the idea is If you know what these trigonometric Expressions evaluate to in this case. I picked easy angles and so Sine and cosine of these values is is a half and these values is Approximately point eight six six. And so basically you can break those three equations these three equations And they're unknowns Into an expression like this So I've pulled the coefficients out of that Those set of equations into this left hand side coefficient matrix I've put the unknowns In this green vector here and I've taken the right hand side and I put it in red here And so right hand side meaning What these equations equal right so here the right hand side equals zero Here it equals positive 100 And then here it equals zero So yep, that's what we can boil down this physical problem to in a Algebraic sense and now all we have to do is use kramer's rule To solve for f1 f2 and f3 and that's the project of this lab That's what we're trying to do and we'll do that From scratch in assembly right now Okay, cool So we're going to start completely with the clean slate here. I don't even have the Suppository installed on this machine. So we're going to get everything from scratch You will need nazan nazan isn't an assembler That's what we use to assemble our assembly code and you will also need get to get the suppository And so I'm just going to get clone um The link HTTPS Get hub dot com Slash me slash It's own Okay, this pulled the suppository down. Now I have it. Let's go in there And when you download that you will have A couple things typically we do all our examples in the example directory and we do all our library programming in the lib Directory so if I show you what's in lib you can see I have a bunch of debugging functions I'll functions math functions memory functions system functions and timing functions And we'll have many more in this series as as time goes on But in this video It's a lab. So we're going to put things in the lab directory. So if we go into the lab directory Oh before I do that run the make bins Shell script. It's not a virus. I promise Well, maybe it is that just generates a bin directory in that bin directory is a bunch of Utilities that you can use one. We're going to use is make executable That just turns binaries from just zeros and ones to being Executable by the os just changed the permissions on that. So we need that For our software. So we have that function now So let's go into the lab directory And in here I have a template that we're going to copy. So copy Template and we're going to make a new Lab and you could make one either in here or elsewhere. I'm going to call mine 001 lab Lab this is your one famous rule You can follow along. You may have to change the name. It may be already existing by the time I upload this So you just make your own Folder And we'll go in there In this folder, we have two different files. One is just a template One is this is just a template here We're going to use this to generate to write our code. All it has is just a bare minimal executable. It just exits So all we have is just syscalls and exit and here's just the bare minimum Elf header that we can we can work with and also it has some Accommodation here for printing it because typically you want to print things to the screen So I left printing in the template and then we have our run shell script. So you need to have a bash compatible shell So basically all this does this is like a make file Basically, it just compiles our assembly code into a binary And it it calculates it computes if you're on linux or bsd and it includes the corresponding syscalls Um, and then it uses that make executable binary that we just created um to change that set of zeros and ones to being executable As far as the os is concerned and then it runs that binary. So that's all it does Let's look now into the code And this is dark mode. I don't like dark mode for these videos. Let's do Light mode Okay So we're gonna need a couple different things in this couple different things to include So we always have to think about what we're going to be doing um, and we have to include some uh Functions here, so we're going to need the Actually, let me open up my actual Thing here. This is the survive story. So let's see in live. We're going to need the We have to be able to print out our results. I want to print out an array of floats So i'm just going to snag This Yes, yes, yes, it's a virus. Thank you very much um So this function we're going to use that to print out our arrays of floats Let me just do that really quick. So it's in lib math No, live io Print array float Cool, we'll also need um print cars. So let me snag that Actually, it might already be included by this. Hold on. Let me check really quick Yeah, it already is included. So I don't have to bother with that include If you include things multiple times it it doesn't matter because we have an if def on all our Files, let me show you that really quick So if not defined this will only be included If you've not yet defined this value And so once you include this file once it will never re-include itself So you'll never gonna have a problem. We're gonna have multiple includes of the same file. Anyway enough about that um Print array float we'll need that one. We'll also need Uh, we'll need mem copy and matrix insert column So we'll need mem copy to copy our our matrix. I'll talk about what that means in a second. I'll just include this really quick. So Mem copy I'll snag this You have to forgive me. I'm not the best uh Vim user I know the bare minimum enough to to break stuff As they say Mem copy we'll use that to copy our matrix back and forth into a temporary location And uh, we'll also need something to math Matrix matrix insert row Oh, no column column. We have to be able to insert the right hand side vector b into our Matrix a so we need this function. Let me snag this Yes, it's dangerous. Thank you very much Include lib math Matrix matrix insert column asm Okay, that's all we did. I think for this program Just those couple functions. Oh, we have to make a function We have to make the determinant function, but we're not going to make that in the elegant way I'm just going to parkode that right now So we'll have a function called determinant three by three and we're going to program that in a minute I'm not going to waste time right now And then we'll also need Some values. So I'm going to have it written down here the uh The matrix coefficients. So we'll we'll need the a matrix we'll need a A Determinant like a temporary matrix where we're going to put in the right hand side vector To evaluate the determinant We'll also need the right hand side matrix b and we're going to need a spot to put our solution x And so the solution we don't care that's just going to be So let me show you This this solution vector here. That's just three Double precision numbers. So each double is eight bytes. So this is going to be 24 bytes of space I'm going to define it as times three Dq 0.0. So it's going to initialize it basically to be three Zeros, so it'll be zero zero zero. That's going to be the initial value The Right hand side vector here. I believe it was zero Let me put point zero 100 zero Let me check Yep, zero 100 zero again. It has to be a floating point. You have to put the point zero to make it floating point Otherwise it will just be an integer value Um eight bytes long and then I'm going to I'm going to put this value into the A memory location So up here and again, I should say even though it's a vertical vector B was vertical. I I can define this like this. I could say dq zero dq 100 dq zero, that's fine, too It's just the same thing. This is exactly the same meaning as uh this what I had before And so I like this. It's a little more compact easier to read. Anyway, um for our a matrix I'm going to plug in those values. So we had a dq zero point five Negative and this is approximate zero point eight six six zero point zero And we had the second row was zero point eight six six zero point five zero point zero And then our last row that was uh zero point zero zero point eight six six Need a comma there one point zero That's our right hand. That's our uh coefficient matrix and now we just need a holding spot Into which we can copy our a matrix and then replace each column into the a we'll use this ai memory location So I'll say times nine dq zero point zero. So I'm just going to initialize it as a nine element double precision floating point memory chunk Cool, those are all our input values and that's all our working space for Our store leopards rom I should say for uh Our our program Okay, I shouldn't have said that that was really bad. Um Now let's implement our determinant function. So we just need the hard code basically This This mathematics Into assembly So how can we do that? Well, I will show you how we can do that Before I do that, let me um Put some Some comments here. So this function It's going to return in x and m zero. That's usually how you return floating point values. That's how I'm doing it at least Um, and it's called the terminate three by three And it will only take in one input and that is the address Or a pointer to the first address because we're going to assume it's always going to be a three by three matrix That's why it's called determinant three by three um in rdi What does this function do this function? Uh returns the Determinance of the three by three double precision floating points matrix at starting at rdi And I'm I don't care so much about the calling convention for this example. Normally we try to preserve all registers. I'm going to say um Likely violates I'd say it will violate violates calling convention By clustering probably we'll call our x and m one Okay, so that's Sort of like if you were using c that's how you would refer to this function If you were to include this in a c header file, that's what you would write. I guess So in this determinant function, we need to be able to basically just do the math that was described here And so basically the way this works is the address rdi points to element a so this is at address r di Element b is that r di plus 8 And so on so c would be 16 offset d would be 24 offset, etc, etc, etc And so we're going to just implement this using floating point arithmetic based off offsets into our Array that is just known because a is always going to be zero offset F's always going to be 40 offset for example. Okay, let's implement that So first thing I'm going to do is I'm going to use um x and m one to compute those intermediate multiplications. So I'm going to use basically X and m one to compute this and this and this and this One at a time I'm just going to add it to x and m zero to keep it running some so our sum Of all this will be an x and m zero and x and m one is just going to track each individual term in this addition Okay, so first thing we'll do is we'll move Into x and m one the a value such that rdi plus zero That's a Then we will multiply Against a the next value in that term. I believe was e so a e And e is offset by 32 Then We're multiplying that by it was i let me show you before I get too far here So basically I was just taking the offset of element a element e and element i From address a and register rdi which we're passing into this function to basically Compute the multiplication of this term here and then once I have that By the way, I is that address? oops 64 it's the last last one And then we're going to just move that value into x and m zero So x and m zero comma x and m one we're going to save that term that that multiplication Is just going to be x and m zero that's going to give us our first Part of this running sum in x and m zero cool Now Let's copy this Five more times one two three four five And we're just going to compute the other terms so Term Two that was b f G Term three was c d h Term Uh four was c e G i'm just copying my notes here b d i and the last one was a f h Now we have to adjust these instructions because they don't match anymore So um first let's adjust the offset. So the offset to element b is not in zero. It's eight Then offset to f is 40 offset to g is 48 Offset to c was what's uh 16 I guess Offset to d was going to be 24 based off of that and then h it looks like it's 56 That's one before i Um offset to c again is 16 offset to e we have that already don't we 32 it's right there and then g was 48 And then offset to b again is eight d is was a 24 And i's last one that's 64 and then a zero f is 40 right 40 and then h is 56. That's the second to last one All right, that gives all our offsets correct. We're using the right terms now, but the um instruction is not correct Um for this so in the first case so basically let me show you We now Are computing for each of those steps the correct value of x m m one But each time we're just moving it into x and m zero. I didn't change that instruction yet reality The first one should be Move then we should have an ad instruction ad instruction and then two and then one two three subtract instructions So let's do that really quick So move then add Add Subtract Subtract Subtract That should now I return That should compute the determinants. Let me just make sure I didn't do anything stupid Yeah, that should compute the determinants Okay, just making sure really quick before I make a fool of myself that that matches that should compute the determinant of a three by three matrix Based off this Algebra that we're showing here okay With that out of the way now we can actually Do kramer's rule We have our our underlying function complete now. Let's do kramer's rule and so I should point out This is an address Determinant there by three is an address of our executable and when we call This function is just going to be a jump to this address after we push the return value on to the stack so Basically start is where our program starts and that's Evidenced by in our header file in our elf header You can see our entry point is that start so when the os loads our program it will jump over everything It will jump over the help header. It will jump over all of our includes Which are just copying pastes from other files It will jump over this determinant function that we just wrote jump over that whole thing to start If to excuse my uh swung word cat in the background So now Let's do some uh Some kramer's rule here. So the first thing we want to do is we want to be able to compute the determinants of a for the original matrix hey To do that all we do is we move Into rdi remember rdi is the input Into our function here It's our offsetting Address so we're passing into this determinant 3 by 3 function the address of our array the first um You know bite the first double and that double here is At address a a colon is just an address So we can move into rdi The address called a Then we're just going to call determinants 3 by 3 and what that does is uh this Uh puts Into xmm 0 As we just wrote the determinant of a And then i'm going to save it into xmm 15 or something just to keep it safe i'll say xmm 15 Equals determinant of a cool that basically This three lines which is actually Calling a much larger function that we just wrote that Basically does This it computes the denominator for all of our evaluations That is this determinant of a is what we use to compute the Division here for every unknown xi Great So now we have to Compute the determinants of the other matrices so The ai's and what is ai remember ai was just the a matrix the original a matrix with column vector b dumped In the corresponding column Okay, let me go back So now let's uh generate a One which is a With column vector b I'll say with b for column one To do that the first thing i'm going to do is i'm going to use that mem copy function To copy the original matrix a so i'm going to move into rdi ai the destination address i'm going to move into rsi the address of the Source that's what usually rdi you use for the destination of something and source is for the source So in this case we're copying from a to ai and how many bytes are we copying we're copying eight times Well eight bytes times nine elements or 72 so move into rdx 72 and this will will uh ai Now contains a So just to go over that again mem copy was a function that we've written previously you can see it takes in um two pointers to To two memory locations and then all you do is you pass in rdx How many bytes you want to copy and it just copies bytes You know one by one or four by four whatever it is eight by eight maybe from rsi into rdi So that's what this part of the uh the code does So at this point the ai address down here, which originally was all zeros remember times nine zero now it contains a So literally exact copy of a will be in ai now um We were going to use our matrix insert column function to insert the column vector b into the Vector to the matrix ai and so Move into rdi ai Man i have to do that it may already be in ai it may already be in rdi But i'm going to do it anyway just for complete sake move into rsi the vector b right hand side vector b Move into rdx I believe this is these are the size of the Matrix ai so rdx is the number of rows rcx is the number of columns. I think we programmed that in um And then the r8 contains the destination column and so in this case Column zero is actually in you know in my definition column Column one is column zero so moving basically moving vector b moving This vector Into this column That's what we're doing right now So to do that move r80 and uh that should that should work Now let's uh Well, okay, so at this point. Let me see what we have we have a ai Now contains what we're calling a1 or what Wikipedia was calling a1. Let me show that again really quick So this now we contain a1 and now all we do is we to get the determinant of a1 And that's the numerator for our division And we just divide that by our old value of determinant of a which we save the x of m15 and that will give us our result Our solution uh x or that scale factor x Okay, so let me just snag this really quick and paste Move that call determinants I'm going to just get rid of this no use Just repeat that and then i'm going to divide uh x of m zero by x of m15 So now so I should have that x of m zero Contains determinant of a1 We're dividing it by x of m which was our original determinant value and then we're moving it into we'll say Address x offset zero. This is the zero element of our solution vector um x of m zero Okay, so that that will generate for us the Uh the first solution let's repeat that for The second and the third So just copy and paste that really quick generate a2 column two Just change the comments really quick column three a three determine a three Now the offsets are going to change element three is 16 bytes offset element two is Eight bytes offset and then the the column that we insert is going to be different So r is going to go from zero to one and from zero to two That should just work So now we have to print out our results. So Let's see to print out stuff say Print results print x vector So we move into rdi the solution vector address and we uh Oh, sorry, we move into our rdi the standard output Then it was the source is the x vector address uh move into rdx the um Number of rows which was three rcx is the number of columns. That's one Um, what else is there? Oh, there's no extra offsets. So x or r8 r8 r9 contains the The formatting of our print we're just going to say print float And then uh Number of sig figs is going to be in r10 And now we're going to call uh called print Hooray floats and this should just work. I hope this works. If not, I made a mistake Hold on a second here That that looked right to me um Let me put a a new line here really quick. So move into rsi Have a grammar move rdx one called print cars We'll make a grammar Line here. I usually do that db Will that make it look better? no well, uh Either way I I think the uh the result is correct Hold on. Let me just check for the quick to see if I've made any terrible mistake here Maybe my uh numbers Incorrect That all matches Just bear with me for a minute here The number the answer is correct. I'm sure why is not printing out, right? What? Oh, I I'm so I'm retarded Ugh I have to flush the print buffer. I'm so dumb Okay, um I don't even need this Like thinking myself what's going on? Why is this wrong? I guess you can see me trying to debug something in real time You don't need to have that so um Flush print buffer novice mistake Um rsi I'm not even just I'll just say call Right that's what it is There we go And actually let me go back and let me change that to more safe there so we can see Yeah, so These are apparently the solution to our problem. So x1 is 86.6 x2 is 50 and x3 is negative 43 interesting Very interesting Which yeah would suggest that going back to the picture f1 and f2 being positive numbers means that yeah our assumption that they were under compression is correct f3 being an a number means it's under under tension, which makes sense if we're pushing down here These members are going to be in compression And this member if that's in compression, this is going to be in tension to oppose that Which makes sense without the signs and if you plug in the numbers, I'm pretty sure you'll find that's the case In fact, let me open up octave. That's why I love octave We can Uh put in those values and by the way, I already did this here are the same coefficients that we just uh implemented in assembly In vector a now right hand side vector again was 0 100 0 that's going to be vector b And then in octave or a matlab to solve these you can just do a backslash or whatever that is b And you can see here if I Uh Quit this Those values match What we computed with kramer's rule ourselves from scratch in assembly And so yeah, there's just an example this video has been an hour in the making I included a little bit of a head scratch here there at the end, but thankfully we're we're through it Um, I hope you enjoyed this video. I just wanted to show that yeah, you can make completely functional software to solve real engineering problems In assembly without having to use c at all No, no c whatever in in the tool chain unless you count nazm unless you count the os. I mean Whatever you want to do, but yeah, so this was kramer's rule. I hope you enjoyed that Little discussion there And I hope you enjoyed this idea to have little a few labs now and then we just take previously existing code apply it to a new problem try and uh Make some valuable computations that are meaningful in some way and have fun in in doing so If you've watched this far, I would I would invite you to our Secret discord server the link at the bottom of the description Um, check it out if you're interested. We can hang out. It's a couple of us there. We're pretty active Um, and thanks for watching. I'll see you guys