computer organization and design addressing modes montek singh wed, sep 19, 2012 lecture 6
TRANSCRIPT
Computer Organization and Computer Organization and DesignDesign
Addressing ModesAddressing Modes
Montek SinghMontek Singh
Wed, Sep 19, 2012Wed, Sep 19, 2012
Lecture 6Lecture 6
Operands and Addressing Operands and Addressing ModesModes
• Where is the data?• Addresses as data• Names and Values• Indirection
Reading: Ch. 2.3, 2.14
C vs. JavaC vs. Java For our purposes C is almost identical For our purposes C is almost identical to Java except:to Java except:C has C has ““functionsfunctions””, JAVA has , JAVA has ““methodsmethods””
function == method without function == method without ““classclass””i.e., a global methodi.e., a global method
C has C has ““pointerspointers”” explicitly explicitlyJava has them (called “references”) but hides them Java has them (called “references”) but hides them under the coversunder the covers
JVM takes care of handling pointers, so the JVM takes care of handling pointers, so the programmer doesn’t have toprogrammer doesn’t have to
C++ is sort of in-between C and JavaC++ is sort of in-between C and Java
In this class, we will see how In this class, we will see how pointers/references are implemented at pointers/references are implemented at the assembly language levelthe assembly language level
What is a “pointer” in C?What is a “pointer” in C? A pointer is an explicit A pointer is an explicit memory addressmemory address
ExampleExampleint iint i
ii is an integer variable is an integer variablelocated at, say, address 1056located at, say, address 1056
int *pint *ppp is a variable that “points is a variable that “points to” an integerto” an integer
pp is located at, say, address is located at, say, address 20042004
p = &ip = &ithe the value in value in pp is now equal is now equal totothe the address of variable address of variable ii
i.e., the value stored in i.e., the value stored in Mem[2004] is 1056 (the Mem[2004] is 1056 (the location of location of ii))
1056
i
p
Memory
address
1056
1060
1064
1068
20002004
Referencing and Referencing and DereferencingDereferencing Referencing an object meansReferencing an object means
… … taking its address and taking its address and assigning it to a pointer assigning it to a pointer variable (e.g., variable (e.g., &i&i))
Dereferencing a pointer Dereferencing a pointer meansmeans… … going to the memory address going to the memory address pointed to by the pointer, and pointed to by the pointer, and accessing the value there accessing the value there (e.g., (e.g., *p*p))
ExampleExampleint i;int i; // i is an int variable// i is an int variable
int *p;int *p; // p is a pointer to int// p is a pointer to int
p = &i; p = &i; // referencing i// referencing i
// p is assigned 1056// p is assigned 1056
*p = 5; *p = 5; // dereference p// dereference p
// i assigned 5// i assigned 5
5
1056
i
p
Memory
address
1056
1060
1064
1068
20002004
Pointer expressions and Pointer expressions and arraysarrays Dereferencing could be done to an Dereferencing could be done to an expressionexpression So, not just So, not just *p*p, but can also write , but can also write *(p+400)*(p+400)
accesses memory location that is 400th int after accesses memory location that is 400th int after ii
Arrays in C are really pointers underneath!Arrays in C are really pointers underneath! int a[10];int a[10]; // array of integers// array of integers aa itself simply refers to the address of the itself simply refers to the address of the startstart of the array of the array
aa is the same as is the same as &a[0]&a[0] aa is a constant of type “ is a constant of type “int *int *”” a[0]a[0] is the same as is the same as *a*a a[1]a[1] is the same as is the same as *(a+1)*(a+1) a[k]a[k] is the same as is the same as *(a+k)*(a+k) a[j] = a[k];a[j] = a[k]; is the same as is the same as *(a+j) = *(a+k);*(a+j) = *(a+k);
Pointer arithmetic and Pointer arithmetic and object sizeobject size IMPORTANT: Pointer IMPORTANT: Pointer expressions automatically expressions automatically account for the size of account for the size of object pointed toobject pointed toExample 1Example 1
if p is of type “int *”if p is of type “int *”and an int is 4 bytes longand an int is 4 bytes longif if pp points to address 1056, points to address 1056,(p=p+2)(p=p+2) will point to address will point to address 10641064
C compiler automatically does the C compiler automatically does the multiply-by-4multiply-by-4
BUT… in assembly, the programmer BUT… in assembly, the programmer will have to explicitly do the will have to explicitly do the multiply-by-4multiply-by-4
Example 2Example 2char *q;char *q;q++; // really does add 1q++; // really does add 1
1056
i
p
Memory
address
1056
1060
1064
1068
200020041064
Pointer examplesPointer examplesint i;int i; // simple integer variable// simple integer variable
int a[10];int a[10]; // array of integers// array of integers
int *p;int *p; // pointer to integer// pointer to integer
p = &i;p = &i; // & means address of// & means address of
p = a;p = a; // a means &a[0]// a means &a[0]
p = &a[5];p = &a[5]; // address of 6// address of 6thth element of a element of a
*p*p // value at location pointed by p// value at location pointed by p
*p = 1;*p = 1; // change value at that location// change value at that location
*(p+1) = 1;*(p+1) = 1; // change value at next location// change value at next location
p[1] = 1;p[1] = 1; // exactly the same as above// exactly the same as above
p++;p++; // step pointer to the next element// step pointer to the next element
Pointer pitfallsPointer pitfallsint i;int i; // simple integer variable// simple integer variable
int a[10];int a[10];// array of integers// array of integers
int *p;int *p; // pointer to integer(s) // pointer to integer(s)
So what happens whenSo what happens when
p = &i;p = &i;
What is value of What is value of p[0]?p[0]?
What is value of What is value of p[1]?p[1]?
Very easy to exceed bounds (C has no Very easy to exceed bounds (C has no bounds checking)bounds checking)
Iterating through an arrayIterating through an array 2 ways to iterate through an array2 ways to iterate through an array
using array indicesusing array indicesvoid clear1(int array[], int size) {void clear1(int array[], int size) { for(int i=0; i<size; i++)for(int i=0; i<size; i++) array[i] = 0;array[i] = 0;}}
using pointersusing pointersvoid clear2(int *array, int size) {void clear2(int *array, int size) { for(int *p = &array[0]; p < &array[size]; p++)for(int *p = &array[0]; p < &array[size]; p++) *p = 0;*p = 0;}}
or, also using pointers, but more concise or, also using pointers, but more concise (more cryptic!)(more cryptic!)
void clear3(int *array, int size) {void clear3(int *array, int size) { int *arrayend = array + size;int *arrayend = array + size; while(array < arrayend) *array++ = 0;while(array < arrayend) *array++ = 0;}}
Pointer summaryPointer summary In the In the ““CC”” world and in the world and in the ““machinemachine”” world: world:
a pointer is just the address of an object in a pointer is just the address of an object in memorymemory
size of pointer itself is fixed regardless of size size of pointer itself is fixed regardless of size of objectof object
to get to the next object:to get to the next object:in machine code: increment pointer by the objectin machine code: increment pointer by the object’’s size s size in bytesin bytes
in C: increment pointer by 1in C: increment pointer by 1 to get the ith object:to get the ith object:
in machine code: add in machine code: add i*sizeof(object)i*sizeof(object) to pointer to pointerin C: add in C: add ii to pointer to pointer
Examples:Examples: int R[5]; // 20 bytes storageint R[5]; // 20 bytes storage R[i] is same as *(R+i)R[i] is same as *(R+i) int *p = &R[3] is same as p = (R+3) int *p = &R[3] is same as p = (R+3) (p points 12 bytes after start of R)(p points 12 bytes after start of R)
Addressing ModesAddressing Modes
What are all the different ways to What are all the different ways to specify an operand?specify an operand?
Revisiting OperandsRevisiting Operands Operands = the variables needed to Operands = the variables needed to perform an instructionperform an instruction’’s operations operation
Three types in the MIPS ISA:Three types in the MIPS ISA:Register:Register:
add $2, $3, $4add $2, $3, $4 # operands are the # operands are the ““contentscontents”” of of a registera register
Immediate:Immediate:addi $2,$2,1addi $2,$2,1 # 2nd source operand is part of # 2nd source operand is part of the instructionthe instruction
Register-Indirect:Register-Indirect:lw $2, 12($28)lw $2, 12($28) # source operand is in memory# source operand is in memory
sw $2, 12($28)sw $2, 12($28) # destination operand is memory# destination operand is memory
Simple enough, but is it enough?Simple enough, but is it enough?
MIPS can do these with appropriate choices for Ra and const
Common Common ““Addressing ModesAddressing Modes””
Absolute (Direct): lw $8, 0x1000($0)
– Value = Mem[constant]– Use: accessing static data
Indirect: lw $8, 0($9)– Value = Mem[Reg[x]]– Use: pointer accesses
Displacement: lw $8, 16($9)– Value = Mem[Reg[x] +
constant]– Use: access to local
variables
Indexed:– Value = Mem[Reg[x] +
Reg[y]]– Use: array accesses
(base+index)
Memory indirect:– Value = Mem[Mem[Reg[x]]]– Use: access thru pointer in
mem
Autoincrement:– Value = Mem[Reg[x]]; Reg[x]++– Use: sequential pointer
accesses
Autodecrement:– Value = Reg[X]--; Mem[Reg[x]]– Use: stack operations
Scaled:– Value = Mem[Reg[x] + c +
d*Reg[y]]– Use: array accesses
(base+index)Is the complexity worth the cost?Need a cost/benefit analysis!
Relative popularity of Relative popularity of address modesaddress modes
From Hennessy & Patterson
Absolute (Direct) AddressingAbsolute (Direct) Addressing What we want:What we want:
Contents of a specific memory location, i.e. Contents of a specific memory location, i.e. at a given addressat a given address
Example:Example:
CaveatsCaveatsIn practice $gp is used instead of $0In practice $gp is used instead of $0Can only address the first and last 32K of Can only address the first and last 32K of memory this waymemory this way
Sometimes generates a two instruction Sometimes generates a two instruction sequence:sequence:
“C”int x = 10;
main() { x = x + 1;}
“MIPS Assembly”.data.global xx: .word 10
.text
.global mainmain:
lw $2,x($0)addi $2,$2,1sw $2,x($0)
lui $1,xhighbitslw $2,xlowbits($1)
Allocates space for a single integer (4-bytes) and initializes its value to 10
Absolute (Direct) Absolute (Direct) Addressing: Addressing: More detailMore detail
“C”int x = 10;
main() { x = x + 1;}
“MIPS Assembly”.data.global xx: .word 10
.text
.global mainmain:
lw $2,x($0)addi $2,$2,1sw $2,x($0)
“After Compilation”.data 0x0100.global xx: .word 10
.text
.global mainmain:
lw $2,0x100($0)addi $2,$2,1sw $2,0x100($0)
Assembler replaces “Assembler replaces “xx” by its address” by its addresse.g., here the data part of the code (e.g., here the data part of the code (.data.data) ) starts at 0x100starts at 0x100
xx is the first variable, so starts at 0x100 is the first variable, so starts at 0x100
Indirect AddressingIndirect Addressing What we want:What we want:
The contents at a memoryThe contents at a memory address held in a register address held in a register
Examples:Examples:
CaveatsCaveatsYou must make sure that the register contains You must make sure that the register contains a valid addressa valid address(double, word, or short aligned as required)(double, word, or short aligned as required)
“C”int x = 10;
main() { int *y = &x; *y = 2;}
“MIPS Assembly”.data.global xx: .word 10
.text
.global mainmain:
la $2,xaddi $3,$0,2sw $3,0($2)
lui $2,xhighbitsori $2,$2,xlowbits
“la” is not a real instruction, It’s a convenient pseudoinstruction that constructs a constant via either a 1 instruction or2 instruction sequenceori $2,$0,x
Note on Note on lala pseudoinstruction pseudoinstruction lala is a pseudoinstruction: is a pseudoinstruction: la $r, xla $r, x
stands for “load the address of” variable stands for “load the address of” variable xx into register into register rr
not an actual MIPS instructionnot an actual MIPS instructionbut broken down by the assembler into actual but broken down by the assembler into actual instructionsinstructionsif address of x is small (fits within 16 bits), if address of x is small (fits within 16 bits), then a single then a single oriori
if address of x is larger, use the if address of x is larger, use the lui + orilui + ori combocombo
“MIPS Assembly”.data.global xx: .word 10
.text
.global mainmain:
la $2,xaddi $3,$0,2sw $3,0($2)
lui $2,0x8000ori $2,$2,0x0010
ori $2,$0,0x1000x0100 0x80000010
Displacement AddressingDisplacement Addressing What we want:What we want:
contents of a memory location at an contents of a memory location at an offset offset relative to a registerrelative to a registerthe address that is the sum of a constant and a the address that is the sum of a constant and a register valueregister value
Examples:Examples:
CaveatsCaveatsMust multiply (shift) the Must multiply (shift) the ““indexindex”” to be to be properly alignedproperly aligned
“C”int a[5];
main() { int i = 3; a[i] = 2;}
“MIPS Assembly”.data 0x0100.global aa: .space 20
.text
.global mainmain: addi $2,$0,3 // i in $2 addi $3,$0,2 sll $1,$2,2 // i*4 in $1 sw $3,a($1)
Allocates space for a 5 uninitialized integers (20-bytes)
Displacement Addressing: Displacement Addressing: 22ndnd exampleexample What we want:What we want:
The contents of a memory location relative to a The contents of a memory location relative to a registerregister
Examples:Examples:
NoteNoteoffsets to the various fields within a structure offsets to the various fields within a structure are constants known to the assembler/compilerare constants known to the assembler/compiler
“C”struct p { int x, y; }
main() { p.x = 3; p.y = 2;}
“MIPS Assembly”.data.global pp: .space 8
.text
.global mainmain: la $1,p addi $2,$0,3 sw $2,0($1) addi $2,$0,2 sw $2,4($1)
Allocates space for 2 uninitialized integers (8-bytes)
Assembly Coding TemplatesAssembly Coding Templates
For common C program fragmentsFor common C program fragments
Conditionals: Conditionals: if-elseif-else
C code:
if (expr) { STUFF1} else { STUFF2}
MIPS assembly:(compute expr in $rx)beq $rx, $0, Lelse
(compile STUFF1)beq $0, $0, Lendif
Lelse:
(compile STUFF2)Lendif:
C code:
if (expr) { STUFF}
MIPS assembly:(compute expr in $rx)beq $rx, $0, Lendif
(compile STUFF)Lendif:
There are little tricks that come into play when compiling conditional code blocks. For instance, the statement:
if (y > 32) { x = x + 1; }
compiles to: lw $24, y ori $15, $0, 32 slt $1, $15, $24 beq $1, $0, Lendif lw $24, x addi $24, $24, 1 sw $24, xLendif:
Loops: Loops: whilewhile
MIPS assembly:
Lwhile:(compute expr in $rx)
beq $rX,$0,Lendw
(compile STUFF)
beq $0,$0,Lwhile
Lendw:
C code:
while (expr)
{ STUFF}
Alternate MIPS assembly: beq $0,$0,Ltest
Lwhile:(compile STUFF)
Ltest:(compute expr in $rx)
bne $rX,$0,Lwhile
Lendw:
Compilers spend a lot of time optimizing in and around loops- moving all possible computations outside of loops- unrolling loops to reduce branching overhead- simplifying expressions that depend on “loop variables”
Loops: Loops: forfor Most high-level languages provide loop Most high-level languages provide loop constructs that establish and update an constructs that establish and update an iteration variable, which is used to control iteration variable, which is used to control the loopthe loop’’s behaviors behavior
MIPS assembly:sum: .word 0x0data: .word 0x1, 0x2, 0x3, 0x4, 0x5 .word 0x6, 0x7, 0x8, 0x9, 0xa
add $30,$0,$0Lfor: lw $24,sum($0) sll $15,$30,2 lw $15,data($15) addu $24,$24,$15 sw $24,sum add $30,$30,1 slt $24,$30,10 bne $24,$0,LforLendfor:
C code:
int sum = 0;
int data[10] = {1,2,3,4,5,6,7,8,9,10};
int i;
for (i=0; i<10; i++) { sum += data[i]}
Next ClassNext Class WeWe’’ll write some real assembly codell write some real assembly code Play with a simulatorPlay with a simulator