Download presentation
Presentation is loading. Please wait.
Published byShanon Watkins Modified over 9 years ago
1
Machine Programming – Procedures and IA32 Stack CENG334: Introduction to Operating Systems Instructor: Erol Sahin Acknowledgement: Most of the slides are adapted from the ones prepared by R.E. Bryant, D.R. O’Hallaron of Carnegie-Mellon Univ.
2
Integer Registers (IA32) %eax %ecx %edx %ebx %esi %edi %esp %ebp %ax %cx %dx %bx %si %di %sp %bp %ah %ch %dh %bh %al %cl %dl %bl 16-bit virtual registers (backwards compatibility) general purpose accumulate counter data base source index destination index stack pointer base pointer Origin (mostly obsolete)
3
Moving Data: IA32 Moving Data movx Source, Dest x in { b, w, l } movl Source, Dest: Move 4-byte “long word” movw Source, Dest: Move 2-byte “word” movb Source, Dest: Move 1-byte “byte” Lots of these in typical code %eax %ecx %edx %ebx %esi %edi %esp %ebp
4
Moving Data: IA32 Moving Data movl Source, Dest: Operand Types Immediate: Constant integer data Example: $0x400, $-533 Like C constant, but prefixed with ‘$’ Encoded with 1, 2, or 4 bytes Register: One of 8 integer registers Example: %eax, %edx But %esp and %ebp reserved for special use Others have special uses for particular instructions Memory: 4 consecutive bytes of memory at address given by register Simplest example: (%eax) Various other “address modes” %eax %ecx %edx %ebx %esi %edi %esp %ebp
5
movl Operand Combinations Cannot do memory-memory transfer with a single instruction movl Imm Reg Mem Reg Mem Reg Mem Reg SourceDestC Analog movl $0x4,%eaxtemp = 0x4; movl $-147,(%eax)*p = -147; movl %eax,%edxtemp2 = temp1; movl %eax,(%edx)*p = temp; movl (%eax),%edxtemp = *p; Src,Dest
6
Simple Memory Addressing Modes Normal(R)Mem[Reg[R]] Register R specifies memory address movl (%ecx),%eax DisplacementD(R)Mem[Reg[R]+D] Register R specifies start of memory region Constant displacement D specifies offset movl 8(%ebp),%edx
7
Using Simple Addressing Modes void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } swap: pushl %ebp movl %esp,%ebp pushl %ebx movl 12(%ebp),%ecx movl 8(%ebp),%edx movl (%ecx),%eax movl (%edx),%ebx movl %eax,(%edx) movl %ebx,(%ecx) movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret Body Set Up Finish
8
Using Simple Addressing Modes void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } swap: pushl %ebp movl %esp,%ebp pushl %ebx movl 12(%ebp),%ecx movl 8(%ebp),%edx movl (%ecx),%eax movl (%edx),%ebx movl %eax,(%edx) movl %ebx,(%ecx) movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret Body Set Up Finish
9
Understanding Swap void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } movl 12(%ebp),%ecx# ecx = yp movl 8(%ebp),%edx# edx = xp movl (%ecx),%eax# eax = *yp (t1) movl (%edx),%ebx# ebx = *xp (t0) movl %eax,(%edx)# *xp = eax movl %ebx,(%ecx)# *yp = ebx Stack (in memory) RegisterValue %ecxyp %edxxp %eaxt1 %ebxt0 yp xp Rtn adr Old % ebp %ebp 0 4 8 12 Offset Old % ebx -4
10
Understanding Swap movl 12(%ebp),%ecx# ecx = yp movl 8(%ebp),%edx# edx = xp movl (%ecx),%eax# eax = *yp (t1) movl (%edx),%ebx# ebx = *xp (t0) movl %eax,(%edx)# *xp = eax movl %ebx,(%ecx)# *yp = ebx 0x120 0x124 Rtn adr %ebp 0 4 8 12 Offset -4 123 456 Address 0x124 0x120 0x11c 0x118 0x114 0x110 0x10c 0x108 0x104 0x100 yp xp %eax %edx %ecx %ebx %esi %edi %esp %ebp0x104
11
movl 12(%ebp),%ecx# ecx = yp movl 8(%ebp),%edx# edx = xp movl (%ecx),%eax# eax = *yp (t1) movl (%edx),%ebx# ebx = *xp (t0) movl %eax,(%edx)# *xp = eax movl %ebx,(%ecx)# *yp = ebx Understanding Swap 0x120 0x124 Rtn adr %ebp 0 4 8 12 Offset -4 123 456 Address 0x124 0x120 0x11c 0x118 0x114 0x110 0x10c 0x108 0x104 0x100 yp xp %eax %edx %ecx %ebx %esi %edi %esp %ebp0x104 0x120
12
Understanding Swap 0x120 0x124 Rtn adr %ebp 0 4 8 12 Offset -4 123 456 Address 0x124 0x120 0x11c 0x118 0x114 0x110 0x10c 0x108 0x104 0x100 yp xp %eax %edx %ecx %ebx %esi %edi %esp %ebp 0x120 0x104 movl 12(%ebp),%ecx# ecx = yp movl 8(%ebp),%edx# edx = xp movl (%ecx),%eax# eax = *yp (t1) movl (%edx),%ebx# ebx = *xp (t0) movl %eax,(%edx)# *xp = eax movl %ebx,(%ecx)# *yp = ebx 0x124
13
Understanding Swap 0x120 0x124 Rtn adr %ebp 0 4 8 12 Offset -4 123 456 Address 0x124 0x120 0x11c 0x118 0x114 0x110 0x10c 0x108 0x104 0x100 yp xp %eax %edx %ecx %ebx %esi %edi %esp %ebp 0x124 0x120 0x104 movl 12(%ebp),%ecx# ecx = yp movl 8(%ebp),%edx# edx = xp movl (%ecx),%eax# eax = *yp (t1) movl (%edx),%ebx# ebx = *xp (t0) movl %eax,(%edx)# *xp = eax movl %ebx,(%ecx)# *yp = ebx 456
14
Understanding Swap 0x120 0x124 Rtn adr %ebp 0 4 8 12 Offset -4 123 456 Address 0x124 0x120 0x11c 0x118 0x114 0x110 0x10c 0x108 0x104 0x100 yp xp %eax %edx %ecx %ebx %esi %edi %esp %ebp 456 0x124 0x120 0x104 movl 12(%ebp),%ecx# ecx = yp movl 8(%ebp),%edx# edx = xp movl (%ecx),%eax# eax = *yp (t1) movl (%edx),%ebx# ebx = *xp (t0) movl %eax,(%edx)# *xp = eax movl %ebx,(%ecx)# *yp = ebx 123
15
456 Understanding Swap 0x120 0x124 Rtn adr %ebp 0 4 8 12 Offset -4 Address 0x124 0x120 0x11c 0x118 0x114 0x110 0x10c 0x108 0x104 0x100 yp xp %eax %edx %ecx %ebx %esi %edi %esp %ebp 456 0x124 0x120 123 0x104 movl 12(%ebp),%ecx# ecx = yp movl 8(%ebp),%edx# edx = xp movl (%ecx),%eax# eax = *yp (t1) movl (%edx),%ebx# ebx = *xp (t0) movl %eax,(%edx)# *xp = eax movl %ebx,(%ecx)# *yp = ebx 456 123
16
Understanding Swap 0x120 0x124 Rtn adr %ebp 0 4 8 12 Offset -4 456 Address 0x124 0x120 0x11c 0x118 0x114 0x110 0x10c 0x108 0x104 0x100 yp xp %eax %edx %ecx %ebx %esi %edi %esp %ebp 456 0x124 0x120 0x104 movl 12(%ebp),%ecx# ecx = yp movl 8(%ebp),%edx# edx = xp movl (%ecx),%eax# eax = *yp (t1) movl (%edx),%ebx# ebx = *xp (t0) movl %eax,(%edx)# *xp = eax movl %ebx,(%ecx)# *yp = ebx 123
17
Complete Memory Addressing Modes Most General Form D(Rb,Ri,S)Mem[Reg[Rb]+S*Reg[Ri]+ D] D: Constant “displacement” 1, 2, or 4 bytes Rb: Base register: Any of 8 integer registers Ri:Index register: Any, except for %esp Unlikely you’d use %ebp, either S: Scale: 1, 2, 4, or 8 (why these numbers?) Special Cases (Rb,Ri)Mem[Reg[Rb]+Reg[Ri]] D(Rb,Ri)Mem[Reg[Rb]+Reg[Ri]+D] (Rb,Ri,S)Mem[Reg[Rb]+S*Reg[Ri]]
18
IA32 Stack Region of memory managed with stack discipline Grows toward lower addresses Register %esp contains lowest stack address = address of “top” element Stack Pointer: %esp Stack Grows Down Increasing Addresses Stack “Top” Stack “Bottom”
19
IA32 Stack: Push pushl Src Fetch operand at Src Decrement %esp by 4 Write operand at address given by %esp Stack Grows Down Increasing Addresses Stack “Top” Stack “Bottom” Stack Pointer: %esp -4
20
IA32 Stack: Pop Stack Pointer: %esp Stack Grows Down Increasing Addresses Stack “Top” Stack “Bottom” popl Dest Read operand at address %esp Increment %esp by 4 Write operand to Dest +4
21
Procedure Control Flow Use stack to support procedure call and return Procedure call: call label Push return address on stack Jump to label Return address: Address of instruction beyond call Example from disassembly 804854e:e8 3d 06 00 00 call 8048b90 8048553:50 pushl %eax Return address = 0x8048553 Procedure return: ret Pop address from stack Jump to address
22
%esp %eip %esp %eip 0x804854e 0x108 0x10c 0x110 0x104 0x804854e 0x8048553 123 Procedure Call Example 0x108 0x10c 0x110 123 0x108 call 8048b90 804854e:e8 3d 06 00 00 call 8048b90 8048553:50 pushl %eax 0x8048b90 0x104 %eip: program counter
23
%esp %eip 0x104 %esp %eip 0x8048591 0x104 0x108 0x10c 0x110 0x8048553 123 Procedure Return Example 0x108 0x10c 0x110 123 ret 8048591:c3 ret 0x108 0x8048553 %eip: program counter
24
Stack-Based Languages Languages that support recursion e.g., C, Pascal, Java Code must be “Reentrant” Multiple simultaneous instantiations of single procedure Need some place to store state of each instantiation Arguments Local variables Return pointer Stack discipline State for given procedure needed for limited time From when called to when return Callee returns before caller does Stack allocated in Frames state for single procedure instantiation
25
Call Chain Example yoo(…) { who(); } who(…) { amI(); amI(); } amI(…) { amI(); } yoo who amI Example Call Chain amI Procedure amI is recursive
26
Frame for proc Frame Pointer: %ebp Stack Frames Contents Local variables Return information Temporary space Management Space allocated when enter procedure “Set-up” code Deallocated when return “Finish” code Stack Pointer: %esp Previous Frame Stack “Top”
27
Example yoo(…) { who(); } yoo who amI yoo %ebp %esp Stack
28
who(…) { amI(); amI(); } Example yoo who amI yoo %ebp %esp Stack who
29
amI(…) { amI(); } Example yoo who amI yoo %ebp %esp Stack who amI
30
amI(…) { amI(); } Example yoo who amI yoo %ebp %esp Stack who amI
31
amI(…) { amI(); } Example yoo who amI yoo %ebp %esp Stack who amI
32
amI(…) { amI(); } Example yoo who amI yoo %ebp %esp Stack who amI
33
amI(…) { amI(); } Example yoo who amI yoo %ebp %esp Stack who amI
34
who(…) { amI(); amI(); } Example yoo who amI yoo %ebp %esp Stack who
35
amI(…) { } Example yoo who amI yoo %ebp %esp Stack who amI
36
who(…) { amI(); amI(); } Example yoo who amI yoo %ebp %esp Stack who
37
Example yoo(…) { who(); } yoo who amI yoo %ebp %esp Stack
38
IA32/Linux Stack Frame Current Stack Frame (“Top” to Bottom) “Argument build:” Parameters for function about to call Local variables If can’t keep in registers Saved register context Old frame pointer Caller Stack Frame Return address Pushed by call instruction Arguments for this call Return Addr Saved Registers + Local Variables Argument Build Old %ebp Arguments Caller Frame Frame pointer %ebp Stack pointer %esp
39
Revisiting swap void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } int zip1 = 15213; int zip2 = 91125; void call_swap() { swap(&zip1, &zip2); } call_swap: pushl $zip2# Global Var pushl $zip1# Global Var call swap &zip2 &zip1 Rtn adr %esp Resulting Stack Calling swap from call_swap
40
Revisiting swap void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } swap: pushl %ebp movl %esp,%ebp pushl %ebx movl 12(%ebp),%ecx movl 8(%ebp),%edx movl (%ecx),%eax movl (%edx),%ebx movl %eax,(%edx) movl %ebx,(%ecx) movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret Body Set Up Finish
41
swap Setup #1 swap: pushl %ebp movl %esp,%ebp pushl %ebx Resulting Stack &zip2 &zip1 Rtn adr %esp Entering Stack %ebp yp xp Rtn adr Old %ebp %ebp %esp
42
swap Setup #1 swap: pushl %ebp movl %esp,%ebp pushl %ebx &zip2 &zip1 Rtn adr %esp Entering Stack %ebp yp xp Rtn adr Old %ebp %ebp %esp
43
swap Setup #1 swap: pushl %ebp movl %esp,%ebp pushl %ebx &zip2 &zip1 Rtn adr %esp Entering Stack %ebp yp xp Rtn adr Old %ebp %ebp %esp Resulting Stack
44
swap Setup #1 swap: pushl %ebp movl %esp,%ebp pushl %ebx &zip2 &zip1 Rtn adr %esp Entering Stack %ebp yp xp Rtn adr Old %ebp %ebp %esp
45
12 8 4 swap Setup #1 &zip2 &zip1 Rtn adr %esp Entering Stack %ebp yp xp Rtn adr Old %ebp %ebp %esp Resulting Stack Old %ebx movl 12(%ebp),%ecx # get yp movl 8(%ebp),%edx # get xp... Offset relative to %ebp
46
swap Finish #1 yp xp Rtn adr Old %ebp %ebp %esp swap’s Stack Old %ebx movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret yp xp Rtn adr Old %ebp %ebp %esp Resulting Stack Old %ebx Observation: Saved and restored register %ebx
47
swap Finish #2 yp xp Rtn adr Old %ebp %ebp %esp swap’s Stack Old %ebx movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret yp xp Rtn adr Old %ebp %ebp %esp Old %ebx
48
swap Finish #2 yp xp Rtn adr Old %ebp %ebp %esp swap’s Stack Old %ebx movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret yp xp Rtn adr Old %ebp %ebp %esp Resulting Stack
49
swap Finish #2 yp xp Rtn adr Old %ebp %ebp %esp swap’s Stack Old %ebx movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret yp xp Rtn adr Old %ebp %ebp %esp
50
swap Finish #3 yp xp Rtn adr Old %ebp %ebp %esp swap’s Stack Old %ebx movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret Resulting Stack yp xp Rtn adr %ebp %esp
51
swap Finish #4 yp xp Rtn adr Old %ebp %ebp %esp swap’s Stack Old %ebx movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret yp xp Rtn adr %ebp %esp
52
swap Finish #4 yp xp Rtn adr Old %ebp %ebp %esp swap’s Stack Old %ebx movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret yp xp %ebp %esp Resulting Stack Observation Saved & restored register %ebx Didn’t do so for %eax, %ecx, or %edx
53
Disassembled swap 080483a4 : 80483a4: 55 push %ebp 80483a5: 89 e5 mov %esp,%ebp 80483a7: 53 push %ebx 80483a8: 8b 55 08 mov 0x8(%ebp),%edx 80483ab: 8b 4d 0c mov 0xc(%ebp),%ecx 80483ae: 8b 1a mov (%edx),%ebx 80483b0: 8b 01 mov (%ecx),%eax 80483b2: 89 02 mov %eax,(%edx) 80483b4: 89 19 mov %ebx,(%ecx) 80483b6: 5b pop %ebx 80483b7: c9 leave 80483b8: c3 ret 8048409: e8 96 ff ff ff call 80483a4 804840e: 8b 45 f8 mov 0xfffffff8(%ebp),%eax Calling Code
54
Register Saving Conventions When procedure yoo calls who : yoo is the caller who is the callee Can Register be used for temporary storage? Contents of register %edx overwritten by who yoo: movl $15213, %edx call who addl %edx, %eax ret who: movl 8(%ebp), %edx addl $91125, %edx ret
55
Register Saving Conventions When procedure yoo calls who : yoo is the caller who is the callee Can register be used for temporary storage? Conventions “Caller Save” Caller saves temporary in its frame before calling “Callee Save” Callee saves temporary in its frame before using
56
IA32/Linux Register Usage %eax, %edx, %ecx Caller saves prior to call if values are used later %eax also used to return integer value %ebx, %esi, %edi Callee saves if wants to use them %esp, %ebp special %eax %edx %ecx %ebx %esi %edi %esp %ebp Caller-Save Temporaries Callee-Save Temporaries Special
57
Linux Memory Layout Stack Runtime stack (8MB limit) Heap Dynamically allocated storage When call malloc, calloc, new DLLs Dynamically Linked Libraries Library routines (e.g., printf, malloc ) Linked into object code when first executed Data Statically allocated data E.g., arrays & strings declared in code Text Executable machine instructions Read-only Upper 2 hex digits of address Red Hat v. 6.2 ~1920M B memory limit FF BF 7F 3F C0 80 40 00 Stack DLLs Text Data Heap 08
58
Linux Memory Allocation Linked BF 7F 3F 80 40 00 Stack DLLs Text Data 08 Some Heap BF 7F 3F 80 40 00 Stack DLLs Text Data Heap 08 More Heap BF 7F 3F 80 40 00 Stack DLLs Text Data Heap 08 Initially BF 7F 3F 80 40 00 Stack Text Data 08
59
Text & Stack Example (gdb) break main (gdb) run Breakpoint 1, 0x804856f in main () (gdb) print $esp $3 = (void *) 0xbffffc78 Main Address 0x804856f should be read 0x0804856f Stack Address 0xbffffc78 Initially BF 7F 3F 80 40 00 Stack Text Data 08
60
Dynamic Linking Example (gdb) print malloc $1 = { } 0x8048454 (gdb) run Program exited normally. (gdb) print malloc $2 = {void *(unsigned int)} 0x40006240 Initially Code in text segment that invokes dynamic linker Address 0x8048454 should be read 0x08048454 Final Code in DLL region Linked BF 7F 3F 80 40 00 Stack DLLs Text Data 08
61
Memory Allocation Example char big_array[1<<24]; /* 16 MB */ char huge_array[1<<28]; /* 256 MB */ int beyond; char *p1, *p2, *p3, *p4; int useless() { return 0; } int main() { p1 = malloc(1 <<28); /* 256 MB */ p2 = malloc(1 << 8); /* 256 B */ p3 = malloc(1 <<28); /* 256 MB */ p4 = malloc(1 << 8); /* 256 B */ /* Some print statements... */ }
62
Example Addresses $esp0xbffffc78 p3 0x500b5008 p1 0x400b4008 Final malloc0x40006240 p40x1904a640 p20x1904a538 beyond 0x1904a524 big_array 0x1804a520 huge_array 0x0804a510 main()0x0804856f useless() 0x08048560 Initial malloc0x08048454 BF 7F 3F 80 40 00 Stack DLLs Text Data Heap 08
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.