Lecture 12 – Orthogonal ISA, C Constructs Mapping, Addressing Modes

and equivalently ah this was done by intel
and equivalently there was that ah ah three d now by a m d now we will continue on this
discussion on the evolution of instruction set architectures so next step would be as
we know that an instruction basically has an opcode and operands
on the operand side there are many decisions that need to be taken for example how many
operands right so what is the rational behind having
ah these many amount of operands so this one one very important decision that we need to
take and the next is type of operands and another important thing is is there a
relation between opcode and operands ok so can i have say some instruction there are
some in opcodes for which there are two operands some opcodes for which there are three operands
and so on if that is the case and then this these sets are quite large like there are
some say thirty different unrelated opcodes for which there will be two operands and some
forty opcodes for which there are three operands then what would happen here is as i told you
earlier there are two levels of translation first is you are high high level language
gets compiled into a machine language then this machine language is interpreted by your
hardware so every instruction has to be understood by your hardware and that is what we call
as decoding and instruction right so there are ones and zeros that are coming into your
ah ah hardware and the hardware should understand yes i have to do i had on this subtract on
this so thats there is an implicit understanding there is happening within the hardware and
when that is happening the hardware should essentially realise what is the opcode and
what are the operands right that’s also a part of you know your understanding procedure
understanding process now if i can go and interpret my opcode and the operands concurrently
then my understanding process becomes faster right if i can go and interpret the operands
independent of the opcode right any let any let let there be any opcode my decoding or
understanding of what the operands are are independent of is independent of the opcode
if suppose such a scenario exist then your understanding process becomes easy i will be understanding what do you mean by
understanding we will when we see the actual hardware we will understand [laughter] what
you mean by understanding why what do you what do you mean by hardware understanding
the ah you know instructions but i can go and understand what the operands concurrently
with while i am trying to interpret what the opcode is so instruction set architectures
where the opcode is independent of the operands and vice versa are called orthogonal i s a’s now we will try and be as orthogonal as possible
it’s not it’s not possible to be completely orthogonal and we will try and be as orthogonal
as possible ok so so if you look at the hack i s a that we did last semester it is almost
orthogonal right now what is one necessary condition for an orthogonal i s a what is
one condition that will make orthogonal i s a ah possible ah fixed length fixed length ok so i need to have fixed length
if i don’t have fixed length automatically it implies that depending on some opcode some
operand will be somewhere etcetera ok so so mostly the risc i s a’s or more orthogonal
than the cisc i s a’s because risc i s a’s or more or fixed length when compared to cisc
i s a’s ok so there are three points that we want to cover today an instruction comprises
opcode and operands now we have to discuss more on the operands before that for the implicit
translation process interpretation process there is a there are opcode there are operands
and there should be an deciphering of the opcode and operands by the hardware and that
is going to be fast if you are going to have orthogonal orthogonality established between
them and i will try to be as orthogonal as possible i can’t have that hundred percent
orthogonality and risc i s a’s are much more orthogonal then the cisc i s a’s right that’s
why risc process do work faster is not that cisc doesn’t work but actually what happens
is today if i have a cisc processor the way the cisc processor is constructed this is
what we infer nobody tells you how it is done ah is that all this cisc instructions there
is a layer which interprets it and converts it in to risc every cisc instruction gets
converted into a underlying risc instruction and then below this is a risc processor which
executes so from the operating system or from from the outside view you only see a sisc
processor but the cisc instructions are not directly executed on on on a cisc processor
by say cisc hardware the underlying hardware is a cisc hardware and all your ah risc instruction
cisc instructions are interpreted or converted into a set one or more risc instructions and
it’s executed on cisc processor this is how ah so building cisc processors
are becoming difficult and this is how the complexities basically taken care of so there
is one hardware layer intermediately which will interpret this cisc and convert to ah
risc so this particular concept is called code morphing
ok so there ah there is been an extensive research in m i t so just google this on code
morphing is a very old concept but it’s a very interesting concept ok now we will go
on the next discussion would be on the operands so how many operands should i have two should
i have three right these are all questions right and so why should i have three why should
i have two so what are the decisions so can you give me some reasons for why should i
have three three operands we like say add r one r two r three so i these are three operands
instruction r one is equal to r two plus r three but i could i have again add e a x comma
e b x where e a x is e a x plus e b x why should i have this why should i have this
what are the pros and cons of having a three operand versus a two operands if you want to preserve the original value
then you don’t want to put it back to the result value ok so one thing is preserving original values
right so this allows you to preserve original values while ah this your origin one of the
original value is lost but normally registers registers are basically
used as scratch pads they only store temporary results so there is no reason there is so
for example normally ah i will have things like b equal to c plus or i will have b plus
plus where i have to update that value or c plus plus c is equal to c plus a right so
normally when you look at many of the ah you know programming ah when you see the actual
ah you know code you will see that a variable modifies itself as a part of your assignment
statement right the normal ah thing that you see so again if you ask our analytical proof
i cant give but this is how code is written ok very rarely you will say say for example
somewhere like matrix multiplication you will say a equal to b plus c a i j is very rarely
you will see such type of constructs so many point of time we will we will have a variable
that is getting incremented or get that is getting added to some other variable so the
so that is why we are happy with this scratch pads where we are happy with you know two registers
here see the point is when i even i say c equal to a plus b both a and b are in memory
ok both a and b are in memory so i have to fetch it from memory right i have to go and
fetch it from memory and then add it so my easiest way is let a b stored at thousand
b b stored at thousand four i will go and bring ah into the thing is i will if you let
if you use this i will just say move in to e a x thousand and then i can say add a x
with two thousand four and say let this be thousand eight i will sto i will move two
thousand eight a x this is the easiest code i can write here right so even if you have
if you have if you have instructions like this these instructions are basically stored
in memory and i can go and access from there and store right are you able to get this but
you could ask me right i could can i have something like even add thousand eight thousand
thousand four this is simplest instruction but i will have three memory addresses here
so if i have a three address three operand instruction can i do something like this first
and foremost yes if i have a operand instruction and each operand can be a memory then i can
do the but is it practically possible or not what are what is the what are the difficulties
in this writing in to the memory i will write in to the memory read thousand
four and thousand from memory and then write it write the answer add it and and write back
the answer in to thousand eight what will be the practical difficulty here temporary register we need temporary some
scratch by the store memory no i can directly see if you use the intel
ah ah architecture you can directly access from memory as a part of your instruction
i could have something like this for sure right these three are valid instructions in
intel move a x add a x and this so what stops you from having such type of ah such type
of things we may need more or registers but more imp practically what is the difficulties
not only takes time now i am taking three instruction time here it is impossible to
implement this because i for me to access memory i have a memory management unit and
it can at a at a point of time take only mem one memory request from ah one c p u right
that’s the that’s the practical difficulty i could not have two memory request then the
whole memory management unit construction of that memory management unit becomes extremely
complex are you able to get this right so that is very very important so that is a there
is there is a difficulty in even creating this type of a memory management where i can
go and read two simultaneously i can read i can give two address read two address and
and also write one right so and this should be viewed in the context of pipe lining which
we will be talking next ok so so there is a practical difficulty in having two memory
operands in the same instruction leave alone three even two so if you carefully look at
the entire intel ah i s a that thousand or pages thousand plus pages you will never find
an instruction that has explicit two memory accesses right it will not it will not have two explicit
two memory accesses ok there are some set of instructions we will see where both the
destination and source are memory but there are very very specific instructions right
but you will not find two fellows which are explicit memory access so that is something
that we need to ah basically keep in mind so there are certain practical limitations
which stop you from having a ah uh now we are not even talking about three three operands
we are basically saying that two operands itself i cant have both the operands as memory
ok right now but why do so some of the risc architectures do have three address right
so what is the difficulty in having three other difficulty in having three addresses
and what are some some con something say so ah what are some characteristics of risc i
s a’s which enable you to have these three addresses one thing is so let us take some
dig in to compilers ah has basically you take a c language construct now this basically
gets converter into what we call as three address code or what we call as three address
intermediate representation yeah right right so what is so basically ah then this three
address code is basically converted in to a machine machine code right ah in in our ah ah um in the hack jack to
hack conversion your jack got ah converted in to a one address code correct because it
was push pop on to the stack but push in to something pop into something push from something
right so there was one address in many cases so but in general your c c language or any
high level language the compiler will convert it in to a three address code that means an
instruction with three operands right right so now if i have a three address three three
operand i s a this translation actually becomes simpler ok so if i have a three operand i
s a was that say this is a two operand i s a certainly this is much easier than this
when you do the compiler course you will also understand that generating a three address
code is much simpler there ok right so that is one motivation for lot of ah you know lot
of i s a is to have three address operands but when i look at three address operands
those type of i s a’s fall in to one category called load store i s a’s what do you mean
by a load store i s a there are only two instructions that touch
memory that access memory so in the entire ah computer science ah ah analyse of computer
science accesses essentially means read or write ok that’s one single word for read or
write only two instructions in the risc i s a in the in the load store i s a access
memory one is called load another is called store load will move from memory to a register
and store will move from register to memory all other instructions operate on
on registers like add r one r two r three these are all registers so i will not add
a memory operand inside the add operation ok so i will not have memory operands any
instruction except load and store so many of the i s a’s today the i s a inside you
are favourite arm processor which is in your mobile phone are all three address i s a’s
there are risc i s a’s they are all of fixed length and they are all load store i s a’s
because then the entire process becomes much more simplified so if you also carefully look
at the hack i s a it was also a load store i s a there was a load and store instruction
there is an a instruction so if you go carefully and look back into a ah hack ah i s a which
you did last semester it’s also a low storage ok now next so what are the type of operands
that we could have we have studied we have been discussing on the number of operands
now what are the type of operands that we could we could have immediate operands we
could have register operands and we could have memory operands
immediate operand means in the instruction itself the the the the value of the operand
would be therefore for example suppose i have something like c equal to zero this can translate
to move e c x comma zero x zero this is a hexadecimal representation or c equal to five
c equal to ten then i can say move e c s comma zero x a this is a hexadecimal value now this
is basically an immediate operand and you will see lot of places where you are doing
this initialisation so this is an immediate operand while this is called a register operand
or we call it as a register addressing mode so these these three are also called as addressing
modes the mode by which i address the operands this is a register operand or register addressing
mode this is an immediate the next one so there is so they have also seen some implicit
the addressing modes like your dev that we talked last time right there are some registers that are hidden that
on explicitly stated in the instruction but they get modified when you do a dev instruction
so we will talk about explicit ah so we have already talked about implicit operands so
we are now talking about explicit operands here so here e c x is a register operand and
this is an immediate so whenever i see a variable and that variable is temporarily used right
so or i am i am so i will start using register operations whenever i see a long expression
a plus b plus k plus two then i will start using register operands here whenever i see
a constant i will use an immediate operand so these are all very simple things that we
see the more complex things come in memory so intel has come out with excellent ah ah
ah excellent thought processing in terms of memory let us go and see the different memory
operand so in intel could have base plus care into index plus displacement this can go up
to thirty two bit displacement ok base you can have a all the ge general purpose registers
we call it as g p s general purpose registers i could have stack i could have e a x e b
x e c x e d x e s i e d i e b p and e s p all these things i could have then the scale
is one two four eight index again can be any of these d s p and displacement can be any
thirty two bit displacement and i could have a combinations of this ok right i could have
just base alone i can neglect everything else i could have base alone i could have displacement
alone i could have scale ind index alone i i could have just index i could have base
plus scale into index i could have scale in to index plus displacement i could have base
plus displacement on all possible combinations i could have right and if we actually go in
to um if the intel manual you will see that just to handle this complexity there is something
called mod r slash m plus scale index by sib bytes and it’s a big matrix that you see in
two pages very big matrix so the way this is translated in to machine language that
is your base this this addressing mode is translated into machine language that should
be a representation right so when the machine sees it should know that this is a base this
i should know its a address displacement it should know this is base plus scale into index
it should all these combination the hardware should understand so you should translate
it in a way that the hardware understands so for for break making the hardware understand
what sort of memory addressing you are trying to do there is something called mod r m plus
sib bytes two bytes there mod r m byte and sib bytes so if you look at the intel manual
two um manual two first or manual one last you will see a very big page with this mod
r m and sib bytes ok so there will be something close to five hundred and twelve entries something
like that before going in to why we need this i should also tell you that intel provides
this two five hundred and twelve bytes right of extensively co extremely complex byte you
know representation its the compiler actually sets it out to create that representation
then the hardware again sets it out consumes lot of your battery power to find out what
you are representing so all this are put in to your hardware please note that this interpretation
of your in instruction is its done by your hardware so there is an hardware which is
going to ah interpret your mod r m and sib byte right so but when we use traditional
compilers right some of the compilers which say i have a thirty two bit version of compiler
all these fellow shouts if you use those compilers if you go and disassemble the code and see
out of say all these five hundred and twelve possible combination ten combinations are
only used there are some combinations which are never used you take all the codes disassemble
them and see in a particular domain like you can take all your ah you know network domain
or your web transaction domain or your you know financial transaction domain or no normal
computing normal c code engineering domain very rarely you will see all these addressing
modes completely used you will see only ten percent or twenty percent of this two fifty
six rarely ten or fifteen of your two fifty five hundred and twelve bytes getting used
there so all the remaining thing or inside your ah you know hardware they are part of
your decoding right decoding they consume power they heat it up for some fan to cool
it further and again the fan will get heated up and this will cooling so some adiabatic
thermodynamics cycle is happening there is that nothing is getting used so the point here is that when a when we when
that’s why many of these software comp many of these hardware companies processor companies
do have their own software division they will have their own compiler division and the work
of that compiler division is to see how to use this hardware so i always say hardware
is like building a dam you have to fill it with water otherwise there is not use for
that dam who will fill it with water a good compiler will fill it water you understanding
this right i so when i give an interface there should be a layer which will try and use that
interface to the best possible thing so that’s why many of these companies today if we go
and look at intel a m d i b m all there are very very strong software division which will
write compilers and other things to basically see that their hardware is utilized very well
ok so that is another very important thing that we need to keep in mind now coming up
why at all these so many complexities that we have look at right now all this who is
driving all these things there should be some programming language construct that is going
to drive this right now for example if i have int star i this is a pointer right correct
how do i manage this i store so i will be say stored in some thousand four i will be
i i will be stored in thousand four which has some three thousand value right now when
i say star i it is the content of three thousand that i am trying to access so this value three thousand will be stored
somewhere in thousand four and i am going to access this three thousand ok so so so
there is one indirection that is happening here right so this i will not store the address
but we will not store the value but it will store the address where it is stored now how
do it go and manage you manage it with basically these ah you know the in the the instructions
the the the the register addressing modes right right so there are something called
l e a what you call as load effective address ok so there are certain certain instructions
i just leave it to you to go and find out what this l e a now these these are instructions
and then that l e a will basically you know try and load in to your register again so
we need something like ah three thousand in registers so some register e b x has three
thousand i need this three thousand there then i can go access this three thousand so
star i would be the content of three thousand which is nothing but the content of content
of thousand four correct are you able to follow this right star a is the content of i right
star a is the content of three thousand which is this so there are instructions basically used to
handle these type of activities so l e a is one instruction which can be used but nevertheless
suppose i have so so let us just use where we are using one register for addressing so
suppose i have ah ah int i int a of hundred right and then i say i equal to for i equal
to one to hundred i just do some processing on a so what i can do is first e b x will
be storing a let us say a starts at thousand five hundred ok a of zero is is stored at
thousand five hundred this is so e b x will have a right now and what i do every time
when i start doing here i will increment e b x by four and i will access e b x are you
getting this i will increment e b x by four and i will start accessing e b x so what is
as my loop goes on from one to hundred a zero would be one thousand five hundred when i
come to a one sorry when i come to a one then what happens by the time i increment e b x
by four so it is thousand five hundred and four and the content of thousand five hundred
four this so i can basically have a you know e b x ah one of the so e b x is basically
we will use e b p also because it’s a base pointer sometimes you can use a b p right
so so i can keep incrementing that register i can use any of these registers but i can
keep incrementing the registers to keep accessing the next ten next this elements so this is one use of ah you know register
addressing mode ah register based ah register direct memory addressing mode right if i just
use this register this is register direct right but then we need to go and talk about
the other parts like right so i said base plus scale in to index plus displacement
so how do you do this when we will i use base plus displacement suppose i have a struct
so i have int i int j and something ok the let ah so the structure will be stored structure
will start at thousand i will be stored from thousand to thousand three while j will stored
from thousand four to thousand seven ok now where will so i can use say thousand as e
b x then i can say e b x plus when when i compile so i assume that the structure base
of the structure will be load at e b x so i can now say e b x plus ah zero just e b
x would be ah i and e b x plus four will be j so this gives us base plus displacement
so other thing is if i don’t have something like struct this is quite easy so i have main
and in which i have int i j k as i told you and yesterday’s lab class the compiler assume
it starts from zero whenever it wants to access i it will say zero j it will say four k it
will say eight and so on so just displacement also so we have seen just displacement just
base base plus displacement now let us talk about scale index etcetera where do i use
base plus scale into index plus displacement can you give some interesting things array of structure or structure a structure
in which there is an array both of this are ok now more than that why do i want this scale
and scale into index so let us let me go into some very ah nice thing right so suppose i
have a loop this loop is trying to manipulate data types of different sizes this normally
you will see right it will manipulate say a short integers which is of say two bytes
it will manipulate an int which is of say byte four four bytes in size it will it will
go and manipulate you have double precision floating point which is eight bytes all this
can happened here right so so there could be some c i is equal to a i plus b i there
could be some a b c d d i is equal to four into a b c d e i then i could have f i is
equal to four point zero into k i all these things can be part of your right then what
could happen is that this i is a variable i would like to keep it in e c x c actually
stands for a counter so normally when the intel when the compiler translates the c always
goes for a counter ok there is a there is a there also a stands for an accumulator or
an so it’s so there were in initial architectures which are only the a registers just an accumulator
based architecture right c stands for counter right so like that you know s i and d i they
stand for index registers we will see some of them in the next s p stands for stack pointer
b p stands for base pointer etcetera so normally e c x will go and like what we did in one
of the earlier ah thing let me try and go there i don’t want to keep modifying that
e b p right here what did i do for i i just asked the i got incremented i kept adding
four to this but i don’t want to do it because i want i want i the e c x to represent i if
i keep modifying e c x as i increases if i keep modifying e c x by four adding e c x
adding four to e c x then for this i should add ah two p e c x for this i need to add
ah you know eight p e c x right i i have to mod ah you know modify e c x in three different
waste handle these three different arrays which is going to be extremely complex for
me i don’t want to do it so what i do is i when i am when i am doing
accessing this i will do it as ah two into e c x when i do this i will do it as four
into e c x when i do this i will do it as eight in to e c x and after doing one iteration
i will say increment e c x and i will make the base of ah no there are so many bases
here ok so we will we will try there is lot of work that needs to done here ok but this
is how i will use this scale in to index right the scale is used because i would like to
maintain one counter variable and if that loop is going to handle multiple arrays of
different sizes then i need to basically go and ah modify this interface right now e c
x will be i and your i will keep incrementing e c x as i proceed in your iteration but then
accessing individual entities here we will go with this scale so that’s an use of a scale
so the notion of scale came into your ah uh the notion of scale came into this ah you
know addressing mode because we wanted multiple data type so when an array acts when a when
a when a loop acts on array of multiple data types then scale becomes very useful ok now
can we tell what base plus scale into index plus displacement can you give me one example
right so i can take a struct in which i could have a string ok ok right so how do you do
this or int clue some forty eight courses right so i will put ok so how do you so where you will where you
can use this so there could be a base this struct would be say student record so there
could be a base so let their this record is stored at thousand the name starts or your
marks actually start more than name marks would be interesting ok we start that say
some fifteen thousand fifteen and it’s four four bytes
and so on ok so and if i want to access marks i right and this this let us say ah so i say
thousand plus the displacement would be this fifteen thousand is the base i am accessing
some field which is at least ah fifteen bytes away so this will be fifteen plus i say say
marks of i right so i is this index that will be this index so i want marks of four so four
and int int is the size of this so four if i want marks of eight marks of eight let us
say marks of some thirteen your thirteenth course then essentially i going say suppose
say suppose i start giving you real real marks ok so double then this would become eight
in to right so we can we can create one example so so this is base plus scale into index plus
you can you can construct several such example now this also explains why this particular
combinations very rarely used ok so ok so so for so what we have done today
we have we have understood about ah you know the relationship between opcode and operands
what are the benefits of you know ah a risk architecture ah what is orthogonal i s a and
then we went and discussed about different types of operands and we also showed some
mapping between c constructs and the way we address these operands ok thank you

Leave a Reply

Your email address will not be published. Required fields are marked *