2019-2020-1學期20212407《網路空間安全專業導論》第三週學習總結
今天我學習了《低階程式設計語言與虛擬碼》和《問題求解與演算法設計》兩章內容,思維導圖如下:
低階程式設計語言與虛擬碼
·機器語言是最低等級的程式語言
·虛擬碼能夠表示演算法
6.1 計算機操作
·我們所用的程式設計語言都必須反映出計算機能夠執行的運算型別
·計算機是能夠儲存、檢索和處理資料的可編輯電子裝置。使用者可以把資料輸入計算機,計算機能夠顯示資料。在最底層抽象中,給機器的指令直接反映了這5種操作
·操作字包括可程式設計的(programmable)、儲存(store)、檢索(retrieve)和處理(process)
6.2 機器語言
·機器語言(machine language):有計算機直接使用的二進位制編碼指令構成的語言【計算機必須參考的命令的真實清單並不存在】
·計算機的機器語言是一套機器的硬體能夠識別並執行的指令。每條機器語言指令只能執行一個非常低階的任務
·目前幾乎沒有程式是用機器語言編寫的,主要是因為編寫這種程式太費時間
1.Pep/9:一臺虛擬機器
·虛擬機器(virtual computer (machine)):為了模擬真實機器的重要特徵而設計的假象機器
·每種型別的CPU都有它能理解的自己的機器語言
·Pep/9有40條機器語言指令
----Pep/9的基本特性
·Pep/9的記憶體單元由65536位元組的儲存空間構成;Pep/9的字長是2位元組,或者16位
·暫存器(register)用來儲存特殊的資料和中間值。Pep/9有七個暫存器[重點研究三個pep/9的CPU]
程式計數器(PC),其中包含下一條即將被執行的指令的地址
指令暫存器(IR),其中包含正在被執行的指令的一個副本
累加器(A)用來儲存資料和運算的結果
·儲存器中的地址本身並不儲存在儲存器中,它們只是其中獨立位元組的名字
·可以的位數決定了我們可以使用的記憶體大小
----指令格式
·一條指令由兩部分組成,即8位的指令說明符(instruction specifier)和(可選的)16位的運算元說明符(operand specifier),所以Pep/9的指令長度是一位元組或三位元組,取決於是否需要用操作說明符
·指令說明符(指令的第一個位元組)說明了要執行什麼操作和如何解釋運算元的位置;運算元說明符(指令的第二和第三個位元組)存放的是運算元本身或運算元的地址
·操作程式碼(operation code)稱為操作碼(opcode),長度從4位到8位不等
·定址模式說明符(addressing mode specifier)表示怎樣解析指令中的運算元部分。【定址模式為000:立即定址(immediate(i));定址模式為001:直接定址(direct(d))】
·沒有運算元(要處理的資料)的指令稱為一元指令(unary instruction)
----一些示例指令
·0000停止指令:停止(stop)指令是一個一元指令,沒有運算元說明符
·1100將字載入暫存器A中:將一個字(兩個位元組)載入暫存器A中【定址模式決定了該字要載入的位置】
如果是立即定址,是被載入暫存器A中的值在運算元說明符中;如果是直接定址,是運算元說明符儲存了運算元駐留在記憶體中的地址(address)
·1101將位元組載入暫存器A中:將一個位元組載入暫存器A中
如果是立即定址,運算元說明符第一個位元組會被忽略,第二個位元組被載入暫存器A;如果是直接定址,只載入記憶體位置的1位元組而不是2位元組
·1110儲存暫存器A中的字:把暫存器A中的內容儲存到運算元中指定的位置
在儲存操作碼中使用立即定址模式是非法的,因為我們不能將暫存器的內容儲存到運算元說明符中
·1111儲存暫存器A的位元組:只存1位元組而不是2位元組,它不支援立即定址模式
·0110將運算元加到暫存器A中:與載入操作相似,相加操作使用定址模式說明符,使它有兩種解釋方式
·1000從暫存器A減運算元(與加法操作相似)
2.Pep/9的輸入/輸出
·Pep/9系統模擬了從鍵盤讀入字元輸入並將字元輸出寫到螢幕(終端視窗)中的能力;對於輸入和輸出(I/O),虛擬機器遵循的設計原則記憶體對映輸入/輸出(memory-mapped I/O)
6.3 一個程式例項(在螢幕上顯示“Hi”)
·有5條機器語言指令:2條用於載入,2條用於儲存,1條用於停止程式執行
·二進位制和十六進位制的列代表相同的值
·必須使用儲存單一位元組的儲存指令
1.Pep/9模擬器
·為了執行Pep/9機器語言程式,我們逐位元組輸入十六進位制的程式程式碼到一個有目的碼(Object Code)標籤的視窗中;程式程式碼每個位元組用空格隔開,以zz結束程式
·載入儲存器這個任務通過裝入程式(loader)的軟體工具實現
·讀取——執行週期:1)從由程式計數器確定的儲存器位置上獲取指令;2)解碼指令,更新程式計數器;3)獲得運算元(如果需要);4)執行指令
2.另一個機器語言例項(讀入兩個字元作為輸入,並且將它們逆序打印出來)
·1)載入位元組指令【從儲存器FC15(代表輸入裝置,儲存累加器的字元)位置讀入】;2)儲存位元組操作【暫時儲存儲存器0013位置字元】;3)載入位元組指令【讀取第二個字元,儲存到累加器】;4)儲存位元組操作【將第二個字元輸出到輸出裝置】;5)載入第一個字元【重新回到累加器】;6)儲存位元組操作【將第一個位元組輸出到輸出裝置(用來列印字元)】;7)使用一元終止指令停止
6.4 組合語言
·組合語言(assembly language):一種低階語言,用助記碼錶示特定計算機的機器語言指令
·彙編器(assembler):把組合語言程式翻譯成機器程式碼的程式
1.Pep/9組合語言
·Pep/9組合語言中,運算元用0x和十六進位制表示,接下來是逗號,最後是定址模式【由字母i(立即定址)或d(直接定址)說明,LDWA(載入字)和LDBA(載入位元組)兩種助記碼均能使用(i),定址載入運算元的值可用(d)】
·組合語言支援彙編器指令(assenbler directive),這些指令是彙編器本身使用(翻譯程式使用)的指令,有時被稱為偽操作(pseudo-operation)
·註釋(comment)是為程式使用者而寫的說明文字,解釋了會發生什麼情況
2.數字資料、分支、標籤
·Pep/9機器語言的輸出值被定義為單個字元,不能直接使用機器語言編寫程式來金鄉數值計算
·分支(branch):指出執行下一條指令的指令
1)DECI指令代表十進位制輸入(decimal input),可以讀入十進位制數,並存儲在運算元指定的位置(不支援(i))
2)DECO指令輸出特定的十進位制數字(支援(i)和(d));STRO指令用來列印完整的一串字元
3)BR指令(無條件轉移)使程式計數器(用來確定下一條指令的暫存器)的值為運算元中的儲存器地址
4)BRLT(累加器小於零)和BREQ(累加器等於零)指令只滿足特定情況時導致程式分支
5)CPWA指令對比了累加器中的數值和運算元(將累加器的當前值減去運算元,並存儲累加器的結果)
·標籤(label):對記憶體位置起的名字,可以將這個名字當作運算元
1)每個資料塊2位元組
2)標籤和它們對應的地址會在程式碼清單後以符號表(symbol table)的形式展示
3)BRLT指令被用來在累加器(sum)包含負數的時候進行跳轉
3.組合語言中的迴圈
·我們通過AddNums程式來使用迴圈
6.5表達演算法
·演算法(algorithm):解決方案的計劃或概要,或解決問題的邏輯步驟順序
·虛擬碼(pseudocode):一種表達演算法的語言(不是計算機語言)
1.虛擬碼的功能
·變數:出現在虛擬碼演算法中的名字,引用的是記憶體中儲存值的位置,反映它存放的值在演算法中的角色
·賦值:把值放入變數的方法
1’把值放入變數sum中:Set sum to 0 或者使用反箭頭sum <—— 1
2’訪問變數sum和num的值:Set sum to sum+num 或sum<——sum+num
·存入變數的值可以是單個的值,也可以是由變數或操作符構成的表示式(expression)
3’輸入/輸出
·我們可以使用write語句進行輸出,使用read語句進行輸入
1)Write“Enter the number of values to read and sum” 2)Read num
·雙引號之間的字元叫做字串(string)
·Display和Print都等價於Write,Get和Input與Read同義
·虛擬碼演算法是寫給人們看的,以便轉換成程式設計語言
1)Write “Err”【把雙引號之間的字元輸出到螢幕上】;Write sum【變數sum的內容輸出到螢幕上】
4’選擇
//Read and sum three numbers
IF(sum<0)
Print error message
Print sum
//Whatever comes next
符號"//"用於加註釋,它並不是演算法的一部分
5’重複
Set limit to number of value to sum
WHILE(counter<limit)
Read num
Set sum to sum+num
Set counter to counter+1
//Rest of program
·WHILE和IF旁邊的括號裡表示式是布林表示式(boolean expression),其結果可為真或假
·將WHILE、IF和FLSE大寫是因為這些語句通常直接使用在很多程式語言中,在計算領域中它們由特殊的含義
·一個虛擬碼語句可以被翻譯成多種組合語言語句
2.執行虛擬碼演算法
·decimalNumber最初存放的是這個問題的初始值,即要轉化的數
·方框newBase在整個過程中都沒有改變,這個演算法是把十進位制數轉化為另一種基數的值,所以必須給這個問題輸入新基數
3.寫虛擬碼演算法
·numberRead需改變,要增加numberRead的值
·虛擬碼是人們為了表示演算法而使用的一種便捷形式的語言,允許使用者命名變數(存放值的空間)、把數值輸入變數以及輸出儲存在變數中的值
·我們問了問題並推遲了細節。推遲細節則是首先給任務一個名稱,然後在補充細節來完成這個任務
·在沒有測試之前,演算法都不算完成。可以採用基於模擬基數轉換演算法的方法來測試演算法:選擇數值,用紙與筆進行程式碼走查
·桌面檢查(desk checking):在紙上走查整個設計
4.翻譯虛擬碼演算法
·如何翻譯虛擬碼演算法取決於我們將演算法翻譯成哪種成哪種語言
·首先使用ASCII偽操作設定訊息,然後建立程式碼將這個訊息寫出來;STRO指令是用來列印訊息的
認證是非政府組織給予滿足組織要求規定的個體識別資格的過程;許可是一個政府資助的法律權威
6.6 測試
·我們根據程式原先的目的來判斷它直觀的正確性
·測試計劃(test plan):說明如何測試程式的文件(每套輸入的資料值稱為測試用例(test case))
·程式碼覆蓋(明箱)測試法(code-coverage(clear-box)testing):通過執行程式碼中的所有語句測試程式或子程式的測試方法
·資料覆蓋(暗箱)測試法(data-coverage(black-box)testing):把程式碼作為一個暗箱,基於所有可能的輸入資料測試程式或子程式的測試方法
·測試計劃實現(test-plan implementation):用測試計劃中規定的測試用例驗證程式是否輸入了預期的結果
·程式碼覆蓋測試法通過仔細檢查程式的程式碼來決定程式的輸入;資料覆蓋測試法通過考慮所有可能的輸入值來決定程式的輸入
問題求解與演算法設計
·演算法,即它們在解決問題、開發策略、採用和測試的技術中的作用。我們選擇經典搜尋和排序演算法來討論演算法
7.1 如何解決問題
·如果把文字未知量改成問題,資料換成資訊,定理換成解決方案,Polya的書中“如何解決它”這個列表適用各種型別的問題
·其中第二步(找到資訊與解決方案之間的聯絡)是問題求解的核心
1·提出問題
2·尋找熟悉的情況
3.分治法(應用了抽象概念)
4.演算法
·演算法(algorithm):在有限的時間內用有限的資料解決問題或子問題的明確指令集合
5計算機問題求解過程
·四個階段:分析和說明階段(清楚的問題描述)、演算法開發階段(通用解決方案)、實現階段(計算機可以執行的程式)和維護階段(檢查是否有錯誤)
·如何用計算機解決問題的略圖中,包括Polya類別中的所有階段。第一步都是理解問題,不可能給根本不理解的問題編寫計算機解決方案
6.方案總結
·四個步驟:1)分析問題 2)列出主要問題(用自然語言或虛擬碼在主模組中重述問題) 3)編寫其餘的模組 4)根據需要進行重組和改寫
7.測試演算法
·計算機求解的目標是生成問題的特定答案
7.2 有簡單變數的演算法
1.帶有選擇的演算法(IF ;ELSE IF ;··· ;ELSE )
·到達第二個if語句的唯一條件是第一個if表示式是不真實的
2.帶有迴圈的演算法
兩種基本迴圈:計數迴圈;事件迴圈
1’計數控制迴圈(Set count to 初始值;WHILE(條件);Set count to 表示式;···)
·使用一個特殊的變數叫做迴圈控制變數(loop control variable)
·第一部分是初始化;第二部分是測試;第三部分是增量
·while迴圈稱為前測試迴圈(pretest loop),因為迴圈開始前就測試了
·永遠不會終止的迴圈叫做無限迴圈(infinite loop)
2’事件控制迴圈
·迴圈中重複的次數是由迴圈體自身內發生的事件控制的迴圈稱為事件控制迴圈
·使用while語句實現迴圈的三個部分:事件必須初始化;事件必須被測試;事件必須被更新
·巢狀結構(nest structure):控制結構嵌入另一個控制結構的結構,又稱為巢狀邏輯(nested logic)
3.平方根
·絕對值:abs(epsilon)
·猜測的平方與原始值的差距在0.001之前,則這個值足夠好
Read in square
Set guess to square/4
Set epsilon to 1
WHILE (epsilon>0.001)
Calculate new guess
Set epsilon to abs(square-guess*guess)
Write out square and the guess
·抽象步驟(abstract step):季節仍未明確的演算法步驟
·具體步驟(concrete step):季節完全明確的演算法步驟
7.3 複雜變數
·引用中的字母叫做字串,儲存一個字串,所需位置數量取決於字串字元的數量
1.陣列
·陣列是同構專案的有名集合
·專案在集合中的位置叫做索引
·與陣列相關的演算法:搜尋(搜尋陣列的項,一次找一個特定的值)、排序(按順序放入陣列)、處理(對陣列中的項所做的所有其他計算)
2.記錄
·記錄是異構專案的有名集合,可以通過名字單獨訪問其中的專案
·異構指集合中的元素可以不必相同
7.4 搜尋演算法
1.順序搜尋(Set position to 0;Set found to FALSE;WHILE (條件);IF (條件);Set found to TRUE;ELSE;Set position to 表示式
·布林操作符包括特殊操作符AND、OR、NOT
2.有序數列中的順序搜尋
·在有序數列中查詢數字
3.二分檢索
·二分檢索(binary search):在有序列表中查詢專案的操作,通過比較操作排除大部分檢索範圍
·陣列必須是有序的
·如果陣列是有序的,已經排好,且其中的專案超過20個,使用二分檢索更好
7.5 排序
1.選擇排序(Set ··· to ···;WHILE(條件);IF(條件);Set ··· to ··· )
·選出第一個,在從剩下的裡找出第二個,以此類推
·選擇排序演算法不能確定陣列是有序的,一定要執行整個演算法
2.氣泡排序
·氣泡排序也是一種選擇排序法,只是在查詢最小值時採用了不同的方法。它從陣列的最後一個元素開始,比較相鄰的元素對,如果下面的元素小於上面的元素,就交換這兩個元素的位置
3.插入排序
·current就是元素插入有序數列的元素
7.6 遞迴演算法
·當在一個演算法中使用它自己時,這樣的演算法被稱為遞迴演算法,也就是說,如果在某種程度上呼叫自己,則這個呼叫稱為遞迴呼叫
·遞迴(recursion):演算法呼叫它本身的能力,是另一種重複(迴圈)的
·每個遞迴演算法至少有兩種情況:基本情況(答案已知的情況)和一般情況(呼叫自身來解決問題的更小版本的解決方案)
·有遞迴解決方案的第一步都是確定尺寸係數
·使用遞迴演算法時,每次執行演算法提供給演算法的資料值必須是不同的。因此,繼續遞迴之前前,先要了解一個新的控制結構:子程式語句
1.命名程式碼出現的地方叫呼叫單元
2.遞迴階乘
·Factorial(N) = N*Factorial(N-1)
·每次呼叫 Factorial 時N都會減小,每次給出的資料稱為引數
·子程式將不斷地呼叫自身,直到執行時間支援系統耗盡了記憶體為止的情況叫無限遞迴(與無限迴圈等價)
3.遞迴二分檢索
4.快速排序
·基本策略是分治法
·這種策略的基礎是遞迴,即每次對一堆試卷排序,都要把它分成兩小堆(較小的情況)然後分別對每一小堆試卷應用同樣的方法
·永遠不要重複造輪子
·如果問題陳述邏輯上分為兩種情況(基本情況、一般情況),則遞迴是一種可行的選擇
7.7 幾個重要思想
1.資訊隱蔽
·資訊隱蔽(information hiding): 隱蔽模組的細節以控制對這些細節的訪問的做法
2.抽象
·抽象( abstraction)和資訊隱蔽就像一個硬幣的兩面:資訊隱蔽是隱藏細節的做法,抽象是隱藏細節背後的結果
3.事物命名
·給資料和過程的名字叫作識別符號
4.測試
·測試分類:白盒測試和黑盒測試