IA32 Addressing Modes Chapter 5 The ISA Level cont’d.
Post on 23-Dec-2015
228 Views
Preview:
Transcript
addressing
• Opcode indicates what operation is to be performed.
• Operands specify the location of data.• Example of addressing modes that we have
already used:A = 12B dword 52
mov eax, 1 ; immediatemov ebx, eax ; registermov ecx, A ; immediatemov edx, B ; direct memory
IA32 addressing modes
1. Immediate2. Direct memory3. Register
4. Register indirect (new)5. Indexed (new)6. Based-indexed (new)
Register indirect
• Consider the following:B dword 52
…mov eax, B ; eax now equals 52
• In the above example, the operand actually contains the address of B.
• That’s not very flexible.
Register indirect
• Say B is located at memory location (address) 400. We load the address of B into a register.
mov ebx, 400 ;load the address of Bmov eax, ebx ;eax is now 400mov eax, [ebx] ;eax now equals 52
• This is the register indirect addressing mode. The register does not contain the value but contains a reference to (pointer to/location of) the value in memory.
Register indirect
• But how do we get the address of something into a register to start with?
• We don’t know where the assembler and linker place A in memory!
• Just as we have instructions that load values from memory, we have instructions that load the address of values in memory.
lea eax, A ;store addr of A in eax;lea = load effective addr
mov eax, offset A ;same result
Sum up values in a table
tbl dword 1, 2, 7, 22, 59, 100
mov eax, offset tbl ;eax points to the first table entrymov ebx, [eax] ;ebx contains the first table entry;how can we make eax point to the next table entry?
Sum up values in a table
tbl dword 1, 2, 7, 22, 59, 100
mov eax, offset tbl ;eax points to the first table entrymov ebx, [eax] ;ebx contains the first table entryadd eax, 4 ;eax now points to next table entry
Sum up values in a table
tbl dword 1, 2, 7, 22, 59, 100
mov eax, offset tbl ;eax points to the first table entrymov ebx, [eax] ;ebx contains the first table entryadd eax, sizeof dword ;even better
Sum up values in a table
tbl dword 1, 2, 7, 22, 59, 100
mov eax, offset tbl ;eax points to the first table entrymov ebx, [eax] ;ebx contains the first table entryadd eax, 4 ;eax now points to next table entry;how can we sum the next entry?
Sum up values in a table
tbl dword 1, 2, 7, 22, 59, 100
mov eax, offset tbl ;eax points to the first table entrymov ebx, [eax] ;ebx contains the first table entryadd eax, 4 ;eax now points to next table entryadd ebx, [eax] ; sum the second entry…
Sum up values in a tabletbl dword 1, 2, 7, 22, 59, 100
mov eax, offset tbl ;eax points to the first table entrymov ebx, [eax] ;ebx contains the first table entryadd eax, 4 ;eax now points to next table entryadd ebx, [eax] ;sum the second entryadd eax, 4add ebx, [eax] ;sum the thirdadd eax, 4add ebx, [eax] ;sum the fourthadd eax, 4add ebx, [eax] ;sum the fifthadd eax, 4add ebx, [eax] ;sum the sixth
Note: If we know that we have N entries in the table, we can use a loop instead.
Indexed
Used to:
1. reference memory at a constant offset from a register
• when register points to object and data member is a know offset from start of object
2. reference memory using a register as an additional offset
• when register is used as an offset to an array element
Indexed
A dword 592h, 50h, 60h, 70h, 80h, 90h
mov eax, 4mov ebx, A[eax] ;what’s in
ebx?mov ecx, [A+eax] ;what’s in
ecx?
Indexed
A dword 592h, 50h, 60h, 70h, 80h, 90h
mov eax, 4mov ebx, A[eax] ;what’s in
ebx?mov ecx, [A+eax] ;what’s in
ecx?
Using indexed addressing to sum up values in a table
tbl dword 1, 2, 7, 22, 59, 100
mov eax, 0 ;eax is offset from start of tablemov ebx, tbl[eax] ;ebx contains the first table entryadd eax, 4 ;eax now is offset to next table entryadd ebx, tbl[eax] ;sum the second entryadd eax, 4add ebx, tbl[eax] ;sum the thirdadd eax, 4add ebx, tbl[eax] ;sum the fourthadd eax, 4add ebx, tbl[eax] ;sum the fifthadd eax, 4add ebx, tbl[eax] ;sum the sixth
Based-indexed
• Address is computed by adding two registers (base and index) plus an optional offset (displacement).
• One of the two registers (but not both) may also be optionally scaled.
• Offset = base + (index*scale) + displacement
Using based-indexed addressing to sum up values in a table (approach #1)tbl dword 1, 2, 7, 22, 59, 100
mov eax, 0 ;offset from start of tablemov ebx, tbl[eax*4] ;get first table entryinc eax ;subscript of next table entryadd ebx, tbl[eax*4] ;sum the second entryinc eaxadd ebx, tbl[eax*4] ;sum the thirdinc eaxadd ebx, tbl[eax*4] ;sum the fourthinc eaxadd ebx, tbl[eax*4] ;sum the fifthinc eaxadd ebx, tbl[eax*4] ;sum the sixth
Using based-indexed addressing to sum up values in a table (approach #2)tbl dword 1, 2, 7, 22, 59, 100
mov eax, offset tbl ;point to start of tablemov ebx, 0 ;offset from start of tablemov ecx, [eax+ebx*4] ;get first table entryinc ebx ;subscript of next table entryadd ecx, [eax+ebx*4] ;sum the second entryinc ebxadd ecx, [eax+ebx*4] ;sum the thirdinc ebxadd ecx, [eax+ebx*4] ;sum the fourthinc ebxadd ecx, [eax+ebx*4] ;sum the fifthinc ebxadd ecx, [eax+ebx*4] ;sum the sixth
Using based-indexed addressing to sum up values in a table (approach #3)tbl dword 1, 2, 7, 22, 59, 100
mov eax, offset tbl ;points to start of tablemov ebx, 0 ;offset from start of tablemov ecx, [eax+ebx] ;get first table entryadd ebx, 4 ;offset of next table entryadd ecx, [eax+ebx] ;sum the second entryadd ebx, 4add ecx, [eax+ebx] ;sum the thirdadd ebx, 4add ecx, [eax+ebx] ;sum the fourthadd ebx, 4add ecx, [eax+ebx] ;sum the fifthadd ebx, 4add ecx, [eax+ebx] ;sum the sixth
Methods of passing arguments to functions
• Methods:1. Use registers.
2. Use stack.3. Use one register which points to a parameter
block.
Stack temporarily keeps return address.
main PROC ;program execution begins heremov eax, offset afterCall ;addr of inst after call fcall dump ;show contents of regscall f
afterCall:mov eax, input(prompt) ;prompt the userexit ;end of program
main ENDP;----------------------------------------------------------------------f PROC
mov eax, [esp] ;gets return addresscall dumpret
f ENDP
main PROC ;program execution begins heremov eax, offset afterCall ;addr of inst after call fcall dump ;show contents of regscall f
afterCall:mov eax, input(prompt) ;prompt the userexit ;end of program
main ENDP;----------------------------------------------------------------------f PROC
mov eax, [esp] ;gets addr of return addresscall dumpret
f ENDP
Note: In f, esp points to return address which is location of afterCall.
main PROC ;program execution begins heremov eax, 7push eax ;push the contents of eax on the stackpush 4 ;push the value 4 on the stackcall fpop eax ;must clean up stack!pop eax ;must clean up stack!mov eax, input(prompt) ;prompt the userexit ;end of program
main ENDP;----------------------------------------------------------------------f PROC
mov eax, [esp+4] ;eax = 4mov ebx, [esp+8] ;ebx = 7call dumpret
f ENDP
Passing arguments to functions via the stack
main PROC ;program execution begins heremov eax, 7push eax ;push the contents of eax on the stackpush 4 ;push the value 4 on the stackcall fpop eax ;must clean up stack!pop eax ;must clean up stack!mov eax, input(prompt) ;prompt the userexit ;end of program
main ENDP;----------------------------------------------------------------------f PROC
mov eax, [esp+4] ;eax = 4mov ebx, [esp+8] ;ebx = 7call dumpret
f ENDP
Passing arguments to functions via the stack
Can you suggest another way to perform this clean up?
Passing arguments to functions via the stackmain PROC ;program execution begins here
mov eax, 7push eax ;push the contents of eax on the stackpush 4 ;push the value 4 on the stackcall fadd esp, 8 ;must clean up stack!
mov eax, input(prompt) ;prompt the userexit ;end of program
main ENDP;----------------------------------------------------------------------f PROC
mov eax, [esp+4] ;eax = 4mov ebx, [esp+8] ;ebx = 7call dumpret
f ENDP
Another way to perform this clean up.
Passing arguments to functions via the stackmain PROC ;program execution begins here
mov eax, 7push eax ;push the contents of eax on the stackpush 4 ;push the value 4 on the stackcall fadd esp, 8 ;must clean up stack!
mov eax, input(prompt) ;prompt the userexit ;end of program
main ENDP;----------------------------------------------------------------------f PROC
mov eax, [esp+4] ;eax = 4mov ebx, [esp+8] ;ebx = 7call dumpret
f ENDP
But this functions modifies eax and ebx.
How can we modify this function to NOT change any registers?
Passing arguments to functions via the stack
f PROCpush eax ;save reg usedpush ebx ;save reg usedmov eax, [esp+12] ;get argmov ebx, [esp+16] ;get another arg...pop ebx ;restore reg usedpop eax ;restore reg usedret
f ENDP
We modified this to NOT change any registers.
n! (n factorial)
• The number of ways n objects can be permuted (arranged).
• For example, consider 3 things, A, B, and C.3! = 6
1. ABC2. ACB3. CAB4. CBA5. BCA6. BAC
• The first few factorials for n = 0, 1, 2, 3, 4, 5 are 1, 1, 2, 6, 24, 120.
n! (n factorial)
• n! for some non negative integer n is defined as:
– n! = n * (n-1) * (n-2) * … * 2 * 1
– 0! is defined as 1.
– from http://mathworld.wolfram.com/Factorial.html
Java version (iterative)
public static int fact1 ( int n ) {int result = 1;
for (int ecx=n; ecx>0; ecx--) {result = result * ecx;
}return result;
}
fact1 proc ;input: eax contains n (value to calculate n!);output: eax contains the result (n!);all other registers except edx are preserved
push ecx ;save register usedmov ecx, eax ;init loop counter to nmov eax, 1 ;to accumulate result (also n! = 1 for n<=1)cmp ecx, 1 ;check for 1!jle fact1Done ;br if 1!
fact1Loop:mul ecx ;accumulate the result of n!jo fact1Error ;br if result is larger than 32 bitsdec ecx ;dec our loop counterjnz fact1Loop ;br if not finished
fact1Done:pop ecx ;restore register usedret ;return to caller
fact1Error: ;handle errorspushad ;save all registersprint SADD("fact1: overflow",CR,LF) ;output error messagepopad ;restore all registerspop ecx ;restore register usedret ;return to caller
fact1 endp
Iterativefactorial
Two things to note:
1.This is a common version of the for-loop.
2.How can we also preserve edx? (Where does edx change?)
n! (n factorial)
• n! for some non negative integer n can be rewritten as:– 0! = 1 for n = 0– 1! = 1 for n = 1– n! = n * (n-1)! for all other n > 1
Mathematical induction
• The idea of sequences in which later terms are deduced from earlier ones, which is implicit in the principle of mathematical induction, dates to antiquity.
• The truth of an infinite sequence of propositions Pi for i=1, ..., is established if1. P1 is true, and2. Pk implies Pk+1 for all k.
• This principle is sometimes also known as the method of induction.
– from http://mathworld.wolfram.com/RecursiveSequence.html and http://mathworld.wolfram.com/PrincipleofMathematicalInduction.html
Mathematical induction
• The idea of sequences in which later terms are deduced from earlier ones, which is implicit in the principle of mathematical induction, dates to antiquity.
• The truth of an infinite sequence of propositions Pi for i=1, ..., is established if1. P1 is true, and2. Pk implies Pk+1 for all k.
base case(s)
inductive case(s)
Back to n! (n factorial)
• n! for some non negative integer n can be rewritten as:– 0! = 1 for n = 0– 1! = 1 for n = 1– n! = n * (n-1)! for all other n > 1
base cases
inductive case
Let’s code n! (n factorial)
• n! for some non negative integer n can be rewritten as:– 0! = 1 for n = 0– 1! = 1 for n = 1– n! = n * (n-1)! for all other n > 1
public static int nFactorial ( int n ) {
}
base cases
inductive case
Let’s code n! (n factorial)
• n! for some non negative integer n can be rewritten as:– 0! = 1 for n = 0– 1! = 1 for n = 1– n! = n * (n-1)! for all other n > 1
public static int nFactorial ( int n ) {//base casesif (n==0) return 1;
}
base cases
inductive case
Let’s code n! (n factorial)
• n! for some non negative integer n can be rewritten as:– 0! = 1 for n = 0– 1! = 1 for n = 1– n! = n * (n-1)! for all other n > 1
public static int nFactorial ( int n ) {//base casesif (n==0) return 1;if (n==1) return 1;
}
base cases
inductive case
Let’s code n! (n factorial)
• n! for some non negative integer n can be rewritten as:– 0! = 1 for n = 0– 1! = 1 for n = 1– n! = n * (n-1)! for all other n > 1
public static int nFactorial ( int n ) {//base caseif (n<=1) return 1; //more generic/robust
}
base cases
inductive case
Let’s code n! (n factorial)
• n! for some non negative integer n can be rewritten as:– 0! = 1 for n = 0– 1! = 1 for n = 1– n! = n * (n-1)! for all other n > 1
public static int nFactorial ( int n ) {//base caseif (n<=1) return 1;
return n * nFactorial( n-1 );}
base cases
inductive case
Let’s code n! (n factorial)
• n! for some non negative integer n can be rewritten as:– 0! = 1 for n = 0– 1! = 1 for n = 1– n! = n * (n-1)! for all other n > 1
public static int nFactorial ( int n ) {//base caseif (n<=1) return 1;
return n * nFactorial( n-1 );}
This is an example of a recursive function (a function that calls itself)!
To use this function:
int result = nFactorial( 10 );
fact2 proc ;input: eax contains n (value to calculate n!);output: eax contains the result (n!);all other registers except edx are preserved
cmp eax, 1 ;base case when eax=1jle fact2One ;br if 1 (actually <=1)push ebx ;save reg usedmov ebx, eax ;save copy of n so we can calculate (n-1)!dec eax ;get ready to calculate (n-1)!call fact2 ;calculate (n-1)!mul ebx ;calculate n*[(n-1)!]jo fact2Error ;br if result is larger than 32 bitspop ebx ;restore reg usedret ;return to caller
fact2One:mov eax, 1 ;1! = 1ret ;return to caller
fact2Error: ;handle errorspushad ;save all registersprint SADD("fact2: overflow",CR,LF) ;output error messagepopad ;restore all registerspop ebx ;restore reg usedret ;return to caller
fact2 endp
Recursivefactorial
Summary of IA32 addressing modes
1. Immediate mov eax, 122. Direct memory mov eax, X3. Register mov ebx, eax4. Register indirect mov ebx, [eax]5. Indexed mov ebx, T[eax]
mov ebx, [T+eax]6. Based-indexed mov ecx, [eax + ebx*2 + T]
Methods of passing arguments to functions
• Methods:1. Use registers.2. Use stack.
3. Use one register which points to a parameter block.
.data
Point3D struct //structure defn.x dword 0y dword 0z dword 0Point3D ends
p1 Point3D { } //p1 w/ default valuesp2 Point3D {1, 2, 3} //p2 w/ specified values
.dataPoint3D struct //structure defn.x dword 0y dword 0z dword 0Point3D ends
p1 Point3D { } //p1 w/ default valuesp2 Point3D {1, 2, 3} //p2 w/ specified values
mov eax, p2.x ;get x valuemov ebx, p2.y ;get y valuemov ecx, p2.z ;get z valuecall dump
.dataPoint3D struct //structure defn.x dword 0y dword 0z dword 0Point3D ends
p1 Point3D { } //p1 w/ default valuesp2 Point3D {1, 2, 3} //p2 w/ specified values
lea eax, p2 ;get addr of p2mov ebx, offset p2 ;get addr of p2 via another methodcall dump
.dataPoint3D struct //structure defn.x dword 0y dword 0z dword 0Point3D ends
p1 Point3D { } //p1 w/ default valuesp2 Point3D {1, 2, 3} //p2 w/ specified values
lea eax, p2 ;get addr of p2mov ebx, offset p2 ;get addr of p2 via another methodcall dump
mov Point3D.x[eax], 5mov Point3D.z[eax], 10mov eax, p2.x ;get xmov ebx, p2.y ;get ymov ecx, p2.z ;get zcall dump
eax contains the base address of structured data that can be referenced by called functions! (Point3D.x is simply the offset to x from the start of the struct.)
top related