What Is Assembly Language?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello I was tapping with a web developer friend the other day he asked the question what is assembly language and this took me back a little bit though I thought you know you're a programmer surely you know what assembly languages then it occurred to me actually there's probably many programming perfections where people will never have any exposure or reason to use assembly language such as yes web development database backends a user interface designers script writers and so I thought it might be works put together a little video on what is assembly language when I was working in academia I used to work in a laboratory that designed processes right through from the conceptual stage to actually fabricating them on silicon when you develop your own processes you also need to create your own framework and tools so we have to design an assembly language threat to design an instruction set and then build compilers and debugging tools now the thing with assembly language is there are many many different flavors in fact you could argue that for every different type of processor architecture out there there is a unique assembly language for it I'm not going to go into the specifics for this video today this is really a where does assembly language fit in the scheme of programming to understand the role of assembly language we're going to need to look at the fundamentals of computer architecture we're going to look at CPUs and memory and how they talk to each other but before we get started at the end of this video there's a couple of my thoughts about the recent events that have happened in Manchester I'd appreciate it if you stuck around to watch those two so let's get started when trying to classify assembly language it's useful to look at the hierarchy of all the languages now I've chosen some naming see which probably aren't conventional but I think you'll see the gist of what I'm trying to get across so the declarative structures these are the really high-level things like I consider that to be things like HTML Jason essentially languages which don't really have an executable order but still nonetheless define useful things these very high-level languages are usually used to define things in scripting languages as well as other things so scripting language I would consider things like Python and JavaScript and our bowl ones like Lua I like Lua these languages usually execute line by line there are some fancy compiling techniques to make things run a bit quicker but ultimately they are interpreted as and when they are required and therefore they running something called a virtual machine which is basically a software equivalent to a computer now these virtual machines will be written in a more sophisticated language usually along the lines of something like C++ debatably something like c-sharp I'll await some of the hate in the comments there and the whole load of older languages the list of those is endless and at the very bottom we have assembly language which is the language that the CPU speaks the problem we're trying to define a hierarchy of languages is some of them share bits and pieces with others so for example some could argue that c-sharp here is actually a scripting language because it's interpreted it produces a bytecode which requires a virtual machine ultimately it's not black and white and the point I'm trying to get across is at the very top we usually have things that define stuff like what a website looks like and at the very bottom we have the instructions that tell the computer hardware how to display on the screen what that website should look like but this video is about assembly language so we need to have a look at computer systems architecture fundamentally a computer consists of a central processing unit and RAM random access memory and between the two the central processing unit will output an address and it can read or write to a certain location in the memory let's start with a very simple one Ram is effectively an array to the coders out there there is usually an index and there will be some sort of data now the width of the data depends on the architecture we can only hear 32-bit perhaps could be 128-bit could be 256 bit it really does depend on the system this video is not going to go for any particular architecture we're just going to keep everything very very high level whereas RAM is used to store data the CPU is used to manipulate data and it does this by using several internal units so I'll have a look at what these are the first thing is CPU usually contains registers which basically its own internal ram and it'll only have a small number of these so in my simplified example here we have four registers RA RB RC and RD and these will just store numeric values as we'll see later some CPUs have specific registers for specific functions a CPU isn't very useful unless it has an arithmetic logic unit otherwise known as an ALU the ALU is responsible for performing well addition subtraction and logic and and ORS and other sort of computations CPUs will also contain a status flag register which is a collection of bits which tells us about the state of the CPU and the arithmetic logic unit the program counter is used to store the address of where we're up to in our program so as a program is executed sequentially the program counter increases the program counter value can be set depending on the result of something in the status flags register so we can use this to branch and we'll see an example of that later on and finally you usually have a section of inputs and outputs or communications so this is how we get data into and out of the CPU the purpose and sophistication of a CPU depends on what parts it's got inside it so some CPUs will have more registers and some CPUs will have bigger and more complex arithmetic logic units these are known as extensions and on desktop computer architectures were very reliant on extensions for the processes to do lots of the wonderful things we expect them to do these days now for the purposes of today's video we're going to assume we have one more module and you can't go into a shop and buy this and it's going to be program memory so I'm going to keep this separate from random access memory and the program memory is accessed when the CPU outputs its a program counter and in return receives the next instruction that it needs to execute this configuration is not how it works on your desktop and in fact that the random access memory is is used to store the program as well however on some embedded systems the program memories frequently kept separate from the working random access memory I've decided to keep the two separate just for this video it clears things up through the worked example later on if you're familiar with basic programming you'll be familiar with the function and the function takes arguments well an assembly language can be considered to be the same thing but if we use the correct parlance for assembly language the function is normally called an opcode and each argument will be called an operand to demonstrate how the assembly language works we're going to design a very simple processor with just a handful of instructions now operands can be either registers as we profess are before registers a b c and d they can be memory addresses locations somewhere in memory and they can be constants numeric values our simple process was only going to have four instructions so the first is going to be move which moves it's going to take two operands and if these are going to be the destination and the source and the point of the move command is it moves contents from the source location to the destination location we're going to have some very simple mathematics so we'll have add and subtract these are opcodes and the first operand is going to be the register which we're targeting with the addition and the second operand is going to be a value or a register and the fourth instruction is going to be jump and the first operand is going to be the condition on which we jump and the second operand will be the location of where we're going to jump to this will become a bit more clear when we start writing some code later on our CPU can only move stuff a stuff's abstract stuff and jump to a different location so is it very useful well probably not but it is enough to do some more advanced functions so how can we multiply a couple of numbers together for example if we had three times ten well we know that if we sit in a loop we can simply add ten to itself three times so let's have a look at the program for this here's a little example program ever written using our new language to multiply two numbers together but I'll need to explain some of the syntax to you first clearly here we have the opcode and we have our two operands so the first operand here is RA which we saw in our CPU means register a the second operand I've put in square brackets and this means we want the source of the move to be from memory address number three unlike this one here where I've not used the square brackets and what I'm implying by this this operand is that we want to move the value 0 in to register C so we can load in a constant value or we can read from memory looking back at our RAM I'm going to assume that our memory has now been populated with some values so we can execute our program in this case we want to multiply 10 by 3 so these are already stored somewhere in memory now we're going to do something very old-fashioned to execute this program by hand so we know for the first thing here we're going to do is read from location 3 which has the value 10 so that puts into our a the value 10 on the next iteration we want to read in from memory into register B which we know is going to be 3 this time the next instruction we're simply setting a counter to zero this is going to store our result the add instruction here we'll take our a and add it to what's already in our C so in this case we've got our C equals our C plus R a which in this instance is of course the same as saying zero plus ten so our C after this instruction equal ten likewise the subtraction instruction here sub subtract the value from the current register so here we've got our B equals our B minus one but it's a value this time we're not using another register so that equals three minus one equals two now with the jump instruction we're going to see something interesting let's look at the arithmetic logic unit in a bit more detail simply put it takes two values and an instruction and performs the operation so in this case it could be our registers or constants the instruction is the ad or the subtract and it gives us a result but it also updates the status register the status register contains some interesting things based on the result of the calculation is just performed so if I do a little bit of pseudocode here we could say if result is equal to zero then set the zero bit helps don't in our simple processes a status register only contains this one bit whether the results of the previous computation was equal to zero or not well the bits that are commonly found in status registers include overflows carry bits has the result of the computation gone out of bounds of the number of bits allowed to store the result you can also include errors in the status register such as divide by zeros going back to our program we can now try and understand the jump statement a bit more in this case the condition is looking for not zero so remember the zero bit was set by the result of the calculation we can see in this case it was two so it is not zero so the jump condition is true and we tell it to jump back to address 13 so this is going to loop back round up here our C is now our C equals 10 plus 10 and our B is now to take 1 but we can see this is still not a zero so again we jump back round this iteration we can see our C equals 20 plus 10 which equals 30 so we know we're getting close to our result now and on the next line down our B is now one take one which is equal to zero and that's important because now on our jump construction the result was zero but we're checking foot not being zero so in this case we don't jump so on the final instruction we just carry on with the next one which is finally a move instruction which says whatever is in registers see here we're going to store in memory address five the register C already contains our 30 which is the result and we're going to store that in memory address five somewhere in RAM so when the write occurs 30 the result is written to that address location so we've done a successful multiply now this program demonstrates what is typically assumed by most people that don't really know assembly language is that they think it is hard and that's because we didn't have a multiply instruction there poppers out so we have to do it the long way around if our little CPU did have a multiply instruction we'd only need to call it the one so we wouldn't need to set up a loop we wouldn't need to manage the registers as much let's now consider a slightly more real-world example so I'm using the visual studio environment here to look at some x86 compiled assembly language this isn't going to go into the very minutiae of the language or what's going on but it will show you how you can actually use the environment to study assembly language first thing we want to do is run it in debug mode so I like to highlight the line and press ctrl + f10 and once I've set up here in the debug window is if I get it to show first of all the disassembly it goes a bit small and I can't zoom in unfortunately in Visual Studio so you'll have to bear with me on that and in the registers I've got the well I've got the register window viewing at the bottom here so we can see that in the x86 in its most simple level we have some registers EAX EBX ECX edx these are like a ra RB RC and RD that we had before and we've also got some flags well let's have a look at the code that it produced so we can see from my line of C code here the int a equals 10 we stored the value 10 in the address pointed to by a using a move command just as we did before so it's obviously in hexadecimal here the same goes for B we're storing the value 3 at the location pointed to by the variable B now let's have a look at how it handles the instruction so the first thing it's doing is loading from the memory where variable a is stored it's loading it into EAX and we can see here down here in the register window that EAX is now in set to 10 in hex of course which is a the x86 does have a multiply instruction and we can see it uses the EAX register which is preloaded with the value 10 and it's using directly for memory the value stored wherever the variable B is so the the disassembly window here doesn't show you all of the memory addresses of these things because it would be inhumane for quite frankly to debug these things so it does actually use the symbol that I provided in the code which is very handy and so it'll do the result and the result is gone straight into EAX and so 1e is in fact the hexadecimal 430 and we store now just a before with the move instruction again we store back into whatever location see is in the memory we store the value of register ei X which is the result of the equation so this program does exactly the same as the little toy program we created earlier let's have a look at some differences between the CPU architectures so if I choose to operate in the floating-point domain now instead of the integer how does it resolve this let's take a look and when we look at this we start to see why assembly language has a bit of a reputation for being tough what is going on here well let's just have a look at the commands that are being used first so the first thing we can see there is a move command it is a slightly different move command to before but it's still the same things the principle is the same and we can see actually there is a multiply command down here but everything else looks a lot more complicated why is this the x86 processor has some extensions specifically for dealing with floating-point and the compiler is recognized that our code could benefit and be faster from using these instead in fact the extension it's used here is the SSE extension so we can see that the register xmm 0 is on here so this is an extra set of registers just on the cpu specifically for handling floating-point data let's step through and see what happens this time I've expanded the registers window to the side makes things a bit clearer and we can see your pier in the these are the raw register values but the debugger also provides the floating-point equivalent so that will make things a bit easier for us to follow what's going on so the first instruction was load a with 10 and because we need to use a specific register the first thing we have to do is load our data into the into the processor so we've loaded in now our value 10 here which of course is all in our exponential notation we can load in our value 3 so in this case we're loading into a floating point register xmm 0 and then we're storing the contents of that register back into memory so here we've got the the actual the guts of the calculation the first thing it's done is load the memory now pointed to by a into xmm 0 which is our 10 we can see here in exponential notation that it's done it and then it multiplies directly the register with itself and the value from beasts this is three off-brands going on here not just two and straightaway we've now got the result 30 when it stores that result back out in memory even though this looks horrific we can disable some of these compiler settings so we can use simpler and other extensions of the CPU tablet so if I go into the project properties for this curve program and go to the code generation I can specify which set of extensions are used for floating point calculations so I'm going to disable them entirely I'm going to say you can't use any of the more advanced features let's see how it compiles the code this time the first thing we can see is it doesn't use all of these complicated registers so I'm going to get rid of these from the view in fact what it does use is the really old-school intel x86 floating-point registers and this uses a slightly different operand and opcode architecture so the first instruction was a floating point load FLD where it loaded in the numeric value it then goes and stores that value in memory again we see exactly the same notation used for memory then we're going to do exactly the same for 3 so we've done out 10 dinar 3 and now we'll have a look at the calculation it works a little bit like a stack in this case that it now is going to read from the memory address pointer to by variable a with the FLD floating-point load you can see here that the register on this is st 0 i'm not quite sure the st stands for but it makes sense to think of it in a stack in this sense so we've loaded in the value 10 in exponential notation and now we're going to multiply it directly by the value stored in memory 3 which gives us our result 30 and then we store that back out in see we've now looked at two different ways of compiling the same program just using different compiler flags so we're choosing which bits of the CPU we want to perform our computation what's reassuring is that yes even though the the notation has changed slightly there's still a common thread there's still some familiarity between each of the extensions so we can we can work out what's going on we can follow how the code is being executed my system level architecture diagram here is a little over simplified for example if the processor can only talk to the men me how does it do anything useful it's just doing calculations and storing it back in memory well on quite a lot of architectures one thing to do is to have memory addresses which have specific functionality let's consider a piece of hardware that's monitoring a temperature sensor for example the temperature sensor is filling an area of this memory and our central processing unit is using its bus to read from it likewise let's say we wanted to set the brightness of an LED at one way to do it is the CPU will write to a known memory location the value that it wants and some extra hardware will go away and deal with the brightness knowing that you've got certain parts of your memory allocated to doing Hardware stuff does make using memory quite tedious and tricky and in Windows and other operating systems we're kind of used to just letting the operating system handle that for us we just give us some memory and it goes thank you very much here you are but on an embedded platform it's very important that you know what these locations are and if we do occasionally still see this in Windows for example as you install more hard work you will see the amount of overall ram decreasing we're gonna put a big graphics card in with a Giga gram it's not uncommon to see a system ram decreased by a gig because it's Matt that's address spaced over to the graphics account I will emphasize that what we've seen today is a very simplified view of assembly language although it should give you a taste of how useful it can be you might think why would I ever need a program like this well our MOOC system systems that haven't got any software written for them already if you want to build drivers for example for hardware somebody still has to do this level of coding the compiler simply doesn't exist there used to be an argument you could write much quicker and more optimized code using assembly language although this is debatable now the power of today's compilers is this is quite surprising and often will create more optimized code than the programmer thought that they could do in the first place even though there are professional programmers out there that will never need to see assembly language it's good to have an appreciation of just how much work the processor is doing to do what they consider to be a simple thing having appreciation about just how many clock cycles are required to execute your pretty logo on the screen can only be a good thing I quite like assembly language and I think I'm going to do more videos on this topic in particular I'd like to create a virtual machine that executes our very simplified assembly language I used as an example and potentially we could take that even further we could implement it in VHDL and release our FPGA so it's no longer a software machine is that genuine physical processor running our own language I don't know we'll see where it goes one thing I'm sure when we start talking about assembly languages some people can get very excited about it so if you if I've said something that upset you or if you agree with something please say so in the comments if you found this video useful give me a thumbs up or subscribe I'll see you next time thanks for continuing to watch this isn't code related and I'm not going to get into the habit of airing my personal views but the recent events in Manchester have it a little too close to home for me to ignore until recently I lived in works in Manchester City Center for 12 years and still have many close connections to the city clearly the cowardly act of terrorism was apparent was rightfully been condemned by the international community the thing with Manchester though is perhaps its citizens are the embodiment of cultural acceptance just days after the attack Manchester hosted the Manchester Marathon were crowds of hundreds of thousands of different races colors creed sexual orientations religious persuasions got together to celebrate charity I can't think of a better way to say hope yours to those who want us to live our lives according to the bizarre myopic and hate-filled doctrines well done Manchester
Info
Channel: javidx9
Views: 331,991
Rating: 4.9656229 out of 5
Keywords: Assembly language, x86, asm, c++, programming, tutorial, ram, cpu, alu, atithmetic logic unit, learning, manchester, onelonecoder, one lone coder
Id: 1FXhjErUz58
Channel Id: undefined
Length: 24min 56sec (1496 seconds)
Published: Mon May 29 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.