750 likes | 1.55k Views
第三章 電腦的語言 : 指令. 計算機組織與設計 蔡昌隆 學貫行銷股份有限公司. 學習目標. 瞭解高階語言和低階語言的區別 瞭解控制電腦硬體實際運作的機器語言 瞭解電腦硬體如何執行運算 瞭解組合語言 (MIPS) 的定址法和程式設計. 前 言. 電腦溝通的語言,其 單字即為指令 ,而 字彙就是指令集 ,將很多指令集彙集編成一個可以命令電腦去執行並達成計畫目標的就叫做程式。 主程式( main program ) :顧名思義即為最主要的程式或者說是程式的主體部分,為一個完整可以執行的指令集。
E N D
第三章電腦的語言:指令 計算機組織與設計 蔡昌隆 學貫行銷股份有限公司
學習目標 • 瞭解高階語言和低階語言的區別 • 瞭解控制電腦硬體實際運作的機器語言 • 瞭解電腦硬體如何執行運算 • 瞭解組合語言(MIPS)的定址法和程式設計
前 言 • 電腦溝通的語言,其單字即為指令,而字彙就是指令集,將很多指令集彙集編成一個可以命令電腦去執行並達成計畫目標的就叫做程式。 • 主程式(main program):顧名思義即為最主要的程式或者說是程式的主體部分,為一個完整可以執行的指令集。 • 副程式或副常式(subroutine):涵蓋在主程式中的一小部分獨立的迴圈或疊代處理的程式或是獨立於主程式之外,可透過主程式的程序呼叫去執行主程式所交付的任務。
一般程式語言主要區分為高階程式語言和低階程式語言(包括組合語言與機器語言等),這些語言都是我們和電腦溝通所使用的工具,它們的功能屬性各有不同,而使用高階語言來撰寫程式的好處是可以避免使用標籤來執行跳躍的動作,因為那會增加程式預測所需付出的作業時脈週期。一般程式語言主要區分為高階程式語言和低階程式語言(包括組合語言與機器語言等),這些語言都是我們和電腦溝通所使用的工具,它們的功能屬性各有不同,而使用高階語言來撰寫程式的好處是可以避免使用標籤來執行跳躍的動作,因為那會增加程式預測所需付出的作業時脈週期。
程式語言的發展 • 真空管時期(1946~1954年期間):為美軍委託賓州大學研成ENIAC計算機後所使用的語言,含機器語言和組合語言。 • 電晶體時期(1955~1964年期間):為因應美國AT&T貝爾實驗室(Bell Laboratory)發明電晶體後,新一代使用電晶體的電腦問市後所使用的程式語言含COBOL、LISP和FORTRAN等。
積體電路(IC,Integrated Circuit)時期(1965~1974年期間):為因應德州儀器開發出積體電路後,IBM S/360等電腦所使用的程式語言,以BASIC為主。 • 超大型積體電路(VLSI,Very Large Scale Integrated Circuit)時期(1975迄今):在Intel公司推出4004微處理器以後所使用的程式語言,含PL/1、PASCAL、C、MIPS、Ada、C++和Java等等。 • 未來程式語言的發展主要朝向問題導向和程序導向,應屬結合平行處理和人工智慧的產品。
雖然我們使用很多的多媒體或文書編譯軟體,其實它們都是透過高階程式語言或低階程式語言所開發出來的,透過這些方便的介面,讓我們駕馭電腦去完成任務更顯得輕鬆方便又有效率。雖然我們使用很多的多媒體或文書編譯軟體,其實它們都是透過高階程式語言或低階程式語言所開發出來的,透過這些方便的介面,讓我們駕馭電腦去完成任務更顯得輕鬆方便又有效率。 • 在計算機組織系統中比較重要而經常探討的便是MIPS組合語言(含MIPS-32和MIPS-64),它是1980年代的產品,目前有超過上億的處理器使用MIPS組合語言。
硬體運算元 • 電腦中數值的運算都是透過邏輯電路來執行計算的,它會將你所輸入的資料放到暫存器裡面,再把它輸入算術邏輯運算單元去做處理,最後送出答案給你,其中暫存器的大小會直接的影響到你所能計算的數值的最大或最小值,而暫存器的數量多寡則會影響到運算的效率,然而並不是越多的暫存器就會執行越快,因為過多的暫存器會增長時脈週期的時間,如此一來反而降低執行效能,一般電腦的暫存器多為32個。
電腦亦據此以32位元或64位元為基做計算,而計算的基本單位通常為字組(word),即1個字組為32位元,而MIPS組合語言系統對字組有定位排列的限制(alignment restriction),所以程式執行所使用的暫存器都必須使用4的倍數當起始的位址。每當執行一個指令,程式計數器便會累加1,然後擷取下一行的指令,而下一行的指令其對應儲存在指令記憶體中的位址便是按4的倍數排列(如下圖),這即是MIPS系統的對應規則。
暫存器 高位址 4的倍數 資料 8 資料 4 資料 低位址0 硬體運算元
AX 高位元31 0低位元 16 EAX AH AL ECX CH CL EDX DH DL EBX BH BL • Intel公司最初所推出的8位元處理器,其資料暫存器僅有A、B、C和D等四個;其後的16位元處理器的暫存器定名為AX、BX、CX和DX,再透過H(high)和L(low)來表示屬於高位元或低位元,例如AH或AL。隨著32位元處理器的問市,IA-32系統則使用EAX、EBX、ECX和EDX來代表暫存器,其前面加上的“E”表示延伸或擴展
副程式的執行步驟 • 參數需儲存在副程式可以讀取或儲存的位址。 • 由副程式控制執行工作。 • 副程式擷(讀)取所需的儲存資料。 • 執行運算。 • 運算結果回傳給呼叫副程式可以儲存的位址。 • 副程式將控制權交回給主程式。
MIPS暫存器 • MIPS系統中執行運算的暫存器有32個 • 編號0:$zero(零值暫存器) • 編號1:$at(組譯器使用的暫存器) • 編號2~3:$v0~$v1(回傳值暫存器) • 編號4~7:$a0~$a3(參數暫存器,argument pointer) • 編號8~15:$t0~$t7(暫時暫存器,temporary pointer)
MIPS暫存器 • 編號16~23:$s0~$s7(儲存暫存器,saved pointer) • 編號24~25:$t8~$t9(暫時暫存器) • 編號26~27:$k0~$k1(作業系統使用的暫存器) • 編號28:$gp(全域性指標暫存器,global pointer):為儲存指引靜態資料區塊位址的暫存器。 • 編號29:$sp(堆疊指標暫存器,stack pointer)
編號30:$fp(框指標暫存器,frame pointer) :為儲存指引到程序框第一個字組位址的暫存器。 • 編號31:$ra(回傳位址暫存器,return address) :為儲存指引返回原來位址的暫存器。 • $s0~$s7和$ra屬於堆疊指標位址以上的記憶體,在程序呼叫時,被呼叫者”必須”暫時儲存這些暫存器的資料;而$t0~$t9、$a0~$a3和$v0~$v1則為堆疊指標位址以下的記憶體,在程序呼叫時,被呼叫者”不需”暫時儲存這些暫存器的資料
例題:撰寫MIPS程式將堆疊中空出三個暫存器來儲存資料例題:撰寫MIPS程式將堆疊中空出三個暫存器來儲存資料 • 說明: 步驟一:空出堆疊空間,可以使用立即加法指令 addi $sp, $sp, -12 空出三個儲存空間 等於是撥出3*4=12個位址 所以將堆疊指標-12 步驟二:將空出的空間儲存資料 sw $s0, $0($sp) 將$s0儲存到堆疊中 sw $s1, $4($sp) 將$s1儲存到堆疊中 sw $s2, $8($sp) 將$s2儲存到堆疊中
$fp $fp $sp $sp $fp 參數 暫存器 回傳位址 暫存器 程序呼叫前的指標 指引情形 因尚未開始堆疊資料,所以$sp指到堆疊最上面 完成程序呼叫後,指標會返回原來的指引位置 儲存 暫存器 區隔性的 陣列與結構 $sp 堆疊指標 程序呼叫時的 指標指引情形 • 執行程序呼叫的時候,會使用堆疊指標來標定堆疊資料的起始位址,而程序結構指標或框架指標(frame pointer)則指引到程序或副程式的第一個字組
位址:好比家裡的地址,可以清楚的指引郵差送信到該地址;而該位址裡所存放的資料,就好比家裡的設備配備等等。位址:好比家裡的地址,可以清楚的指引郵差送信到該地址;而該位址裡所存放的資料,就好比家裡的設備配備等等。 • 呼叫者(caller):啟動程序或副程式並給予相關的參數交給被呼叫者去執行。 • 被呼叫者(callee):根據呼叫者提供的資訊(如指令和參數)來執行相關作業,當作業執行完畢後會立即將控制權交還給呼叫者。
程式計數器(PC,program counter):用來標定執行中的指令是儲存在指令暫存器的那一個位址,以便讀取該位址相應的指令碼來執行後續的工作。 • MIPS組合語言系統只提供$a0~$a3四個暫存器給參數使用,若是超過四個以上的參數時,超過的參數部分會被放在程序框指標上方的堆疊;通常程式執行時,程序會預測前四個參數是放在$a0~$a3並自動擷取,而其他的參數則由$fp指標來指出它們在記憶體中所對應的位址。
記憶體 位址 7fff fffc 指標$sp 堆疊 動態資料區塊 指標$gp 靜態資料區塊 1000 8000 1000 0000 程式碼 本文區塊 程式計數$pc 0040 0000 保留區塊 起始 0000 0000 記憶體最下層的部分是保留區塊,依序往上為儲存程式機器碼的本文區塊(text segment),再往上為放置靜態變數和常數部分的靜態資料的儲存區塊(static data segment),最上層的部分則市儲存動態變數的動態資料區塊
例題1:使用暫存器來編撰C程式為x=i+j; • 說明: 步驟一:先指定暫存器給變數 將i存在來源暫存器1=$s1 j存在來源暫存器2=$s2 運算結果值x儲存在目的地暫存器=$t0 步驟二:編撰MIPS程式 add $t0, $s1, $s2
例題2:使用暫存器來編撰C程式為x=(i+j)-k; • 說明: 步驟一:先指定暫存器給變數 將i存在暫存器$s1 j存在暫存器$s2 k存在暫存器$s3 運算的結果值x儲存在目的地暫存器=$t0 步驟二:編撰MIPS程式 add $t0, $s1, $s2 完成i+j sub $t0, $t0, $s3 完成i+j-k
例題3:假設X陣列的基底位址為$s1,變數Y對應暫存器$t0,使用暫存器來編撰C程式為X〔100〕= X〔100〕+ Y; • 說明: 步驟一:先指定暫存器給變數 X〔100〕的值存在暫存器$s1,位址為400 運算後的和存在暫存器$t1 步驟二:編撰MIPS程式 lw $t1, 400($s1) 暫存器$t1存放X〔1〕的值 add $t1, $t0, $t1 X〔100〕+ Y sw $t1, 400($s1) X〔100〕+ Y的值儲存到X 〔100〕 ※註:X〔100〕的位址為4*100=400。
程式 執行碼 來源暫存器rs 來源暫存器rt 常數 或位址 6欄位 5欄位 5欄位 16欄位 • 例題6:撰寫常數10和暫存器$s2相加的MIPS程式 • 說明: 1. 解法一:使用立即加法,格式如下 程式碼為 addi $s2, $s2, 4 $s2=$s2+4; 2. 解法二:使用加法 lw $t0, 4 將常數載入$t0暫存器 add $s2, $s2, $t0 執行$s2+4
程式 執行碼 來源暫存器rs 來源暫存器rt 目的地暫存器 位移量 函數 功能 6欄位 5欄位 5欄位 5欄位 5欄位 6欄位 電腦硬體的運算 • 電腦運算不外乎加、減、乘、除和資料的交換應用,本節將以例題說明的方式來闡述電腦中硬體的運算。 • 以MIPS執行運算為例,其指令相對應的欄位內容概略如下:
0 000000 17 10001 18 10010 8 01000 0 00000 32 100000 • 例題1:將MIPS指令add $t0, $s1, $s2轉譯成機器碼 • 說明: • 步驟一:$t0=8(目的地暫存器) $s1=17(來源暫存器1) $s2=18(來源暫存器2) 將暫存器內儲存的值以十進位數值表示如下: 2.步驟二:轉換成二進位的機器碼如下: 3.步驟三:轉換成十六進位後的數值為 000000100011001001000000001000002=0232402016
例題2:請問機器碼0253982016的意義 • 說明: • 步驟一:將16進位機器碼02539820轉換成2進位 轉換後的數值為000000100101001110001000001000002 2. 步驟二:依MIPS指令格式的欄位劃分32位元的2進位數值如下: 程式碼來源暫存器1來源暫存器1目的地暫存器位移量函式 000000 10010 10011 10001 00000 100000 18=$s2 19=$s3 17=$s1 所以轉換後的MIPS程式碼為 add $s1, $s2, $s3
資料交換為程式撰寫中常用的一部分 • C程式語言中,我們常用的資料交換程式內容概下: Temp = X; X= Y; Y = Temp; 如此即完成X和Y的資料交換。
例題3:以MIPS語言撰寫暫存器中資料的交換 • 說明:假設X存在暫存器$s0中,而Y存在暫存器$s1 將X和Y的資料交換,程式如下: lw $t0, X 將X存到暫時的暫存器$t0 sw $s0, Y 將Y存到$s0 sw $s1, $t0 將X由$t0轉存到$s1完成資料交換 • 組合語言: move $t0, $s0 將X存到暫時的暫存器$t0 move $s0, $s1 將Y存到$s0 move $s1, $t0 將X由$t0轉存到$s1
算術邏輯單元控制器 • 通常算術邏輯單元(ALU)的運算會由一個控制器來主導其執行內容,該控制器有4條訊號線,其控制算術邏輯單元的參照表如右:
MIPS組合語言 • 語言架構、邏輯運算、決策指令:將C程式語言轉譯成MIPS組合語言的主要工作是由編譯器所負責的,按MIPS-32指令集架構(ISA;Instruction Set Architecture)所設計的指令都是以32位元模式執行 • 處理暫存器: • 32個32位元的一般用途暫存器(GPRs,general propose register),其中R0設定永遠為0。 • 16個雙倍精準度和32個單倍精準度的浮點數用途暫存器(FPRs,floating-point propose register)。 • 浮點狀態暫存器支援比較和例外功能。 • 此外尚有其他特殊用途的暫存器。
資料型態:包含有8位元組、16位元半字元、32位元整數字元、32位元單倍精準度浮點數、64位元雙倍精準度浮點數。 • 讀取和儲存型式的指令集: • 資料位址包含立即和索引2種模式。 • 分節(跳躍)位址包含程式計數相對和暫存器非直接對應模式。 • 陣列位元組資料載入和儲存的位址表示法
程式 執行碼 程式 執行碼 程式 執行碼 來源暫存器rs 來源暫存器rs 來源暫存器rs 來源暫存器rt 來源暫存器rt 來源暫存器rt 立即 immediate 目的地暫存器 差量 displacement 0 函數 功能 6欄位 6欄位 6欄位 5欄位 5欄位 5欄位 5欄位 5欄位 5欄位 5欄位 16欄位 16欄位 5欄位 6欄位 MIPS組合語言的基本格式 • 算數邏輯運算(ALU) • 算數邏輯立即運算(ALUi) • 記憶體(Mem)的操作
程式 執行碼 程式 執行碼 程式 執行碼 來源暫存器rs 補償 offset 來源暫存器rs 補償 offset 6欄位 6欄位 6欄位 5欄位 5欄位 26欄位 5欄位 5欄位 16欄位 16欄位 • 條件式的跳躍(beqz和bnez) • 非條件式的非直接跳躍(jr和jalr) • 非條件式的絕對跳躍(j和jal)
MIPS組合語言程式執行時的五個工作程序 • 擷取(讀)程式碼(指令)。 • 解碼(瞭解指令所要執行的工作及要讀取的暫存器所儲存的資料)。 • 邏輯運算(交給ALU單元執行運算工作)。 • 記憶體作業(可選擇)。 • 寫回(write back)並計算下一個指令的位址。
MIPS組合語言常用指令 • 資料的讀取(載入)指令: • 讀取位元組lb(load byte) • 讀取無號的位元組lbu(load byte unsigned) • 讀取半字組lh(load half) • 讀取字元組lw (load word) • 立即讀取上半部的高位元資料lui
例題1:lw $s1, $s2 • 說明:將暫存器$s2位址中所儲存的資料放到暫存器$s1位址上。 • 例題2:lw $s1,10 • 說明:將常數值10放到暫存器$s1位址上。
資料的儲存指令 • 儲存位元組sb(save byte) • 儲存無號的位元組sbu(save byte unsigned) • 儲存半字組sh(save half) • 儲存字元組sw (save word)
例題1:sw $s1, $s2 • 說明:將暫存器$s2位址的資料儲存到暫存器$s1位址中。 • 例題2:sw $s1, 10 • 說明:將常數值10儲存至暫存器$s1位址中。
加減乘除的計算 • 加法的計算:指令add $s1, $s2, $s3 • 立即加法的計算:指令addi $s1, $s2, constant(常數值) • 例題1:add $s1, $s2, $s3 • 說明:將暫存器$s2位址所儲存的資料和暫存器$s3位址所儲存的資料相加後,儲存到暫存器$s1的位址上。 • 例題2:addi $s1, $s2, 10 • 說明:將暫存器$s2位址所儲存的資料和常數值10相加後,儲存到暫存器$s1的位址上。
減法計算:指令sub $s1, $s2, $s3 • 例題1:sub $s1, $s2, $s3 • 說明:將暫存器$s2位址所儲存的數值和暫存器$s3位址所儲存的數值相減($s2-$s3)後,儲存到暫存器$s1的位址上。 • 例題2:暫存器$s2位址所儲存的資料減去常數值10後,儲存到暫存器$s1的位址上 • 說明: sw $t0, 10 將常數10存到暫時暫存器$t0; 也可以使用lw $t0, 10的程式寫法 sub $s1, $s2, $t0$s2暫存器所儲存的數值減去$t0暫存器所儲存的數值(常數10),所得的差儲存到$s1暫存器
程式 執行碼 來源暫存器rs 來源暫存器rt 立即欄位 (負的常數值) 6欄位 5欄位 5欄位 16欄位 • 因為C和Java程式語言不常使用負值的常數來執行運算,因需求不多,所以MIPS組合語言中沒有立即減法的指令設計;而若要處理負值的常數計算,可使用立即定址法的指令格式來撰寫程式,只需將負值的常數放在立即值的欄位即可
乘法計算:指令mult $s1, $s2, $s3 • 例題1:mult $s1, $s2, $s3 • 說明:將暫存器$s2位址所儲存的數值和暫存器$s3位址所儲存的數值資料相乘($s2*$s3)後,儲存到暫存器$s1的位址上。 • 例題2:將暫存器$s2位址所儲存的數值乘上常數值10後,儲存到暫存器$s1的位址上 • 說明: sw $t0, 10 將常數10存到暫時暫存器$t0 mult $s1, $s2, $t0$s2暫存器所儲存的數值乘上$t0暫存器所儲存的數值(常數10),所得的積儲存到$s1暫存器
除法計算:指令div $s1, $s2, $s3 • 例題1:div $s1, $s2, $s3 • 說明:將暫存器$s2位址所儲存的數值除以暫存器$s3位址所儲存的數值($s2/$s3)後,所得到的商數儲存到暫存器$s1的位址上。 • 例題2:將暫存器$s2位址所儲存的資料除以常數值5後所得到的商數儲存到暫存器$s1的位址上 • 說明: sw $t0, 10 將常數10存到暫時暫存器$t0 div $s1, $s2, $t0$s2暫存器所儲存的數值除以$t0暫存器所儲存的數值(常數5),所得的商數儲存到$s1暫存器
數值的比較 1.小於時設定slt(set on less than) 2.小於時立即slti(set on less than) 3.無號值小於時sltu 4.無號值小於時立即sltiu • 例題1:slti $s1, $s2, 8 • 說明:假如暫存器$s2位址所儲存的數值小於常數8時,設定暫存器$s1位址所儲存的數值為1,若是大於或等於常數8時則將暫存器$s1位址所儲存的數值為0。 本例子相當於C程式 if ( $s2 < 10 ) $s1=1; else $s1=0
例題2:slt $s1, $s2, $s3 • 說明:假如暫存器$s2位址所儲存的數值小於暫存器$s3位址所儲存的數值時,設定暫存器$s1位址所儲存的數值為1,若是大於或等於常數10時則將暫存器$s1位址所儲存的數值為0。 本例子相當於C程式 if ($s2 < $s3 ) $s1=1; else $s1=0;
資料的移位(shift) • 資料向左移位sll(shift left logic)指令(亦即C或Java程式中的”<<”運算) • 資料向右移位srl(shift right logic)指令(亦即C或Java程式中的”>>”運算) • 例題1:sll $s1, $s2, 8 • 說明:將暫存器$s2位址所儲存的數值向左移位8個位元後所得的新值儲存到暫存器$s2的位址上。 • 例題2:srl $s1, $s2, 6 • 說明:將暫存器$s2位址所儲存的數值向右移位6個位元後所得的新值儲存到暫存器$s2的位址上。
邏輯運算 • 或的運算or指令 • 及的運算and指令 • 反的運算not指令 • 非或的運算nor (not or)指令 • 立即執行及的運算andi (and immediate)指令 • 立即執行或的運算ori (or immediate)指令
例題1:or $s1, $s2, $s3 (亦即$s1 = $s2 | $s3) • 說明:將暫存器$s2位址所儲存的數值和暫存器$s3位址所儲存的數值執行“或”的運算後所得到的新值儲存到暫存器$s1的位址上。