課程資源-計算機組織與結(jié)構(gòu)chapter_第1頁
課程資源-計算機組織與結(jié)構(gòu)chapter_第2頁
課程資源-計算機組織與結(jié)構(gòu)chapter_第3頁
課程資源-計算機組織與結(jié)構(gòu)chapter_第4頁
課程資源-計算機組織與結(jié)構(gòu)chapter_第5頁
已閱讀5頁,還剩26頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第四章指令系統(tǒng)

(三)

指令系統(tǒng)分以下五個部分介紹第一講:指令系統(tǒng)概述指令格式設(shè)計指令系統(tǒng)設(shè)計第二講:指令系統(tǒng)實例IA-32指令系統(tǒng)第三講:

程序的機器級表示

選擇語句的機器級表示循環(huán)結(jié)構(gòu)的機器級表示過程調(diào)用的機器級表示選擇結(jié)構(gòu)的機器級表示

if~else語句的機器級表示if(cond_expr)then_statementelseelse_statement

If-else語句舉例intget_cont(int*p1,int*p2){ if(p1>p2) return*p2; else return*p1; }p1和p2對應(yīng)實參的存儲地址分別為R[ebp]+8、R[ebp]+12,EBP指向當前棧幀底部,結(jié)果存放在EAX。例例x<-3x<=2x^yx-yx>yx*yx+y指令系統(tǒng)分以下五個部分介紹第一講:指令系統(tǒng)概述指令格式設(shè)計指令系統(tǒng)設(shè)計第二講:指令系統(tǒng)實例IA-32指令系統(tǒng)第三講:

程序的機器級表示

選擇語句的機器級表示循環(huán)結(jié)構(gòu)的機器級表示過程調(diào)用的機器級表示循環(huán)結(jié)構(gòu)的機器級表示do~while循環(huán)的機器級表示doloop_body_statement

while(cond_expr);loop:

loop_body_statementc=cond_expr;

if(c)gotoloop;while(cond_expr)loop_body_statement

c=cond_expr;

if(!c)gotodone;loop:

loop_body_statementc=cond_expr;

if(c)gotoloop;done:for(begin_expr;cond_expr;update_expr) loop_body_statementwhile循環(huán)的機器級表示

for循環(huán)的機器級表示

begin_expr;c=cond_expr;

if(!c)gotodone;loop:

loop_body_statement

update_expr;c=cond_expr;

if(c)gotoloop;done:紅色處為條件轉(zhuǎn)移指令!循環(huán)結(jié)構(gòu)intnn_sum(intn){ inti; intresult=0; for(i=1;i<=n;i++) result+=i; returnresult;}

movl8(%ebp),%ecxmovl$0,%eaxmovl$1,%edxcmpl%ecx,%edxjg.L2.L1:addl%edx,%eaxaddl$1,%edxcmpl%ecx,%edxjle.L1.L2利用循環(huán)結(jié)構(gòu)實現(xiàn)整數(shù)累加指令系統(tǒng)分以下五個部分介紹第一講:指令系統(tǒng)概述指令格式設(shè)計指令系統(tǒng)設(shè)計第二講:指令系統(tǒng)實例IA-32指令系統(tǒng)第三講:

程序的機器級表示

選擇語句的機器級表示循環(huán)結(jié)構(gòu)的機器級表示過程調(diào)用的機器級表示

intadd(intx,inty){ returnx+y;}intmain(){ int t1=125;intt2=80; int sum=add(t1,t2); returnsum;}過程調(diào)用的機器級表示以下過程(函數(shù))調(diào)用對應(yīng)的機器級代碼是什么?如何將t1(125)、t2(80)分別傳遞給add中的形式參數(shù)x、yadd函數(shù)執(zhí)行的結(jié)果如何返回給caller?

addmain

main: add:存放參數(shù) 取出參數(shù)調(diào)出add執(zhí)行 執(zhí)行存返回結(jié)果

返回main

過程調(diào)用的機器級表示

過程調(diào)用的執(zhí)行步驟(P為調(diào)用者,Q為被調(diào)用者)(1)P將入口參數(shù)(實參)放到Q能訪問到的地方;(2)P保存返回地址,然后將控制轉(zhuǎn)移到Q;(3)Q保存P的現(xiàn)場,并為自己的非靜態(tài)局部變量分配空間;(4)執(zhí)行Q的過程體(函數(shù)體);(5)Q恢復(fù)P的現(xiàn)場,釋放局部變量空間;(6)Q取出返回地址,將控制轉(zhuǎn)移到P。結(jié)束階段準備階段Q過程P過程處理階段CALL指令RET指令

main: add:存放參數(shù) 取出參數(shù)調(diào)出add執(zhí)行 執(zhí)行存返回結(jié)果

返回main

