Hello its Keith here, and today we're
going to be starting a new series
we're going to be looking at the ARM processor,
now the ARM processor started with the
Arm2 and the acorn archimedes, and it's
progressed over the years and now
basically runs all the mobile phones we
use, and it's starting to make sort of
headway into the server industry, and
things, so Arm has become a very
significant player in the CPU industry,
and is basically the 'number two' behind
the x86 (which I'm covering in the 8086
series)... so we're going to be looking at ARM
and we're going to be learning about
the basics of how its instruction set works
we're going to be primarily
focusing on the arm2  with 'Risc OS'
but we're also going to look a little bit at
the Game Boy Advance, which of course was
also arm based... we're going to be
looking at a few of the simple commands
and we're going to learn how to work
some simple arm programs, and look at the
instruction set... so let's begin today then!
So the first thing we need to
understand is that the ARM processor is
referred to as a "RISC processor"
which is a reduced instruction set processor, 
this means that the instruction design is
more simplified, the bytecode is sort of
more rigid and it works a little bit differently
but it's not something
that's particularly too scary,
there are some things that are quite different to
processes we've looked at in the past
like the 68000, but it's not things that
are going to terrify us beyond belief
it's just things that may be learnt work
a little bit differently with regards to
the way the calls work, and maybe things
that we could do it in one command
before we could do in two... but that said
the arm does now possess some very very
powerful commands that are really quite
remarkable, that a system like Risc-V don't have
so as I say it's a very
impressive system, and it's certainly one
that deserves our attention! now, the ARM
processor has a total of 15
general-purpose registers that we can
use, it does have some others that are system registers
but we're just going to
stick to the basic stuff, now some of
these are used by the system, so number
15 is the program counter
that's the current running instruction, 
so we don't want to use that number,
14 is what's known as the link register, 
now when we do a CALL (that's like a GOSUB if you
familiar with basic) rather than on other
processors things getting pushed onto the stack
with the ARM, the return address is 
put into the link register
now if you don't understand that, 
please don't worry about it
I'm just going through the basics of the
registers... the important thing is that
has a special purpose we'll see later,
number 13 is the stack pointer
but we can just refer to that as SP... now 11 & 12
also have some special uses in certain cases
but essentially everything from
Register 0 to register 10
we can use for whatever we want, 
we can just use them in any way we like
of course there's some flags and all of this we're
going to cover later, this is just a very
quick introduction to the process, 
so just so you have some grounding for when
we actually start looking at things, 
so anyway let's go over to our code and
let's start seeing some programs in
action - just some very simple ones!
okay, so I've got a few little programs here,
the main one we're going to start with
is this minimal example here... now as
always with my tutorials I've got a bit
of a header here, and a bit of a footer,
and these are going to allow us to set
up for working on either RISC OS or on
the Game Boy Advance, and so this is a
test environment for us... so if we're
playing with a few commands and we want
to see some quick results, we can use
this code here... so let's fire up our
emulator and see this running! first on
RISC OS, okay so here's our emulator
running
we're using RpcEmu here, you know you
can download the package for this from
my website, now what we've got here is a
dump of all the registers, and that's
this monitor command here now BL stands
for "branch and link"... now this is the
equivalent of a "CALL" within the Arm CPU
what this means is its branch which
means jump to a label, and link which
means transfer the program counter to
the link register... Now, if I just switch
back to the last screen for a second...
now you may remember I said before the
program counter (PC) is register fifteen, and
the link register (LR) is register fourteen...
so what happens is the program counter
is copied to the link register when the call occurs,
now if we just go back to
our code screen here, if we look at one
of these sample lines here you'll see
this GetScreenPos function has at
the end a
MOV command, which is moving the link
register(LR) back to the program counter (PC) and
this is actually effectively return command
a bit strange I know and we're
going to cover all of this later on,
but if you're familiar with the basic this
is effectively a 'GOSUB" to subroutine
and this is effectively a 'RETURN' command
for the Arm CPU, as I say what we will
cover all of this later, I'm just giving
a very brief introduction here,
so branch and Link is our 'GOSUB' or our 'CALL'
command... 'MONITOR' is a function that's
defined within one of these include
files, this is a separate ASM file which
we're not going to go look into today, 
so this include command with the dot at the
start defines a file to be included, this
'bitmap font' and this 'infinite loop' are labels
you can tell that because they're
at the far left of the screen with a colon,
whereas these other commands are
indented by a tab, and that means they're commands
so we've got a couple of branch
and links, these calls here to a few
functions within these, and this monitor
will show the status of all of the registers
now we can test this if I just
do a MOV R1,#0x1234
and I execute this
you can now see register 1 has changed
to 1234 and if I just exit that and I
change it to 6660
ok and you'll notice I've got this 0x at the start
which means hexadecimal, and as Isay
we'll look at all this again in just a moment
well now you can see register 1 equals 6660
and that just shows that this
monitor is working, and this should be
quite handy if you're just getting
started with programming and you want to
test a few commands and be able to see
some results on the screen.
that's what this is designed for, now as well as the
RISC OS we can also run this on the
Gameboy Advance... if I just run here and
there we go!... you can see the same state
now the 666 is there, the other
registers are different, because it's
completely different hardware, and it's
the contents of the header and the
footer that are allowing that to happen.
They've got some generic graphics set up
routines and things, so that we can run
our test code on either emulator,
and RISC OS is good for arm to the very
early iteration, and the Gameboy Advance
is a much later version of ARM, so
that's quite handy if we're testing the
commands that were added later on, 
so that's going to be a testing environment
and it'll say this is just a very simple
example here that we can use as a template
so that's there for us now we
are going to be compiling with some
build scripts that are provided with
this development environment,
hopefully if you download the tools I've provided
here you can just press f6 and you will
get an option here, and it will let you
select one of the destinations to build
- we've got Game Boy Advance and RISC OS
now this RISC OS strong arm doesn't
really work I don't believe. I was hoping
to be able to some use some more
advanced arm commands, but it seems
there's some problems with that.
So we'll just have to stick to Game Boy Advance
for the more advanced commands and RISC
RISCOS for the ARM2 commands... ok so that should easilly allowed us to build and
the script itself: we're using VASM to
compile, we're specifying a build file,
we're specifying the version of arm,
we're compiling to ARM2 in this case,
I've got a few options here to set
various settings to compile correctly,
and we're also defining a few symbols
that I use in my code here and there
but that's nothing you need to worry about...
We're outputting a
listing file here, this is a debugging tool
it will show the source code, and
the bytes that that compiles to
it's quite handy if you're having trouble, 
or if you suspect your assembler is making
changes behind your back! some of them
do optimization ,and in some cases
in testing things haven't worked the way I
expected, because the assembler is kind of
almost correcting mistakes that I'm
intentionally trying to make,
so it's sometimes worth seeing that listing file
but it's not something you would need
necessarily as a beginner, and then we're
outputting a file with an FF8 extension
which is an executable for RISC OS, and
you can see here we're copying it to a
folder that RpcEmu is using as a disk
drive... Now, hopefully you can download
these scripts and just use them as is, 
but I just like to give a brief introduction
to VASM itself that we're compiling with,
just to get started with these tutorials.
ok!
so today's lesson is just going to be
the real basics of this system, 
we're going to go over some very simple
commands with regards to moving data
around the registers, and a little bit of
memory processing, and we're going to see
all the results on screen! we're going to
go far deeper into this over later
lessons, but the first one is just a
"starting introduction" to show you my
tools, to give a brief description of the system
and also just some very simple
register manipulation to give you a feel
of what kind of things the arm can do, 
ok! so let's begin... now, we're going to start
with this move command here, you can see
here we're starting at the very
beginning of our code with the setup of
the screen, and then we're jumping to
this set of tests... we're using tests
which adds up here, this is a Branch
which means there's no return (JMP / GOTO)... and we're
branching to the label here...
and the label is on the left hand side with a colon (:)...
and then tab indented we've got our
first command.. MOV ... well you can
probably guess that's a MOVe command !
it's quite similar to a lot of other
systems that have that! now on ARM in
general terms the destination is on the
left, and the source is on the right
now sometimes there's multiple registers, and
sometimes you can see here that there's
two commas here and there's two
registers, and we'll discuss those in
just a moment... but in this case we're
moving the value here (Right) into the register here (Left)
and you can tell this is a value,
because it's got a hash here
so that means it's a
value, and you can see there's a zero
followed by an X and 0x means
'hexadecimal'... so we're loading hexadecimal
one two three four into the register
here... now with regards to hexadecimal
this is of course base 16... whereas
decimal goes from 1 to 10 with numbers 0 to 9
Base 16 has an extra 6 'digits' (if
you will) ABCDE ... and binary just has
two digits 0 1 ... now if you need to have
some help with hexadecimal - because you
will need to have some understanding of
it later on this lesso...n you can probably
just look at what happens and have some
appreciation, but if you're going to
start doing serious program yourself
you'll have to understand hexadecimal
and binary to a good extent... now the
easiest thing to do is just get your
windows calculator up... I'm using Windows 7, 
but the windows 10 one is actually even better!
if I type 1234 here, 
and click decimal, you will see that decimal
4660, and if I type 123 in
decimal and click hexadecimal,
you can see that's hexadecimal 7B... 
If you're just getting started that should help
you out a little bit.. now, I do have a
full tutorial on hexadecimal on my
youtube channel, so please have a look
for that... because that goes into a lot of
detail with a lot of examples, so if
you're looking to learn and that should
help you out... but today we can just take
it that we're loading 1234
hexadecimal into r0 here, now all of the
registers on the ARM are 32-bit,
the value here being 2 bytes is 16 bit, 
so we're loading 1234 in the low half of
the register here, and then we're loading
r1 with 1234 in the top half of
the 32-bit register here... okay! well let's
just fire that up, let's see the result of that!
so you can see here r0 is 1234 here, 
and r1 is 1234 in the top
half of the register... OK, now here's a
very unusual thing... it's very unusual to
me anyway! now, let's say we wanted to
load a larger number... let's say we wanted
to load the top half with 12345
well ok not quite the top half... like more
than half (but you get what I mean)... well
that looks logical
but we would want to do that,
well let's have a look at what happens?
oh well!.. if I just changed my window here!
sorry, I'll just size my window here,
(I apologize for the mobile phone users)
it's very small but I will read it out!
it says "error constant 12345 is not
suitable for 8-bit rotated immediate"
that sounds a bit jargon ish! Well, we can
make it a bit easier... what it means is:
We can't set more than 4 digits at a time
in hexadecimal in a register with the
MOVe command... and this is all relating to
the way that the byte code actually compiles,
you see this command here
compiles to a single 32-bit chunk of data
and something like half of that will be
the command move, and the register number
that we're writing to, and the other half
is the digits and effectively the
position of those digits within the data
(within the destination register)
Now, let's just switch over to my other
screen here, and if we scroll around a little bit.
Effectively the bits are
being shifted when they're being stored
by the MOVe command in the immediate
register... so you (kind of) can see here
there's this kind of shifting effect here, 
and that's basically what is
happening internally... now you don't need
to obviously worry about that kind of thing
but the important thing you do
need to understand is that you will be
limited to how many bytes you can set 
at a giventime and in
this case we can only change two bytes
of the value when we're doing a MOVe command
well if you're going from 8-bit
and 16-bit you probably think
"well I don't need 32-bit so anyway!" (well maybe
you're thinking that!)... but if you're not,
or if you really want those extra bits
you're probably thinking "well that's
going to be pretty weird! how do I cope
with that?" well there's two options we
can either move the first half of the
value, and then add the second half
because and we'll look at that later,  
or the alternative is we store the value in
a piece of memory, and then we load in
from that piece of memory, and so that's
another good option! but we're going to
look at all of this later on. It's just a
thing that could easily catch you out
and sounds kind of crazy if
you're familiar with other systems that
you
load your whole register in one go on a
32-bit system it seems like: well, the
16-bit systems can, the 8-bit systems can
why can't the 32-bit systems?
and it's like: well that's kind of part of RISC!
and RISC-5 the same...
there are limitations in the same way. 
now some ,
assemblers may have special commands
that will actually allow us to load the
full part, and they will actually do
things internally, and split the command
up automatically for us... and that's where
your listing file can be quite handy, 
but as I say in this case I wanted to prove
the point that it doesn't work... to show
you know this this is the limitation
and so don't be surprised if you try to do
this and it doesn't work... okay! so we can
only load half of the 32-bit register
with a move command, but we can load it
into the bottom half the top half or any middle half... you know we can just
(to make it clear) we can do that just
right... oh that worked absolutely fine!
so it's the number of consecutive digits.
okay
so we've learned about the basics of
moving a hexadecimal value into a
register here... now what we're going to do
next is we're going to look at some
other kinds of value that we can load in.
Because while in a lot of cases we'll
want to work in hexadecimal (for at least
testing purposes) there will be times we
need to use binary and this times we
need to use decimal... now in VASM if we
want to use hexadecimal we use "0x" 
the x marks "hexadecimal" here
and that's because we always need these to start with the digit (0-9)... if we started with 'F0'
then the assembler wouldn't think that
was some kind of label so they always
have to start with 0x to denote hexadecimal
if we're working in binary we can use 0b and if we don't specify anything like
that we can just specify a number then
we work in decimal... now unfortunately I
don't know if this is just VASM or just me
being stupid, but I can't find a way to
get VASM to store ASCII characters... most
systems would allow you to put a letter
in quotes and it would compile that and
work out the ASCII equivalent
I can't figure out how to get VASM to do that, so I'm having to specify decimals here
so this is the equivalent of a letter A
here, and so I'm just storing that as a
decimal here... so let's just compile that,
and we'll see all of these results here.
okay! so let's have a look at these
values here... well, first we've loaded
hexadecimal 1234 into r0,
and you can tell that because of the 0x here
that means hexadecimal... and you can
see here that 1234 has
been loaded into r0 at the top here, 
just like you can see here..
now next we loaded binary 10101010 here,
and you can tell it's binary
because of this '0b' here ... you can see
here r1 contains the value 'a'  just here
now let's have a look at our calculator,
and if we change the binary and we do 10101010
we change to hex... you can see AA... 
so there we go! we can see that has loaded
in just fine... and r2 contains 41, and
we loaded in decimal 65 here which is
the equivalent of an ASCII A... so if we
just do we could do into the hex
but let's enter the decimal 65 and change to hex, and you can see that's hexadecimal 41 here
so you can see here r2 has
been loaded correctly... okay,
so we've looked at loading immediate values into
registers, and an immediate value means a
value that's held in the source code as
a number, and is in the same line as the
command to perform the operation. 
in this case a MOVe... so we've moved these
values into these registers, but the move
command can do the more than that
it can also transfer one register's value to
another... so in this case we've got a MOVe command.
the destination is on the left
of the comma - again the r0
the source is on the right hand side... this r2 here,
so we're moving r2 into r0 here
and let's just see that on our screen here, 
so you can see here before r2 is equal to 41
and r0 is equal to 1234... well
now we've transferred the 41 here from
r2 to the r0, and you can see r0 now also
equals 41... and so we've transferred the
entire 32 bits here to the 32 bits here,
and that's what the move command has
done for us... so we've looked at the move
command for setting registers - which is a
good start and we can use that to load
immediate values and also to transfer
between registers. But
(of course) we want to be able to do a
little bit of mathematics, and so we need
to look at some more commands
so we're going to look at addition and
subtraction, so these again are 32 bits
and we're going to use an immediate
value in these examples again.
so we're going to be performing an add, now the
add command you can see takes three
registers here, and the way you want to
think of this is that the left-hand side
again is the destination, and the
right-hand two are the two parts that
the maths is being performed on... 
so ADD R0,RO, all of this lot! (Lots of numbers)
means add r0 and  00005678, and
store the result in the left-hand side
register r0... well that means one of the
source values and the destination are both r0
but that works just fine. 
but that's not necessarily what we have to do
We could say r1 equals  r0 + 1 
in this case, it's just decimal 1 or
hexadecimal one (they're the same value) so we're
effectively adding 1 to r1 here
so we're effectively adding 1 in a rather
crude way to r0 here, and storing the
result in R1 here, so there we go that's
a perfectly acceptable thing to do.
we've got other options... we can do a
SUBtract... we can do that in the same way,
we've got r0 here, and we are just
subtracting this top nibble set to 1 here
from r0, and then we're just
subtracting 1 from r1 here again
and we're storing the value in r1 this time.
so this this time we were using register 0
as the source and register 1 is the
destination... But in these cases we're
using the same register itself and both
are perfectly legitimate, and that's one
of the powerful things about ARM in most
instruction sets, we've looked at in the past
you would have a destination, 
and the destination of the add or subtract
command would also be one of the sources
whereas in this case we can add register
2 to register 3 and store the result in
register 0... and register 2 & 3 are unchanged
so that gives us quite a lot
of flexibility there... so if we just
compile this, and have a look!.. so let's
see each stage as we went along,
So first we loaded the top 16 bits as 1234
here
you can see that just here, and then we added 5678 to the bottom part here.
and now you should see how we can sort
out that problem of not being able to
load the full 32 bits in one go.. 
what we can do is we can load in the first half,
and then add the second half and you can
see we've now set that value that we want
and you'll see that a few times in
my test code I do that quite a bit
so that's what we can do there! and then what we've done here is we've set r1 to
r0 +1 and you can see here this
was 12345678 and this is 12345679
we have indeed added one, and of
course we have left r0 unchanged
by that operation... because the
destination the left hand side was r1
okay! now, addition isn't the only thing
we can do... as we said: subtraction - in this
case, what we've done is we've subtracted
the top nibble of one from r0
well if you look before it was 12345678
the 1 has been subtracted... so now it's
02345678 so there we go! a strange thing
to do, but that's what we did! and then we
subtracted the one that we added before
to r1, and so you can see that r1
is now 12345678 again, which
it was when it was loaded in from r0
by this addition command up here, so
we've got some options there with
various values here... now I'm
showing these with immediate values
but we don't have to use immediate here, we could use a register, we could subtract
r0 from r1 and store the result in r1... and so there you, go you can see
we've subtracted r0 from r1, and
that has given us this 1 lots of zeros
and then a 1 here.. so I'm showing these
with immediate options here, but there's
a wide variety of choices with regards
to the register that you can use as the
right-hand-side parameter now what I'd
suggest you do is you download my cheatsheet
which has got some more details on this, 
and also if you have a go yourself
and you should be able to start to
understand what the limitations are,
basically the parameter here always has
to be a register. The parameter on the
right hand side can be more complex in a
lot of cases... we're going to go over in
next week's lesson over the all of the addressing modes
the different options that we can
specify here: the registers, the immediate values
and so on it's going to be quite
complex, but we will go over that
so please follow along for that so there
we've had a look at some simple addition
subtraction and setting of registers.
okay so let's have a look at reading and
writing from memory...  Now, we've looked at
using the registers, but of course we're
going to need more storage than that,
because we've only got about ten
registers that we can reasonably use and
you know we're going to need to store
things to them from memory, and we're
going to start looking at that now.
Now with the ARM processor there's sort
of two ways we can work with memory
in limited cases we will be able to use the
immediate values, if the memory were
working with is nearby... but in the same
ways we can't load very long strings of
hexadecimal into an address, we also can
only add address relatively nearby
pieces of memory directly without
using another register to store that
address into... so what we're going to do
here is we're going to load in from the
nearby address "Rest Val" here, and we're
going to load with this LDR command into r0
so r0 is the destination, and "Test Val"
is the source address here and then
we're going to show the results to the
screen, we're then going to add one to
the register r0... which we read in from
Test Val... and then we're going to use STR
which is STtore, and this is one of
the real exceptions.. because on this case
the left-hand part being register r0 is
the source and test Val the address is
the destination... so this is storing r0
to address "Test Val"... and then we're
going to show the monitor again, so we
can see what happened!... and then we're
going to show the address here again to
the screen, and we're going to see the
results there so that we can confirm
that that change occurred. so let's fire
that up and see that happening... so let's
fire up our code here and here we...
here it is! so you can see here we loaded the
test value with FEDCBA98 here
and our "Show Test Ram" function
shows that to the screen... so here it is here
but you can see that it's backwards,
now that's probably not much of a
surprise to you if you've done assembly before... this is something
known as little-endian where the lowest
byte values come first, and the highest
value comes last so 98 BA  DC FE here
is this just reverse... because that's
the way we store things in memory, now
with the ARM processor that's sort of optional
In theory the processor can
work in either mode, but in practice
I believe it's basically always ittle-endian, 
so and that's what we will
be working with... so we showed that value
to the screen here, we then loaded in
from the address "TestVal" into r0 with
the LDR command here, and you can see
that just here... we've loaded that value
in. we then added 1 to r0, and we stored
the result in r0 because the result is
stored in the left hand side register
with ADD, and so you can see that went up
to 99 here, and then we stored that value
and of course that didn't change there
but then we dumped the memory to the
screen again, the same memories we dumped
here - which is of course this value here,
and you can see that has now gone up to
99... so we successfully changed our
register value here, and after loading it
in here we stored it back here and
change the memory accordingly... ok now one
thing I do have to point out is if we
run this on the Gameboy Advance it will
run but... you can see here the test value
started off at as 98 here, and it ended
as 98 here... and the reason for that is
that this is running from ROM and this
is read-only memory of course, so that
Write commands didn't work... so we will
have to really test this on the RISC OS machine
but as I say we can work with
the RAM within the Game Boy Advance in
other examples, but for this very simple
example it didn't really feel
appropriate to do that, so we're just
testing on them with nearby
memory here... okay now that's how we can
use a address specifying it in line
but there is another alternative, what we can do is we can load the address into a
register and then use that register as
the source, and we put it in little
square brackets here... now we'll be going
over all of these options next week in
the addressing modes tutorial where
we're going through each addressing mode
ability in a simple example... but just for
today, I thought we'd go over the basics
of them just here... so what we're doing
here is we're loading in r1, and we're
loading it from the address in r2, and
you can see that's denoted by these
square brackets here, and then we're
going to show r1 to the screen.
okay so let's have a look at that, 
well you can see that this memory address here is
8608 just here, and we
loaded that into r2 with the ADR command
the source was "Test Val" and the
destinations was r2 and that's why you
can see here r2 is 860... so there we go, so we then loaded in
r1 from r2, and you can see r1
is FEDCBA99 which is the
value that this currently holds, then
what we've done here is we've loaded a
new value in from an immediate 00122100, and we've loaded a different
address,
now this address is being specified differently
it's specified with a hash,
and that's because we've defined this
with a symbol, now we'll have a look at
that in just a moment, and then we've
stored r0 to the address in r2 with
those square brackets... again, now what
we've done next is we've shown this
other RAM area and this RAM area on this
system is 8000, and you can see 00122100 with little endian
of the value is stored here... 
now this user ram will be it's a different
location depending on the system, so if I
just have a look at my source Game boy Advance Header
you can see the "user ram"
is being defined as being equivalent to
this long address here, which I'm not
going to try and read out!... so this is
known as a symbol, now a label when we
define it it's pointing
to a byte within the compiled source
code, and the jump will jump to that byte
but we can also define other kinds of
symbol, and this is saying well when you
see "user ram" in this source code, it
equals that value but with VASM that
does mean that we can't use the load
address command to actually read this in
rather than using ADR as we did
here with VASM we have to specify "User Ram"
with a hash symbol (#) because it's
actually a numeric value, but effectively
the result will be fine for us,
r2 will contain the address we want to use
and then the store command will
store r0 because remember that
with the store command, especially the
left hand side is the source and the
right-hand side is the destination and
the destination is the address in r2 and
the address in part is defined by the
square brackets here, then we're showing
the results on screen and we're showing
the user Ram area to the screen,
we've just got these little user ram functions
and test ram functions just to show
bits and memory to the screen easily, 
and we're not going to go into the exact
workings of those, these are just little
functions that you can see further down
in the source code they're using some
little tools I've written just for these tutorials
but it's way beyond what we're
trying to do in this lesson we're just
looking at the real basics of the system
we are going to be doing more of that
later in the next episode which is going
to be the addressing modes... where we go
over each addressing mode in some detail,
but next we're going to have a look at
this second read and write example, 
so let's go and have a look at that
and here it is, just here now we've looked
there at loading and storing to memory,
but we've been working in 32 bits
because that is the way the arm CPU
wants to work (if you will) that's the way
it's most efficient... but obviously
there's going to be times when that's
not appropriate... for example my graphical
font I use is one bit per pixel, and each
character is one byte wide... so loading in
32 bits isn't going to make a lot of
sense, so there will be times where we
need to work in bytes and the Arm 2
allows us to do that, we just add a B
letter to the end of our load or our
store commands, and instead of loading 32
bits it will load in just 8... now you
can see here we're loading in a full set
of ones here (FFFF0000) and then adding
0000FFFF making all of the bits of
the register one, and that's just so we
can see what happens when we load in
some test values... so let's fire this up
and let's see the example here and you
can see here we loaded our zero with all
ones here which sets it all to F,
then we load it in from "test value" as
before and we load it in just a byte
LDRB into r0... so we're loading in from
this address here, the left hand side
(little endian)
and we loaded in 98 but notice how all
of the other bits have been set to zero
here, so you can see here that it
actually cleared out the rest of the
register, which is quite kind of it in
some ways!  because that is probably gonna
solve some problems (if we forgot to clear the rest)
but anyway,
we've loaded in the value here and then
what we've done is we've added 255, now
of course the limit of a byte is 255
so that's going to make it roll over, and go
beyond the single byte, and this was just
to make the point that when we stored
the byte back, and showed to the screen
again well then 98 + 255 in hexadecimal
was 197 but when we stored the bike back
we only stored the byte back, so only 97
was stored here... and that this one was lost
now of course if we took the B off,
so if you take the day off, and we
compile again... well lo and behold!
now all of these bits have been set to 0 and 1
has been stored just here... so that's what
we can do there... now you may be
thinking "well that's how we can do bytes,
and that's how we can do 32 bits, but
what about if we want to do 16 bits?"
now we will be looking at that in a later
lesson,  but unfortunately the original
arm 2 didn't support those operations, so
we do have to either work in 8 bits or
32 bit on the arm 2... so that's the limitation there, now another thing we
were just will briefly cover is we can
store data in line in our code here if
we need to, but we do have to make sure
we're always 32-bit aligned when it
comes to the program code itself ,so you
will want to put in an align for command if
there's any possibility you won't be
aligned correctly in your code here,
so for safety I probably should have put
an "align 4" in just here
now of course this is 32 bit aligned, but just in
case I decided to put a byte in
in afterwards, if I put byte 1 in here
and then compiled, that will work just fine,
but if I take this out... I will get,
 I've actually got a warning saying
it's been Auto aligned, which is better
than nothing... but that was
sloppy coding of me!  that's
the thing you shouldn't do! now the arm
literally cannot run commands unless
they're correctly aligned and in the
original processor the Arm2 the bottom
two bits of the program counter actually
had a completely different purpose! they
were used for statuses for the
processor mode (I think it was)... but anyway
that's basically what we're going to cover today
so let's go back to our example
code here, okay so we've covered
everything that we needed to there... we've really just done the basic seeing a
few arm commands and getting a feel for
the absolute fundamentals of the system,
it is a little bit more tricky than some
of the systems you may be familiar with  -
(68000 and things) I personally find
it a bit harder, but  you have to admit
the power of it, and we really haven't
looked at that power yet... we will start
to see it when we look at the addressing
modes, because it can do some crazy stuff
compared to other systems, so we'll have
a look at it more next time
I hope you've enjoyed this... I hope you
found it interesting, if you have please
like and subscribe... if you haven't liked it then I
guess don't!!! but I do have other
tutorials if you want to see other
content... I've got 8086 tutorials 6502
and 68000 i'm also going to be doing risc-V
very shortly as well... so if that sounds
something you would be interested to
hearing a bit about, please follow on for that
anyway I hope you found this
interesting today, you can download all
the source code for today's example from
my website, and the development tools the
build scripts and the pre-configured
notepad++ will be available for download
so hopefully that will help you
get started a bit quicker,
if you're looking to do some programming ....anyway
whatever, I hope you've enjoyed this I
hope you found it amusing! thanks for
watching today and goodbye!
