16b: The CPU's Registers (ARM) and a bit of Programming

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everybody Welcome to Bill Skye the assembly guy what we're going to look at today is we're going to look at the CPU registers for arm processors arm processors now I already did one of these for the Intel x8664 architecture we're going to take a look at arm quite a bit different there are some similarities but quite a bit different so let's get started so just like in Intel and AMD processors what are the CPU registers CPU registers are hardwired variables which are etched into the CPU chip these are used to store data to arithmetic indicate the status of the CPU they just are the heart they're they're the memory of the CPU so I like to think of the CPU as the brain of the computer the arithmetic logic unit which is part of the CPU the booth multiplier the control unit there's other other units in there those are like parts of your of the brain so the CPU overall is the brain these are different parts of the brain and the registers are the short-term memory that are put in the that are used by those by the CPU to get things done long-term memory is primary storage secondary storage primary storage being memory chip secondary storage being things like hard drives ssds things like that now there are mult different types of of registers in the arm processor there's general purpose registers and there's special use registers general purpose registers are the ones mostly used by programmers so we're going to concentrate on those we will talk a little bit about the special use registers but not a whole lot so there's two different arms that we're going to look at we're going to look at the 32-bit arm which is like the older Raspberry Pi's and then we're going to look at the 64-bit arm which is like the newest Raspberry Pi's as well as the M1 and M2 chips on the Apple Macintosh computers their newest ones and then other other type of risk risc processors which we'll talk about the difference between those later on in this series of videos so what are the arm 32-bit registers the 32-bit registers are r0 through R12 actually the way that the architecture talks about the general purpose registers is that there are zero through R30 however I like to stick with just the r0 through R12 because those are not used by anything those are things that I can use now the r13 to R30 those are general purpose registers but they're also shared with special use registers which we're going to see an example of that in just a moment so unlike the x8664 architecture the arm general purpose registers are all usable by the programmer uh they're also not split up if you took a look at that video they're not split up into smaller registers now when we get into 64-bit arm we will see a little bit of the splitting up mainly for compatibility purposes so as I said a moment ago this is a picture of the general purpose registers for x8664 we're looking at the eax 32-bit register and if you haven't seen that video that's what we talked about in that video is how they're divided up Now intel chips are still probably the most popular chips out there for desktop computers and servers so you really do need to know this information as well but arm processors really do not split things up the way that the Intel processors do now what are some of the special use registers we talked about the general purpose registers what are some of the special use registers there's the IP register which is the intro procedure stack register it is shared with R12 that's why I don't like to mess with anything outside of that area we have the stack pointer which is the r13 we have the link register we have the program counter and all those are shared with our registers however there is one here the apsr status register it is not shared with any of the r registers and what it is is it is the register that tells you the status of the CPU okay that's the arm32 let's take a look at the arm 64. now the arm 64 general purpose registers are x0 through X15 those are the 64-bit registers and then we also have w0 to w15 and those those are directly related to the x0 through X 15. so w0 is related to x0w1 would be related to X1 and so forth that's the 32-bit component of those X registers the W registers and these are basically the lower half of the X registers which are 64. now w16 through w30 x 16 through x30 those are general purpose registers but they're also used by some of the special purpose registers as well so here's an example of an xn change put n instead of input 0 through 14 in there or actually I think yeah zero through 30. the X registers are 64-bit the W registers are the bottom half of the X registers the 32-bit registers that's the W now why did they do that mainly for compatibility reasons because arm processors started off years and years ago as 32-bit registers they've always been that way but with the Advent of 64-bit CPUs they had to come up with some some way of making them compatible when you go from X32 or I'm sorry 32-bit to 64-bit and that's how they did it much the same way that the Intel x8664 registers are set up so the general purpose registers the w16 through w30 those are the 32-bit general purpose registers but they're also shared with special use registers same with x16 to x30 w16 is associated with x16 and so forth now the programmer may or may not be able to use those registers I pretty much stay away from them all the time for safety reasons because I don't want to overwrite something that may have been put into that special use register or that W or X register I think 15 registers are more than enough to get most of everything you need done so I just ignore them now in 64-bit what are some of the special use registers you're going to see some commonality here the ip0 ip1 those are inter procedure call stack registers and we we may talk about that later on you can look it up on the internet if you're really interested in what those are and that's the x16x17 registers and then you have the stack pointer which is actually independent of any of the general purpose registers you have the link register which is associated with the x30 general purpose register you have the program counter which as you see here has nothing to do with any of the general purpose registers and then you've got the nzc fee nzcv register and that's the status register for arm 64. so that will tell you whether or not there's been a zero we'll talk about that in a little while let's take a look at a debugging demonstration in 32-bit just so you can see how to debug now debugging in an arm on Linux x86 Linux is quite a bit different than using kdbg or DDD as we've done in previous videos so let's take a look at that right now okay so here's our Linux this is a VMware guest operating system running on a Mac Pro desktop computer which is an Intel computer I installed all of the arm 64-bit programming libraries to allow me to write arm code assembler language code on my x86 VM Gaston computer I have another video for that I'll put a link down in the description of this video so you can do that if you haven't done that yet so I'm going to assume right now that you've done that and we've I've downloaded the templates that I've provided to you guys you can see another commonhetsky video downloading the downloading the comanezky libraries for Linux you that's video I'll put a link for that as well just in case you haven't done that and those are free to you you can use them as much as you want so let's take a look at the 32-bit so I'm going to right click on my Linux arm 32-bit template and I'm going to say extract here and I'm going to go into now I'm going to rename this first so I'm going to call this arm 32-bit red demo and I'm going to open that up I'm going to open it up with my editor and there's my editor now one thing in this particular template I don't like I'm going to change it if I've already changed it then you won't see it is I don't really have a data section here so I'm going to create a data section and I always like my variables to be put in a spec explicitly defined data section so I'm going to save and I'm going to build this just to make sure it works by clicking build make and everything worked great I'm now going to go into the where the executable is here's my executable I'm going to right click on that open in terminal dot slash main and it printed out hello arm32 so we know that the build process worked now I'm going to leave this window open over here so let's go ahead and put some data in some registers now if you take a look at this template you can already see some things I put a literal one in r0 I put the address of them of the message variable in R1 I put the length the address of the length variable into R2 I put the literal 4 into R7 and then I interrupted the operating system asked it to do something so we'll be talking about that more but let's do something so ldr means load register so I want to load the register I want to load the r0 register you can lowercase or uppercase it doesn't matter and I'm going to load at immediate value so I'm going to say equals 0x 1 2 3 4 5 6. 7 8. so R zero is a 32-bit register um that's going to be eight nibbles so one two three four five six seven eight no problem it should load it I'm gonna build it there it is and now let's do some more and then we'll we'll go ahead and do some debugging so now let's unload just a byte so I'm going to do an ldrb so load register byte um again I'm a little obsessive compulsive so I'm gonna now put r0 so this is just going to load a single byte two nibbles in a byte and I'm gonna go ahead and clear r0 and then I'm going to load a half word so a half word is smaller it's two bytes instead of four and let's put that in R1 and I'm going to say 0x ABCD and let's clear out R1 instead of clearing out r0 let's clear Auto one okay so all I'm doing is putting stuff into the registers now take a look at the moving data in and out of the CPU to get more information about how to do that this is just a quick little introduction and then let's go ahead and build this all right built just fine now debugging on arm is a lot different arm there aren't a whole lot of debugging tools for arm assembler language so we're going to have to use the GDB debugger now in my template I actually created in the make file I created a way for you to do this that's semi-graphical interface and the way that you do it is you open a window I'll do this again I built it I'm going to right click on the background say open in terminal and I'm going to say make debug one well maybe it was Capital make debug one what just happened there so I'm gonna take a look at our make file and up I have an old version of the templates so I'm going to go ahead and download a newer version of the templates and then I'll give you I'll show you that make file and what I'm missing here okay I fixed my problem I went ahead and downloaded the newest templates and let me show you what I did in the make file so there's a couple of new targets and I do have a make file video out there as well so take a look at that if you're wondering what this is all about and we have the debug one and we have the debug 2 targets now what that's going to allow me to do is I'm going to open up a single window so I'm going to right click on my background and I'm going to say make debug one and what that does is that enables the debugger to be able to communicate or that enables the program to be able to communicate with a debugger now a remote debugger now I'm going to have to open up a new terminal and type in make debug 2 and now I've got my debugger and it's kind of a semi-graphical user interface debugger not quite now you want to leave both windows open but I'm going to go ahead and put this one up there I'm going to put this one over here and we can kind of see our code I'm going to go ahead and bring up my my actual code here and we're on the very first line of code so here's my source code you can see that highlighted is that source code there and what I'm going to do is I'm going to type the S character and then press enter so that executes the first line which is the move one to r0 and it goes on to that you can see it on the top of that window now we can see our registers so I'm just going to go step by step okay so now it went ahead for some reason and I don't know why it went ahead and it executed the ldr zero it actually executed this one right here um and you can see that up here on the register so we moved one two three four five six seven eight to the r0 register I'm now going to step now I'm on this line of code right here and I'm not gonna now I'm going to step oop two s's invalid I'm gonna do One S and we can see that it is now a b it moved a single byte into the r0 register now I'm on this one it's going to clear out the R1 register so we're not going to be looking at our zero we're going to be looking at R1 which is right below r0 so I'm going to type S enter and now R1 has a zero in it r0 was left alone I'm going to step again and now R1 has a b c d and that's what we did right here so if you want to learn more about how to move data into the CPU and move and move it into memory from the CPU take a look at that video and I think what we're going to do now is we're going to try this in 64-bit but before we show this in 64 but I want to show you how to get out of this debugger so when you're done you can either press and type c to continue that will end the program notice how this original terminal my debug one is now blank because we told the debugger told the program you're done running so in my second window I'm going to type Q to exit the debugger and now we're done okay we're back let's go ahead and do the 64-bit demo of this I'm going to right click on my 64-bit template I believe I updated that and let's go ahead and rename that let's open it up let's take a look at our code okay now in the 64-bit version I did put a data section so I didn't indent everything the way I should but I did put it in there and you may have a newer version of the template so you may not have any of that okay so let's go ahead and do this on 64-bit now remember the registers on 64 but our X 0 x 1 x 2 x 3 and then the 32-bit version the 32-bit copies of those the lower half of those X registers are w0w1 w2w3 so I showed that when I originally described those so let's go ahead and let's do a load register I'm going to load into x0 that's the 64-bit x0 register I'm going to load a large number hexadecimal very large number in fact let's save and build that all right built great you can see no problems down here okay so now let's go ahead and let's see what happens when I move something in the bottom half of x0 and to do that we say w0 and in this one we're just going to say all nines so we're going to move that into the bottom half of x0 by using w0 okay so let's go ahead and debug this we're just going to move some we just moved to 32-bit value into there we moved a 64-bit value into there 64-bit first sorry in the X zero now let's go ahead and debug those so let's make sure it's built okay all right looks good and let's go in and debug it now just like in the 32-bit one I'm going to open a terminal in the project I'm going to type make debug one I'm going to open up another terminal and say make debug two and there's my semi graphical user interface debugger let's go ahead and bring our code up here yes I know GDB is not anywhere near as nice as kdbg or DDD or visual studio for that matter so we're going to take a look at these two lines of code so let's get ourselves to line 20 in the debugger and the way that we do that is we just step through so we're on line 14 I'm going to step through we're on line 15. we're on line 16 17 18. and now for some reason the debugger skips over line 20 but it does it you can see up here on the top x0 is one two three four five six seven eight a b c d e f zero so that's cool so now let's go ahead and step again and this time it should put we're going to be in on line 21 we should be right there let's step and now it's all equal to nine now notice though this is one thing I did want to show you on this debug notice how when we put a number into the w0 which is the bottom half of the x0 all of the bits in front of w0 have been overwritten they've been overwritten with zeros so instead of it being one two three four five six seven eight and then all nines because all nines are just put in a w zero it just completely replace it and that's in a compatibility issue I believe so that's our demo of 64-bit arm registers okay we're back to the presentation let's take a look at the status registers in the arm processor so so status registers and arm are there to have a status or a status of the CPU at any time to see whether there's problems whether there's been some issues with operations and for 64-bit it's the nzcv status register and for 32-bit it's the apsr 32-bit let's take a look at what each one of those does the arm32 apsr register bit31 now remember the status register is a whole bunch of bids so bit 31 is the end flag if and if an operation resulted in a negative value the N flag bit 31 will be turned on if an operation resulted in a zero value bit 30 would be turned on otherwise turned off that's the Z flag if there was an unsigned carry in other words if we try to add something to a register and we actually went outside of those bits we lost some data bit 29 would be turned on if it was an unsigned operation if it's a signed operation the V flag bit 28 would be turned on and that's the same thing as if we go outside of the number of bits that we can hold in our operation the V flag is turned on those are the most common ones there are many additional ones but not often used by the programmer and I put in an overview of what each one of those are if you add two unsigned numbers and there aren't enough bits to contain it the bit 29 unsigned carry flag will be turned on same for carry the bit 28 signed carry flag will be turned on the Zero flag will be turned on if an instruction results in a zero value this flag is set if it's not a zero value that flag is unset if an instruction results in a negative value that bit 31 negative flag will be turned on if it doesn't result in a negative value that flag is turned off now for the nzcv register which is the arm 64. is pretty much the same thing the bits are exactly the same you've got the N flag for negative Z flag for zero C flag for unsung carry and V flag for sine carry now this will all mean more when we get into conditional processing on the arm processor where we're asking questions if statements did something happen in this calculation but for right now that's what each one of those means all right so that's the end of this video I hope it helped you get a little bit better understanding of the arm processor and the registers and how to use them hope to see you at the next video
Info
Channel: Bill Sky - The Computer Guy!
Views: 96
Rating: undefined out of 5
Keywords:
Id: JPBsU21XOZs
Channel Id: undefined
Length: 22min 4sec (1324 seconds)
Published: Tue Aug 15 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.