何為現(xiàn)場?通用寄存器的內(nèi)容!為何要保存現(xiàn)場?因為所有過程共享一套通用寄存器過程調(diào)用的機器級表示

IA-32的寄存器使用約定調(diào)用者保存寄存器:EAX、EDX、ECX

當過程P調(diào)用過程Q時,Q可以直接使用這三個寄存器,不用將它們的值保存到棧中。如果P在從Q返回后還要用這三個寄存器的話,P應(yīng)在轉(zhuǎn)到Q之前先保存,并在從Q返回后先恢復(fù)它們的值再使用。被調(diào)用者保存寄存器:EBX、ESI、EDI

Q必須先將它們的值保存到棧中再使用它們,并在返回P之前恢復(fù)它們的值。EBP和ESP分別是幀指針寄存器和棧指針寄存器,分別用來指向當前棧幀的底部和頂部。問題:為減少準備和結(jié)束階段的開銷,每個過程應(yīng)先使用哪些寄存器?EAX、ECX、EDX!過程調(diào)用的機器級表示過程調(diào)用過程中棧和棧幀的變化(Q為被調(diào)用過程)①②③⑤Q(參數(shù)1,…,參數(shù)n);入口參數(shù)的位置每個過程開始兩條指令總是pushl%ebpmovl%esp,%ebp在IA-32中,若棧中存放的參數(shù)的類型是char、unsignedchar或short、unsignedshort,也都分配4個字節(jié)。因而,在被調(diào)用函數(shù)的執(zhí)行過程中,可以使用R[ebp]+8、R[ebp]+12、R[ebp]+16、……作為有效地址來訪問函數(shù)的入口參數(shù)。返回地址EBP在main中的值EBPEBP+8EBP+12入口參數(shù)1入口參數(shù)2入口參數(shù)3EBP+16movl…….準備入口參數(shù)call…….一個簡單的過程調(diào)用例子caller:pushl %ebpmovl %esp,%ebpsubl $24,%espmovl $125,-12(%ebp) movl $80,-8(%ebp)movl-8(%ebp),%eaxmovl %eax,4(%esp)movl -12(%ebp),%eax movl %eax,(%esp) call add movl %eax,-4(%ebp) movl -4(%ebp),%eax leave ret

準備階段結(jié)束階段caller幀底intadd(intx,inty){ returnx+y;}int caller(){ int t1=125;int t2=80; int sum=add(t1,t2); returnsum;}ESP+4分配局部變量準備入口參數(shù)-4-8-12-16-20返回參數(shù)總在EAX中準備返回參數(shù)add函數(shù)開始是什么?pushl%ebpmovl%esp,%ebp

addcallermovl %ebp,%esppopl %ebp例過程調(diào)用參數(shù)傳遞舉例程序一的輸出:a=15 b=22a=22 b=15程序二的輸出:a=15 b=22a=15 b=22程序一#include<stdio.h>main(){inta=15,b=22;printf(“a=%d\tb=%d\n”,a,b);

swap(&a,&b);printf(“a=%d\tb=%d\n”,a,b);}swap(int*x,int*y){ intt=*x; *x=*y; *y=t;}程序二#include<stdio.h>main(){inta=15,b=22;printf(“a=%d\tb=%d\n”,a,b);

swap(a,b);printf(“a=%d\tb=%d\n”,a,b);}swap(intx,inty){ intt=x; x=y; y=t;}按地址傳遞參數(shù)按值傳遞參數(shù)執(zhí)行結(jié)果?為什么?過程調(diào)用參數(shù)傳遞舉例返回地址EBP在main中的值EBPEBP+8EBP+12EBX在main中的值R[ecx]←M[&a]=15R[ebx]←M[&b]=22M[&a]←

R[ebx]=22M[&b]←

R[ecx]=152215局部變量a和b確實交換過程調(diào)用參數(shù)傳遞舉例返回地址EBP在main中的值EBPEBP+8EBP+12R[edx]←15R[eax]←222215M[R[ebp]+8]←

R[eax]=22M[R[ebp]+12]←

R[edx]=15局部變量a和b沒有交換,交換的僅是入口參數(shù)!例函數(shù)原型是什么?過程調(diào)用舉例1voidtest(intx,int*ptr)2{3 if(x>0&&*ptr>0)4 *ptr+=x;5 } 6 7voidcaller(inta,inty)8{9intx=a>0?a:a+100;10 test(x,&y);11}調(diào)用caller的過程為P,P中給出形參a和y的實參分別是100和200,畫出相應(yīng)棧幀中的狀態(tài),并回答下列問題。(1)test的形參是按值傳遞還是按地址傳遞?test的形參ptr對應(yīng)的實參是一個什么類型的值?(2)test中被改變的*ptr的結(jié)果如何返回給它的調(diào)用過程caller?(3)caller中被改變的y的結(jié)果能否返回給過程P?為什么?

