Learn Assembly Programming Language Fast | Lukas Vyhnalek | Skillshare

Learn Assembly Programming Language Fast

Lukas Vyhnalek, Microsoft Employee, Programming Teacher

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
23 Lessons (54m)
    • 1. Motivation

    • 2. First Steps

    • 3. Strategy

    • 4. Assembly and HL Programming

    • 5. Inline assembly

    • 6. First Instructions

    • 7. First Excerxise

    • 8. Other Basic Constructs

    • 9. Different Types

    • 10. Instruction Definition

    • 11. Conditional Jumps

    • 12. Basics of structured programming

    • 13. Registers

    • 14. Addressing

    • 15. Stack

    • 16. Flags

    • 17. Conditional Jumps 2

    • 18. Other Instructions

    • 19. Optimalization

    • 20. Branching

    • 21. Cycles

    • 22. Stack 2

    • 23. Recursion


About This Class

Assembly is a historic programming language, but when you write a program in Java, C# or any other programming language it is translated into Assembly and then Assembly code runs on the processor. So even though Assembly Language is not commonly used programming language. It is still important to know How Assembly works and How you car write programs in Assembly.

In this course, you will learn How Assembly works ( if you learn how assembly works, you understand how the microcontroller works ) and that is useful even if you program in Java or C#. We start off with Inline Assembly, and that is Assembly code wrote inside C/C++. I choose to do so because I want to start simple and then move on to real Assembly.

I Explain Important Concepts such as Registers, Stack, Memory Access, Jumps, Conditional Jumps. And inside this course are plenty of exercises on which you can practice and improve your skills. And if you get stuck or if you don't understand something You can always reach out to me and ask, mostly I respond the same day.


