Organisasi Sistem Komputer
Bagian 7
Bagian 7
Prosedur
Pembahasan
Stack pada IA32
Stac pada
3
Konvensi penyimpanan dalam register
Membuat pointer pada variabel lokal
Membuat pointer pada variabel lokal
Stack pada IA32
Bagian dari memori yang
l l
t k
Stack “Paling Bawah”
mengelola stack
Stack bertambah pada
alamat yang lebih rendah
Register %esp
Alamat Bertambah
B
Register %esp
menunjukkan alamat stack
yang paling bawah
Alamat dari elemen
Besar paling atas Stack Pointer Stack Bertambah Ke Bawah %esp
Push Stack
Penyimpanan pada stack
Stack “Paling Bawah”
y p
p
pushl Src
Src adalah fetch operand
%esp
berkurang 4
Alamat Bertambah
B
%esp
berkurang 4
Menyimpan operand pada
alamat yang ditentukan
oleh register %esp
Besar
oleh register %esp
Stack Stack Bertambah Ke Bawah Pointer %esp -4
Pop Stack
Membaca dari stack
Stack “Paling Bawah”
popl
Dest
Membaca operand dari
alamat yang
Alamat Bertambah
B
alamat yang
ditentukan oleh %esp
%esp
bertambah 4
Disimpan ke
Dest
Besar
Disimpan ke Dest
Stack Bertambah Ke Bawah Stack Pointer %esp +4 +4Contoh Operasi Stack
pushl %eax popl %edx
0x110 0x110 0x104 0x108 0x10c 0x104 213 123 123 0x108 0x10c 123 213 %eax %eax 0x104 0x104 213 213 213 213 213 %esp %eax %edx %esp %eax %edx 555 0x108 555 213 555 213 0x108 0x104 213 0x104 213 0x108
Aliran Kontrol Prosedur
Prosedur call dan return menggunakan stack
gg
Prosedur call :
Call label
Push return address ke stack; Jump ke label
Nil i t
dd
Nilai return address
Alamat ketika instruksi call dipanggil
Contoh dari disassemblyy
804854e : e8 3d 06 00 00 call 8048b90 <main>
8048553 : 50 pushl eax
Return address = 0x8048553
etu
add ess
0 80 8553
Prosedur return :
Contoh Prosedur Call
804854e: e8 3d 06 00 00 call 8048b90 <main> 8048553: 50 pushl %eax call 8048b90 0x10c 0x110 0x108 0x104 0x8048553 123 123 %esp %eip 0x804854e 0x108 0x804854e 0x108 0x8048b90 0x104 p
Contoh Prosedur Return
8048591: c3 ret ret 0x10c 0x110 0x10c 0x110 0x104 0x108 0x8048553 123 0x108 123 0x8048553 %esp 0x104 %esp 0x1040x108Contoh Rangkaian Call
Struktur Kode
ji(…)Urutan Call
j ( ) { • • () sam(…) ji sam sam(); • • } sam(…) { • • • soe(); sam soe soe • • • soe(); • • • } soe(…) { • soe } • soe(); • soe
Prosedur soe adalah
prosedur rekursi
•}
Stack Frame
Setiap stack frame
p
jiberisi:
Variabel lokal
Informasi return
j sam soe
Informasi return
Temporary space
soe proc Frame Pointer %ebp Stack Pointer proc StackOperasi Stack
• • ji • • Frame Pointer %ebpUrutan Call
ji(…) Stack Pointer %esp j ji { • • sam(); sam(); • • }Operasi Stack
• • ji • • FUrutan Call
sam(…) j sam Frame Pointer %ebp ji { • • • soe(); • • • Stack Pointer %esp sam • • • soe(); • • • }Operasi Stack
• • ji • •Urutan Call
soe(…) j sam Frame ji soe(…) { • • () St k soe Frame Pointer %ebp sam soe soe(); • • } Stack Pointer %espOperasi Stack
• • ji • •Urutan Call
soe(…) j sam ji soe(…) { • • () soe Frame sam soe soe(); • • } Stack Frame Pointer %ebp soe soe Stack Pointer %espOperasi Stack
• • ji • •Urutan Call
soe(…) j sam ji soe(…) { • • () soe sam soe soe(); • • } Frame soe soe Stack Pointer %ebp soe soe Stack Pointer %espOperasi Stack
• • ji • •Urutan Call
soe(…) j sam ji soe(…) { • • () soe Frame sam soe soe(); • • } Stack Frame Pointer %ebp soe soe Stack Pointer %esp soeOperasi Stack
• • ji • •Urutan Call
soe(…) j sam Frame ji soe(…) { • • () St k soe Frame Pointer %ebp sam soe soe(); • • } Stack Pointer %esp soe soeOperasi Stack
• • ji • • FUrutan Call
sam(…) j sam Frame Pointer %ebp ji { • • • soe(); • • • Stack Pointer %esp sam • • • soe(); • • • } soe soe soeOperasi Stack
• • ji • •Urutan Call
soe(…) j sam Frame ji soe(…) { • • St k soe Frame Pointer %ebp sam • • } soe soe Stack Pointer %esp soe soeOperasi Stack
• • ji • • FUrutan Call
sam(…) j sam Frame Pointer %ebp ji { • • • soe(); • • • Stack Pointer %esp sam • • • soe(); • • • } soe soe soe soeOperasi Stack
• • ji(…) ji • • Frame Pointer %ebpUrutan Call
ji(…) { • • () Stack Pointer %esp j ji sam(); • • } sam soe soe } soe soeStack Frame IA32/Linux
Stack Frame terdiri dari:
Parameter fungsi yang hendak
dipanggil
“Argument build”
Variabel lokal
ArgumentsCaller Frame
Variabel lokal
Yang tidak dapat disimpan
dalam register
Saved register
Frame Pointer (%ebp) Return Addr Old %ebp ArgumentsSaved register
Frame pointer sebelumnya
Pemanggil Stack Frame
Return address
Saved Registers + L l
Return address
Di-push oleh instruksi call
Argument pemanggil
Local Variables
Bahasa Berbasis Stack
Bahasa yang mendukung Rekursi
a asa ya g e du u g e u s
Contoh : C, Pascal, Java
Kode harus “Reentrant”
Perlu tempat untuk menyimpan kondisi setiap:
Arguments
Local variables
Local variables
Return pointer
Fungsi Swap
int zip1 = 15213; int zip2 = 91125;
call swap:
Memanggil swap dari call_swap
void call_swap() {
swap(&zip1 &zip2);
call_swap: • • •
pushl $zip2 # Global Var pushl $zip1 # Global Var swap(&zip1, &zip2);
} call swap
• • •
void swap(int *xp, int *yp) { int t0 = *xp;
Stack
diperoleh
• • • int t0 xp; int t1 = *yp; *xp = t1; &zip2 &zip1Fungsi Swap
swap:
pushl %ebp
Set
void swap(int *xp, int *yp) { movl %esp,%ebp pushl %ebx movl 12(%ebp),%ecx Set Up int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; movl 12(%ebp),%ecx movl 8(%ebp),%edx movl (%ecx),%eax movl (%edx),%ebx l % (% d ) Body yp = t0; } movl %eax,(%edx) movl %ebx,(%ecx) movl -4(%ebp),%ebx( p), movl %ebp,%esp popl %ebp ret Finish
Swap
Setup - 1
Stack diperoleh
Masuk Stack
%ebp % b • • • %ebp %ebp • • • &zip2 &zip1 yp xp p Rtn adr %esp p Rtn adrOld %ebp %esp
Swap
Setup - 2
%ebpStack diperoleh
Masuk Stack
• • • • • • %ebp yp xp &zip2 &zip1 p Rtn adrOld %ebp %ebp p
Rtn adr %esp
swap:
pushl %ebp
movl %esp %ebp
%esp
movl %esp,%ebp pushl %ebx
Swap
Setup - 3
%ebpStack diperoleh
Masuk Stack
• • • • • • %ebp yp xp &zip2 &zip1 p Rtn adrOld %ebp %ebp p
Rtn adr %esp
O swap:
Pengaruh Swap Setup
Stack
diperoleh
%ebp Offsetp
• • • • • • %ebp yp xp 8 12 (relatif thd %ebp) &zip2 &zip1 p Rtn adrOld %ebp %ebp 0
4 p
Rtn adr %esp
O
Old %ebx %esp
movl 12(%ebp),%ecx # get yp
movl 8(%ebp),%edx # get xp( p), # g p Body . . .
Swap
Finish - 1
Stack
• • Offsetswap
• • • Offset • • • yp xp Rtn adr 4 8 12 yp xp Rtn adr 4 8 12 Rtn adrOld %ebp %ebp 0
4
Old %ebx %esp -4
Rtn adr
Old %ebp %ebp 0
4
Old %ebx %esp -4
movl -4(%ebp),%ebx movl %ebp,%esp
Swap
Finish - 2
Stack
swap
• •Stack
swap
Offsetswap
• • • Offset • • •swap
yp xp Rtn adr 4 8 12 yp xp Rtn adr 4 8 12 Rtn adrOld %ebp %ebp 0
4
Old %ebx %esp -4
Rtn adr
Old %ebp %ebp 0 4 %esp movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp popl %ebp ret
Swap
Finish - 3
Stack
swap
• %ebp •Stack
swap
Offsetswap
• • • Offset • • •swap
yp xp Rtn adr 4 8 12 yp xp Rtn adr 4 8 12 Rtn adrOld %ebp %ebp 0 4 %esp Rtn adr 0 4 %esp movl -4(%ebp),%ebx movl %ebp,%esp
Swap
Finish - 4
%ebpStack
• %ebp • Offsetswap
• • • • • • yp xp Rtn adr 4 8 12 &zip2 &zip1 %esp Rtn adr 4 %espPenjelasan :
movl -4(%ebp),%ebx movl %ebp,%esp popl %ebpPenjelasan :
Menyimpan dan me-restore
register %ebx
Tid k dil k k
d
i t
popl %ebpret
Tidak dilakukan pada register
Aturan Penyimpanan Register
Ketika prosedur yoo memanggil who:
yoo
adalah pemanggil (caller), who yang dipanggil (callee)
Dapatkan register digunakan sebagai penyimpan
sementara ?
se e ta a
yoo: • • • movl $15213 %edx who: • • • movl $15213, %edx call whoaddl %edx, %eax • • •
movl 8(%ebp), %edx addl $91125, %edx • • •
Isi register %edx ditimpa oleh who
Aturan Penyimpanan Register
Ketika prosedur yoo memanggil who:
yoo
adalah pemanggil (caller), who yang dipanggil (callee)
Dapatkan register digunakan sebagai penyimpan
sementara ?
sementara ?
Konvensi :
“Caller Save”
Caller menyimpan nilai sementara dalam frame sebelum melakukan pemanggilan
“Callee Save”
Penggunaan Register IA32/Linux
Register integer
%eax
Penggunaan khusus
%ebp, %esp
callee-save :
%edx %ecx Register Caller-Save%ebx, %esi, %edi
Nilai sebelumnya
disimpan dalam stack sebelum register %ebx %esi Register Callee-Save sebelum register digunakan
caller-save :
%eax, %edx, %ecx
%edi
%esp Register
kh
Dapat dilakukan apa
saja.
Register %eax juga
%ebp khusus
Recursive Factorial
.globl rfact.type rfact,@function int rfact(int x) { , rfact: pushl %ebp movl %esp,%ebp pushl %ebx { int rval; if (x <= 1) return 1; pushl %ebx movl 8(%ebp),%ebx cmpl $1,%ebx jle .L78 rval = rfact(x-1); return rval * x; } leal -1(%ebx),%eax pushl %eax call rfactimull %ebx %eax imull %ebx,%eax jmp .L79
.align 4 .L78:
Registers
%eax
digunakan tanpa
disimpan lebih dah l
movl $1,%eax .L79:movl -4(%ebp),%ebx movl %ebp,%esp
disimpan lebih dahulu
%ebx
digunakan, tetapi
disimpan dahulu diawal dan
dikembalikan lagi di akhir
movl %ebp,%esp popl %ebpret
rfact -
Stack Setup
%ebp pre %ebpMasuk stack
x Rtn adr Caller %esp pre %ebx rfact: pushl %ebp movl %esp,%ebp pushl %ebx rfact: pushl %ebp movl %esp,%ebp pushl %ebx pre %ebp rfact: pushl %ebp movl %esp,%ebp pushl %ebx pushl %ebx pushl %ebx x 8 Caller pre %ebp pre %ebx pushl %ebx Rtn adr 4 %ebp 0 Old %ebpRfact
Body
mo l 8(%ebp) %eb # eb
movl 8(%ebp),%ebx # ebx = x
cmpl $1,%ebx # Compare x : 1 jle .L78 # If <= goto Term leal -1(%ebx),%eax # eax = x-1
pushl %eax # Push x-1 call rfact # rfact(x-1) imull %ebx,%eax # rval * x jmp L79 # Goto done Recursion
jmp .L79 # Goto done
.L78: # Term:
movl $1,%eax # return val = 1
.L79: # Done:
Registers
%ebx
menyimpan nilai x
%
int rfact(int x) { int rval;%eax
Nilai sementara x-1 Return value dari rfact(x-1)
R l f i i i
; if (x <= 1)
return 1;
rval = rfact(x-1) ;
return rval * x; Return value fungsi ini return rval * x;
rfact -
Rekursi
pushl %eax leal -1(%ebx),%eax x Rtn adr pushl %eax x Rtn adrOld %ebp %ebp call rfact
Rtn adr
Old %ebp %ebp Old %ebx
Old %ebx %esp x
Rtn adr
Old %ebp %ebp %esp
x-1
%eax x-1
Old %ebp %ebp Old %ebx x-1 x-1 %eax x %ebx x
rfact -
Hasil
imull %ebx,%eax Kembali dari call
x Rtn adr
Old % b % b x
Rtn adr
Old % b % b Old %ebp %ebp
Old %ebx
%esp x-1
Old %ebp %ebp Old %ebx %esp x-1 (x-1)! p x! %eax p (x-1)! %eax (x-1)! %eax (x 1)!x! x %ebx (x 1)! %eax x %ebx (x 1)! Diasumsikan rfact(x-1) mengembalikan (x-1)! dalam register %eax
rfact -
Akhir
mo l 4(%ebp) %eb mo l 4(%ebp) %eb mo l 4(%ebp) %eb movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret pre %ebp pre %ebx movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret x Rtn adr 4 8 pre %ebx pre %ebppre %ebx pre %ebp %ebp Old %ebp %ebp
0 Old %ebx %esp -4 x-1 -8 x Rtn adr
Old %ebp %ebp 0 4 8 x Rtn adr %esp pre %ebx p x! %eax % b Old %ebp p %esp x! %eax Old % b Rtn adr %esp x %ebx %eax x! Old %ebx %ebx Old %ebx x! %eax
Kode Pointer
Top Le el Call
Prosedur Rekursif
void s_helper
(int x, int *accum) { int sfact(int x) { int val = 1;
Top-Level Call
Prosedur Rekursif
{ if (x <= 1) return; else { i t * * int val = 1; s_helper(x, &val); return val; } int z = *accum * x; *accum = z; s_helper (x-1,accum); } } }M l
tk
i t
t k
d t l k i
Membuat dan Inisialisasi Pointer
sfact:
bagian inisialisasi sfact
sfact: sfact: sfact: _sfact:
pushl %ebp # Save %ebp movl %esp,%ebp # Set %ebp
subl $16,%esp # Add 16 bytes
8( ) #
x Rtn adr
Old %ebp %ebp 0
4 8 _sfact:
pushl %ebp # Save %ebp movl %esp,%ebp # Set %ebp
subl $16,%esp # Add 16 bytes
8( ) #
_sfact:
pushl %ebp # Save %ebp movl %esp,%ebp # Set %ebp
subl $16,%esp # Add 16 bytes
8( ) #
_sfact:
pushl %ebp # Save %ebp movl %esp,%ebp # Set %ebp
subl $16,%esp # Add 16 bytes
8( ) #
Temp. Space movl 8(%ebp),%edx # edx = x
movl $1,-4(%ebp) # val = 1
Menggunakan stack untuk
p -4 val = 1
U d
12 -8 movl 8(%ebp),%edx # edx = x
movl $1,-4(%ebp) # val = 1 movl 8(%ebp),%edx # edx = x movl $1,-4(%ebp) # val = 1 movl 8(%ebp),%edx # edx = x movl $1,-4(%ebp) # val = 1
Space
%esp
int sfact(int x)
gg
variabel lokal
Variabel val harus disimpan
dalam stack Unused -12 -16 int sfact(int x) { int val = 1;
Perlu membuat pointer
Perhitungan pointer -4(%ebp) Push stack sebagai argumen
Passing Pointer
Memanggil s_helper dari sfact
Stack pada waktu call
leal -4(%ebp),%eax # Compute &val pushl %eax # Push on stack pushl %edx # Push x
x Rtn adr Old % b % b 0 4 8 leal -4(%ebp),%eax # Compute &val
pushl %eax # Push on stack pushl %edx # Push x
leal -4(%ebp),%eax # Compute &val pushl %eax # Push on stack pushl %edx # Push x
p #
call s_helper # call
movl -4(%ebp),%eax # Return val
• • • # Finish
Old %ebp %ebp 0
val = 1 -4
-8
p #
call s_helper # call
movl -4(%ebp),%eax # Return val
• • • # Finish
p #
call s_helper # call
movl -4(%ebp),%eax # Return val
• • • # Finish val =x! int sfact(int x) { Unused -12 -16 &val int val = 1; s_helper(x, &val); return val; } %esp x &val }
Menggunakan Pointer
void s_helper
(int x, int *accum) { %edx accum accum*x { • • • int z = *accum * x; *accum = z; x x %eax %ecx accum*x • • • • • • } movl %ecx,%eax # z = x
imull (%edx),%eax # z *= *accum movl %eax,(%edx) # *accum = z • • •
• • •
Kesimpulan
Stack dapat membuat rekursi bekerja
Penyimpanan privat untuk setiap pemanggilan prosedur
Tidak saling mengganggu satu sama lain
Pengalamatan variabel lokal dan argumen relatif terhadap posisi t k
stack
Dapat dikelola dengan stack
Prosedur return dalam urutan call terbalik
K
bi
i i t k i d
t
d l
d
IA32
Kombinasi instruksi dan aturan dalam prosedur IA32
Instruksi Call / Ret
Aturan penggunaan register
Caller / Callee save %ebp dan %esp