testcallerP

caller執(zhí)行過程中,在進入test之前一刻棧中的狀態(tài)如何?進入test并生成其棧幀后,棧中狀態(tài)如何?&y:&a:Pcaller100200300前者按值、后者按地址。一定是一個地址第10行執(zhí)行后,P幀中200變成300,test退幀后,caller中通過y引用該值300第11行執(zhí)行后caller退幀并返回P,因P中無變量與之對應(yīng),故無法引用該值300過程調(diào)用的機器級表示遞歸函數(shù)nn_sum的執(zhí)行流程過程功能由過程體實現(xiàn),為支持過程調(diào)用,每個過程包含準備階段和結(jié)束階段。因而每增加一次過程調(diào)用,就要增加許多條包含在準備階段和結(jié)束階段的額外指令,它們對程序性能影響很大,應(yīng)盡量避免不必要的過程調(diào)用,特別是遞歸調(diào)用。

intnn_sum(intn){ intresult; if(n<=0) result=0; else result=n+nn_sum(n-1); returnresult;}遞歸過程調(diào)用舉例Pnn_sum(n-1)nn_sum(n)PSum(n)Sum(n-1)R[ebx]←nif(n≤0)轉(zhuǎn)L2R[eax]←0R[eax]←n-1R[eax]←0+1+2+…+(n-1)+nn

每次遞歸調(diào)用都會增加一個棧幀,所以空間開銷很大。過程調(diào)用舉例例:應(yīng)始終返回d[0]中的3.14,但并非如此。Why?doublefun(inti){volatiledoubled[1]={3.14};volatilelonginta[2];a[i]=1073741824;/*Possiblyoutofbounds*/returnd[0];}fun(0) 3.14fun(1) 3.14fun(2) 3.1399998664856fun(3) 2.00000061035156fun(4) 3.14,然后存儲保護錯

不同系統(tǒng)上執(zhí)行結(jié)果可能不同為何每次返回不一樣?為什么會引起保護錯?棧幀中的狀態(tài)如何?doublefun(inti){volatiledoubled[1]={3.14};volatilelonginta[2];a[i]=1073741824;returnd[0];}EBP的舊值EBPESPa[i]=1073741824;returnd[0];0x40000000=230=1073741824越界訪問和緩沖區(qū)溢出C語言中的數(shù)組元素可使用指針來訪問,因而對數(shù)組的引用沒有邊界約束,也即程序中對數(shù)組的訪問可能會有意或無意地超越數(shù)組存儲區(qū)范圍而無法發(fā)現(xiàn)。數(shù)組存儲區(qū)可看成是一個緩沖區(qū),超越數(shù)組存儲區(qū)范圍的寫入操作稱為緩沖區(qū)溢出。例如,對于一個有10個元素的char型數(shù)組,其定義的緩沖區(qū)有10個字節(jié)。若寫一個字符串到這個緩沖區(qū),那么只要寫入的字符串多于9個字符(結(jié)束符‘\0’占一個字節(jié)),就會發(fā)生“寫溢出”。緩沖區(qū)溢出是一種非常普遍、非常危險的漏洞,在各種操作系統(tǒng)、應(yīng)用軟件中廣泛存在。緩沖區(qū)溢出攻擊是利用緩沖區(qū)溢出漏洞所進行的攻擊行動。利用緩沖區(qū)溢出攻擊,可導(dǎo)致程序運行失敗、系統(tǒng)關(guān)機、重新啟動等后果。

共24字節(jié)越界訪問和緩沖區(qū)溢出造成緩沖區(qū)溢出的原因是沒有對棧中作為緩沖區(qū)的數(shù)組的訪問進行越界檢查。#include"stdio.h"#include"string.h"voidoutputs(char*str){charbuffer[16];strcpy(buffer,str);printf("%s\n",buffer);}voidhacker(void){printf("beinghacked\n");}intmain(intargc,char*argv[]){outputs(argv[1]);return0;}舉例:利用緩沖區(qū)溢出轉(zhuǎn)到自設(shè)的程序hacker去執(zhí)行outputs漏洞:當命令行中字符串超25個字符時,使用strcpy函數(shù)就會使緩沖buffer造成寫溢出并破壞返址

假定可執(zhí)行文件名為test16+4+4+1=25共24字節(jié)越界訪問和緩沖區(qū)溢出test被反匯編得到的outputs匯編代碼

080483e4push%ebp080483e5mov%esp,%ebp080483e7sub$0x18,%esp080483eamov0x8(%ebp),%eax080483edmov%eax,0x4(%esp)080483f1lea0xfffffff0(%ebp),%eax080483f4mov%eax,(%esp)0804

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論