1. Motivation: most of you probably never wrote any assembly program, and that is OK. These days, assembly is not so popular. But even though it is historic language, it is important if you want to understand what is actually happening inside process. Er, if you understand how assembly works, you will also understand how process or work and that is useful. When you write program in pretty much any programming language, it's always runs on some process. Er and the doorways. It's some set of instructions which correspond with program an assembly. So how Assembly program looks like Well, here is one. Yes. Hey, bed, you look something like this, but this program is actually pretty simple. It just computes absolute value off some variable A. And in this curse, you will learn how to create programs like this. And with that being said, I will see you in the curse 2. First Steps: in this section, we start programming in assembly. And since it is complicated language, I won't go through some details. I will get back to them later in this. 3. Strategy: In order for you to be able to write assembly code, it is important to start with the right strategy. If you want to solve some problem in assembly first, you need to understand the problem and be able to solve the problem. In other words, create algorithm solving that problem. You can, for example, use solution from other programming language such a C or C plus bus that you can only use construct and statements that we can convert to assembly. But if you don't know how to solve the problem, you won't be able to solve it in assembly. For example, if the problem is that you want to reverse a string, then we either know how to solve this problem in other language. And then we can also solve the problem in assembly or we are not able to solve the problem and then the study of programming language changes to study of algorithms. And while we cannot find the algorithm solving this problem, programming and assembly is useless 4. Assembly and HL Programming: As you saw in the Motivation video, our first program in assembly was not the usual whole world, but much simply, er, program on computing the absolute value off some number. Why's that? Well, how world in Assembly would be too complicated as the first program assembly cannot work with strings and mostly it have no instruction for branding something on screen. And because of Dad. Because even simple programs can be complicated and hard to write. This girl's start with something called Inland Assembly and what it means. Well, it ISS assembly code, which we right into some higher level programming language. In our case, it will be C plus plus you can also use see, but you cannot use some modern language like C Sharp or Java, because they aren't allowing to insert assembly code. If you have any questions, just ask, and I will soon except 5. Inline assembly: in line assembly, ISS Assembly Road and said other language. And there's a first example. Let's use our absolute value computation. But this time it is wrote inside steep plus plus function. As you can see, assembly code is defined by underlined A s m. Another thing you can see is that assembly can use variables defined in C plus plus, So that is a good thing. Bad thing is that an assembly, we cannot define functions and we also cannot directly return of value. So that is why there is this line move to value and value is variable in C plus bus, whatever is stored in E a X register. So you may also notice that on every line in one instruction and by instruction, I mean this move or TMP So basically this first word, then there are prayer meters. We can also kill them operates. And as you can see, the number of operations depends on instruction. In general, instructions can have from zero to free operations that an order for computer to be able to execute your code, you need to pass the right number off argument. For example, if I have here only move and then as argument e a X. Then I would get some error because computer wants to know what moved to this register. Another important thing to note is that some computing instructions like, for example, at were always store the result of the operation to first operate. And and that also means the value that was in first operandi will be overridden by the result. And I will talk more about it in lectures later on. So if you understand everything, great, if you don't just ask, I will try to help you and I will see you in except 6. First Instructions: So let's take a look at first instructions. Obviously, we started with the simple one, and here they are. Important thing is that assembly is not case sensitive. So it doesn't matter whether you right and lower or upper case notice that every instruction in table is some arithmetic instruction, which also contains assignment Inside. These instructions also exist in high level programming languages like Java or C sharp, and in assembly they were the same way as in C shop, for example. So if we want to assign value in CPAs, bus or C sharp, we use equal side an assembly we use move similarly with other instructions. Also, you may notice that multiply and divide is a bit complicated. For example, we can move over to operations that we can also killed with only one, and I will get back to this later in this curse. Now you might ask, why is there always some assignment, operation and instruction? Well, it is because of our computer works for human, it is natural to can like a is equal to B plus C. Sadly, computer cannot perform instruction like this because he don't know what to do with the result off B Plus C before his story to a. Also, all the variables are stored in one memory. Off computer and computer can perform on Lee one operation at the time and because of that , this is important in one instruction. We can address memory Onley once, but thankfully we can star values in local memory. Off processor inside of processor is small memory that is where registers live. So that is the reason why working with registers is so fast there directly inside process er but apart. That register works the same way as variable, and you can already saw registers in my code. The four basic registers that are used for computing R E a X e, b x e, c x and e the geeks. I will talk more about these registers later on in this cursed. So now we can write Our A is equal to B plus C, so we need to star be in some register. So move e a x b. Then we can add to e a x C notice that I go to memory on Lee wants in this instruction E a X lives in process er so I go to memory Onley for C variable. And after this instruction, we have in the A X B plus C, right, and then we need to assign it to a and we simply do that using move instruction, and that's it. So the sun things up every word with memory is more expensive than work with registers. We cannot do, for example, move a B because we would go to memory for a that we would also go there for be. And that is a problem. If you don't understand something, just ask, and I will soon except 7. First Excerxise: knowing these basic instructions, you can write simple application. So first exercise is to write function for power. So here's the function User passes indeed your value X And inside this function in the A S M block which indicate in line assembly, you want to return X times X and this function returns X so you need to compute X Time X and then move the result two X. I suggest you pause the video because in few seconds I will show you how to do that. Okay, so we need to move X into some register because we cannot do X time X So we moved to e a X . Whatever is in variable X, then we do Imo instruction and we passed their e a eggs register and ex After this line, we have in e a eggs register stored X Times X because I m o take the first operandi and multiplied with second and Sordi result into first and then all we need to do is smooth two x, Whatever is in e a X register and we are done also the CPA's Baskin pile er natively returns e a x. As a result off functions, so I kinda lied there. We cannot return value from in line assembly. We can bar. We cannot do it explicitly. So try to remove the return statement and this move statement and see what happens. 8. Other Basic Constructs: So you are under instructions that work same way as in C plus plus firstborn ISS comment An assembly we use Sam Accord and commence in assembly are essential Since killed an assembly is really hard to read. You need to put as much comment as possible out of rice. You will get lost over time. Another instruction is jump instruction and killed. Will you write just J. M. P. And it is equivalent to go to in C plus plus. And if you ever heard off, go to you probably heard something like, Don't use it. And I absolutely agree with anyone who ever said that because it makes he killed hard to read. But an assembly we need jumps and what it does well, when this instruction is executed jumps to some label where the name off label is passed as operate to jump. Then there are capital of memory. Working things first is reference in C plus. Plus we write and sad, and it returns address off some very Evelyn memory. In assembly we write Offset. Another one is the reference in C plus plus we write star an assembly, we write squared brackets and this operation basically asked for variable at some address than there is these type conversions in C plus plus, we can do heart conversion to one byte value to bide value or four byte value. And we can also do that. An assembly using Bite BTR, World bt R and D word PTR and there is pretty much it I will see you in the next lecture. 9. Different Types: Let's stop for a while at conversions in assembly, there are couple important differences from C bus Plus Assembly doesn't care about data type like our or in teacher assembly only cares about the number of bytes off some variable . He doesn't care if you get to get her to different types, if both at same number of bytes. Thanks through this, mostly we only need free types that you saw in previous lecture. It was bite word and the word conversions using PTR bricks only for work with memory. It cannot be used with registers. And we should use PTR only when we want conversion from bigger to smaller type. Because if we would like to convert, let's say one bite to work, which is too bad. Computer doesn't know what to put to the additional bite, so he would end up with some error. In the case of full numbers that we use an assembly, the conversion basically adds or Kautz some number two different number of bits when converting to more bits. We want the value to say the same right. We only want additional space about We want the value to stay the same when we are carrying some part. We cannot expect the value to be the same because we are getting great off some bits and if they are not equal to zero, the value will not be the same. Since these operations are executed directly inside process er assembly acts like the same s high level languages. For example, if we convert minus 1000 to die bite, we will get plus 24. So we are reducing to smaller type no matter what these sign off. Our number is when we are working with registers, we just use smaller part of register. For example, let's say that I have car short and into vary of us and since car have length of one bite short, have length off, two bites and end have linked the four bites we can convert. These variables using PT are also, as I said before, we can use only smaller part off registers. So, for example, e a eggs have four bites, but we can also excess only to lowest bites in this register using a X, and we can no so excess lower bite in a X, using a l and higher bite. Using a age and This works also for a V X a Sikhs and 80 ekes, so we can set lowest bite in E A X. Too low is bite in B two variable, and that is not a problem. Both of these operations should have same length. Also, we can take two bites from P four and store them in a X that will also work. And we can also take the lowest bite from E B X and move it to be one. There is nothing wrong with that, similar with B X and B two, When we start to add some bits to unsigned value, we just add zero to every new bed. That is very easy operation, and it can be done using either move that X instruction that works the same as move. But it allows the first operas to be bigger than the 2nd 1 All higher bits are didn't set to zero, and the second bus civil way is using registers. For example, we want to star B l into E a X. So first the SAT E a x 20 and then we set a l to be out and that's it. The problem comes with signed numbers. Why? Well, we are using additional coat for representing negative values, so every negative value have won in its highest bid and also in every unused bit. The algorithms that takes care off adding bits to value is defined by additional code. Thankfully, we have instruction that takes care off this problem. It is guilt move as X, and it works the same as move that x bad. This time it works also for negative values. So here are some examples. Let's say that we have the same variables as before. So using move as X, we are able to move signed byte value that it's stored in a l 24 bide very ever be four. Similarly, when we are moving to some register, So, for example, I can take bite that is starting p one variable and move it into e a eggs using move as acts. If you don't understand something, just ask and I will soon exam 10. Instruction Definition: in next few lectures, I will talk more about instructions into details, and I will tell you what can't and how many operations instruction takes. Also, what instruction does and what earth mythic flags it sets, even though I will talk more about flags later on. The best way to understand types off operations is through examples. For example, move E A X to any free first up friend in our case is register, and 20 free is just number, as you would expect. Next example. Move E X X is pretty much the same. First Opara End is register again, but 2nd 1 is of type memory. And, as I said before, move A B cannot be done since a ISAF type memory and be also but for example, move X 20 free. It's possible since X is memory type about 20. Free is number 11. Conditional Jumps: we are dividing jams into conditional and unconditional unconditional jump is equal to go to instruction from C plus plus conditional jump is different. This jump happens on Lee if some condition is true, so conditional Jump is basically if statement from higher programming language, it never jump instruction. We have one operation and that is name off Sam, a label in our program. So let's look at first conditional jump instruction. It is go G E c X Z, and this instruction jumps to label it register E. C X is equal to zero. Also, this instruction sets no flags. So to sum things up, we have conditional and unconditional jumps. Conditional jumps are almost like if statements, they are used to bridge the coat and they are very useful. I will talk more about it later on and hopefully you understand everything if you don't ask me and I'll soon except 12. Basics of structured programming: structured programming is of a of writing code. It is used, for example, in C Plus Plus, or C sharp, and it brings clarity into code and it reduces errors. And that is a good thing. An assembly you can write code in a different way. So that is why it is important to mention how to write programs the right way. The structured way Imperative Programming Languages describes program as a set off instructions, and these instructions are happening one after another. Also, we have tools to control which instructions are executed. For example, if which can decide what part of gold will be executed based on whether some condition is true or not, another instruction is go to and using these instruction, we can move the execution to some other place and structured programming brings clarity to coat by forbidding the instruction. Go to instead of go to we can use if condition while cycle which loops while some condition is true. And third dysfunction which we can call, and after Dicle, we continue with next line. These three things are essential in new programming languages such a C sharp or C plus plus , but since assembler is a story language we don't have if or while And we can jump whenever you want. And that can make the code. Really? Massey. So that is why you should forget about that and try to follow the rules of structured programming even though you kind of have to use jumps. I hope you understand this. If you don't ask me and I will see you next, Sam. 13. Registers: As you know, from first section every process er have in her memory and in this memory registers lift. We already know four of those historic processes, such as 80 51 had only one register like this and that Waas the accumulator later there were added other registers. The letter e at the beginning of names says that this register is for 32 bits. Without this e character, we would get 16 bits registers, but we still use the same register on Lee without E, we are using Onley part of that other two registers that we can use our e s I and e the eye . These registers used to be used for indexing as I stands for source Index and D I for destination index. We can also excess lower two bites of these registers by removing the e letter. But we cannot split these registers into bites like a L or a H. This is not possible with these two. Another two registers R E B O and E S B. These f same properties, but they're used for different purpose, so we should not use them for common computing. I will talk more about these later on. Lastly, I want mentioned to system registers in register E i. P. It's sort address off currently executed goat. It increments as process er evaluates instruction. Or it can be changed when function is gold or something like that. But we cannot directly excess or read this register using, for example, move. But we can change its value with conditional and unconditional jumps. And last register, you see flags. This register contains flag information. I will talk about that later on. Also, for different types of operations are is different registers. It is not necessary about in Mexico more clear. So when you're working with registers, give this in mind. When capping block of memory. Use he as I as a pointer for reading and e v I as a pointer for writing. Also, you can use E B acts if necessary. If you're function, have no local variables nor input para meters. You can use at the fourth register E B B for indexing. Garay's use e b x. Mostly you will be adding es i two e b x or e the I two e b x for any other operation that doesn't involve working with memory. Is these registers as last option as a counter in cycles? Use E c X for more cycles. Use E C X for the inner cycle and any other registers for outer cycle. For Mathematica operation, use E a X, and as an alternative, you can use e the X. If you are working on Lee with bites, for example, car data type. Don't be afraid to use part of register. Then way you save yourself whole register. You can use variables only if all your registers are full, and with that being said, I will see you next SAT. 14. Addressing: addressing is important, and you will use that a lot. So let's get started. If we know the exact place in memory that we want to work with, mostly global variable, then we use its address or name off. This variable instruction, like Move A 20 free, have its first operandi as name in memory. So in machine coat, it would look like this Where, instead of 123456 is some address where variable a ISS. I noticed that A is same as a in squared brackets, compiler or medically adds D squared brackets, so we don't have to worry about Dad if we don't know exact address. For example, when we work with pointers, race or objects, we first calculate the address store the result into register, and then we use square brackets and insight. We have our register like this. There's instruction sets E a X to value from memory space to each e. B X is pointing. Next option is indexing. This is guilt. When you are working with a race, for example, move E a X or X squared bracket, and inside them E B X ray is the name of global variable and DB X is defining the position or index if you want, but you should use this notation where you at the value off e b X two array and why you should use this. This notation describes what computer is actually doing, he adds e b x to address off our array. Then he takes the value from this place and moves it to EA X. Also, when we are working with a race which contains element off type longer than one bite, we use something called Scale. So let's say we have our A off in teachers and we want to excess element on index for since if we add to our array for it is the same as if we had four bites. But since indeed your value have four bites by adding for we would get to second element. So we need to multiply. The index with something called scale and scale is just the size of one element. So, for example, with in teacher and would be four because indeed your value have four bites. Also noticed that in this example we are using a X to compute the address and then we are using it to store devalue. And this works just fine because computer first computes the address and then it sets E a X . I hope you understand everything. If you don't just askin, I will see you next time. 15. Stack: every process er apart form access to memory have also something killed. Stack In this section, I will introduce you some basic instruction for working with Stack and later on in discursive. We will get back to this when I will talk about recursive function. As we already know, Register E s P is pointing at stack. Last added value is directly on address E s B. Next one is own address E s B bus for and so on. That means we can easily excess the values on stack using square brackets. But we also have instructions for this kind of work. 1st 1 is called push and it pushes some provided value to stack and this is a bit weird. Even though he are pushing, let's say one byte value on stack will be start four bites. Also, this instruction is not setting any flags. Next instruction is pop. This one is called when we want to get value from stack and we can use these instruction multiple times. For example, if I write pope E, a X value from TSB will be start in the A X and then yes, b will move four bites up as So if I go up up again, I get kind of second value from Stack. I hope that makes sense. If you don't understand something, just ask, and I will soon exam. 16. Flags: the construction off assembly language depends on machine code of process er so it is a language which is heavily in fluent ID, by fact, that processors are mostly hardware components. One of the basic attribute of hardware is that it easily realized barrel operations. One off programming concept that used this ability is flag. Every flag is represented by one bed register in process er, all flags come together in one big register where they are representing age bit off this register, for example, in X 86 processors, every flag is placed in 32 bit register cult E flags. We can read this register whenever you want, but we can set on Lee part because some flex are from safety reasons protected and they can be changed Onley by operating system, we can split flags into two groups. First is control flags. They are controlling behavior of process er, and they can be mostly set only by operating system. Other group is arithmetic flags. These flags are primary for reading, not for setting. The venue of this flag is set by process er, while it executes goat, mostly we care about arithmetic flags. These flags are set based on the result off. Some are thematic operation but also a lot of different operations. And using other instructions, we can read values of these flags. For example, in conditional gems, you already saw instructions like this. The first program is saw was absolute value, and it uses this conditional jump. First. It compares E a X 20 and this instruction also sets Earth Medic flags. Then we read the value of these flags. And if they're set correctly, processor jumps to label other rice process or continues with goat execution. I hope you understand this. If you don't just ask, and I will soon excite. 17. Conditional Jumps 2: these instructions are really useful. Unlike jump instruction, conditional jumps are executed on Lee if some condition is mad and the condition is defined in name off instruction apart from G E C x Z, which I showed you before, every other conditional instruction is based on flags. So here are all the jump instructions and I won't bore you by reading these. So these conditions allows us to branch our code. It allows us to use if and our assembly killed and that is essential Onley. One thing you should be aware off is that we have unsigned conditional jumps and side conditional jumps. But that should not surprise you because in assembly we have to deal with additional coding off numbers. So that is the thing about low level programming languages when he use java. You don't realize how these things actually work, But when you use assembly, you understand everything 18. Other Instructions: In this lecture, I will show you some instruction affecting flags. 1st 1 is CMP. Compare. Next is test and Last is BT. They are used for comparing values and testing values and another instructions I will show you also works with blacks and it is instruction A, D, C and SBB. These are adding or subtracting apart from Second Opara and also carry flag. So instruction CMP compare is skilled with two operations and its subtract 2nd 1 from 1st 1 without storing the result. Flex are set based on the result value, and here are the flags that can be set by this instruction. Another instruction is test. Once again, it takes two operations and executes and operation over first and second operation without storing the result and last instruction. Bt takes two para meters and it takes bit from first para meter at index defined by second para meter and stars this bit into carry flag 19. Optimalization: when we consider speed off our program, we prefer untrue conditions. Continuing with next instruction is faster than jump or if we can, we reduce jumps in general, for example, if I have here code that finds out whether the value in the register EA X is even nor aught and based on that information, he said, e d x 21 or zero where one means he a X is sought and zero means it. This even the basic implementation could look like this bar. You can optimize this algorithm so that there is no conditional jump. Also, we can do other optimization, for example, instead offsetting E V X zero, we can use sore instruction. This instruction represents sore binary operation, and in general, bynder operations are faster than any other operations. Then we can shift E a X to write, and by doing that, we said the smallest bit to carry flag and then we can at carry flag to Eby X. And lastly, we said d a x two previous value using rotation left over carry, then wear the bit that we lost by rotating right will be back at correct place. So this is how you can optimal eyes goed. There are a couple of important things. You should definitely optimize your code, but you should start optimizing Onley ones. Your program is working. You don't want to start optimal izing while you implement some algorithm that will lead you to programming hell. But anyway, this was example of how you can optimize coat. If you don't understand something, just ask and I will soon exam. 20. Branching: as we already know branching that is in high level programming languages, thanks to if is in assembly, thanks to jump more precisely conditional jumps. So let me show you how, if and if else is implemented in assembly. So first, let's look how we use if in high level languages so we have if keyword than there is condition and then some code we want to execute. If this condition is true, also, we can use L's branch and goat in this branch will be executed only if this if it's false and this is how these look in assembly. So let's look at classic if condition. Without Dell's branch in assembly, we write condition to to light where at first line is, for example, CMP instruction and then there is conditional jump. All conditional jumps are called GCC. It is not the really instruction it is on Lee. It only represents group off conditional jumps. So if this condition is true, we jumped to went. This is a bit weird because in C plus bus or any other programming languages, we execute B. If a is true about an assembly, we execute be if this conditional jump is false. And here is out if else works so the first bit is same But we cannot forget to jump to the end after executing be And also if a is not true this conditional jump will lead us to see So this is how you can river, right? If condition in assembly Pretty cool, right? And I hope you understand everything. If you don't just ask and I will soon exam. 21. Cycles: in this lecture, we will take a look at cycles in high level programming languages. Cycles are essential and you would have problems creating useful applications without them . So the most basic type of cycle is the one when we know how many times we want to loop. So let's say we have a and a represents number off loops. It can be constant or computed value and the it's good that we want to execute. So an assembly we have instruction called loop, and this instruction looks like this. So first we moved to re see ex A. So we saw in E c X the number off iterating sins. Then there is label called Start Under start is the killed that we want to execute. And last day there is loop instruction and as one para meter this past some label in our example start and this instruction determent e c X, and if it is not equal a jumps to label so be will be executed eight times. Another useful cycle is the do while cycle. So we do be while a is true. Sadly, we don't have instruction for this in assembly, but it is pretty easy to implement. So first we have label start. Then there is B which represents go that we want to execute. And after this gold we have conditioned a And then there is some conditional jump which jumps to start while a is true and the last cycle is simple while cycle So while a do be once again we have starred label that. Then there's condition a and conditional jump and this jump Go sue end. If a is false, then there is skilled that we want to execute and unconditional jump that goes straight to top. I hope you understand everything Cycles are very useful and you should use them. It is one of the basic constructs off structured programming. So it if you don't understand something, just ask and I will soon exam. 22. Stack 2: as you probably know, where incursion is very powerful to in computer science and in programming in general. Also, every process, er can work with Ryker Shin using programs stack. Thanks to this stack, it is pretty easy to use Riker. Shin Stack is a data structure off type life full that basically means last in first out. And we can use this data structure to store current state thanks to Bush operation. And then we can retrieve this information using bop instruction process er issues ing one stack and it just looks like an array off. Four bide numbers and nothing else. Implementation off sac using array It's pretty easy process er is using E S B register and I talk about this register already in previous lecture but process or used his register as a pointer to the top off our stack. So value at TSB it's always last stored value, and we can start to stack any type of value we want. So, using push instruction, we can start direct value address in memory or register, and we can take the information from stack using pop instruction and we can pop into memory or register. These are things that kind mentioned before. But now I add to these ability to call functions using coal instruction. These instruction stores at stack current value off E I P register and pass D control to address defined by ah perent off goal instruction. Next instruction is Rhett. This instruction have no operate and it returns the control back to program. So it basically pops value from stack and then store this value in E I. P and stack is essential when calling function girl of function looks like this. First we store arguments to stack using bush instruction. Then we call function killed. Function creates something called entry code. I will talk more about it later on. Then the function executes itself. After executing, we returned the control to program and then in the program we yet to E S B number of bytes off our para meters. 23. Recursion: So now we know how Stack works and we can try it out on Rikers Shin. So as a first exercise on Rikers in, I chose some off number from one to N. So, for example, if Annise four the result should be one plus two plus free past four. The recursive algorithm. It's pretty simple at and to result off, some with and miners one If argument is smaller or equal to one, We end in CPAs bus. The coat could look like this, so we accept some end. Then we move this and to E. C X. Then we compare E c X and one and then we have conditional jumps. So if e c X is smaller or equal to one, we jump to end. Now you might think that I forget to set. And 21 Well, I did not, because then it's already won. And then there is this recursive goal. So we pushed a stack. Our argument in this case e c x. Then we kill some. Then we pop E c X back from stack. And another thing I need mention is that the result off some function girl will be in e a X register. So then we just need to add e a x suen and that's it for this lecture. If you have any questions, just ask and I will see you in except