20145201 《信息安全系統設計基礎》第3周學習總結

20145201 《信息安全系統設計基礎》第3周學習總結

教材學習內容總結

三種最重要的數字表示:html

  • 無符號
  • 補碼
  • 浮點數
    運算:linux

  • 整數運算
  • 浮點運算git

整數運算和浮點運算不一樣:程序員

整數運算只能編碼相對較小的範圍,可是是精確的;編程

浮點運算能夠編碼一個較大的範圍,可是是近似的;浮點運算不可結合。數組

注意:溢出——運算位數的限制安全

從逆向角度考慮爲何會產生漏洞
大量計算機漏洞都是因爲算數運算的微妙細節引起的。好比無符號數、有符號數、浮點數的侷限性;無符號數或者有符號數的表示範圍有限,而浮點數雖然編碼範圍大,可是不精確。函數

信息存儲

1.十六進制表示法學習

經常使用進制:二進制(B),十進制(D),八進制(O或者Q),十六進制(H)編碼

轉換爲二進制-十六進制相互轉換,二進制的四位數字對應十六進制的一位數字。

同理,二進制與八進制的轉化是三位對應一位。

tips:拿二進制做中間結果就好轉了

當 n 表 示 成 i + 4 j 的 形 式 , 其 中 0 ≤ i ≤ 3 時 , 我 們 可 以 把 x 寫 成 開 頭 的 十 六 進 制 數 字 爲 1( i = 0 )、2( i = 1 )、 4(i=2)或者 8(i=3)

2.字

字長決定虛擬地址空間的最大大小。字長爲w,虛擬地址的範圍爲0~(2^w-1)

3.數據大小

gcc -m32 能夠在64位機上生成32位的代碼

4.尋址和字節順序

1).小端法和大端法

小端法:最低有效字節在前面——「高對高,低對低」
大端法:最高有效字節在前面

2).強制類型轉換

書28頁代碼

5.布爾代數

經常使用運算符號:

與: &
或: |
非: ~
異或:^

位向量

位向量:有固定長度爲w、由0和1組成的串。
位向量的應用——表示有限集合。
布爾運算 | 和 & 分別對應於集合的並和交,而 ~ 對應于于集合的補。

6.位級運算

位運算:位向量按位進行邏輯運算,結果還是位向量(區別於邏輯運算)
常見用法:掩碼——用來選擇性的屏蔽信號

位級表達式
位級表達式的計算,要將經過轉化爲二進制表示進行二進制運算再轉換回原來的進制來進行。

~0:生成一個全1的掩碼。

7.邏輯運算

邏輯運算的計算方法:
全部非零參數都表明TRUE,0參數表明FALSE

邏輯運算的結果:
1-表明TRUE,或者,0-表明FALSE

邏輯運算和位運算的區別:

  • 只有當參數被限制爲0或1時,邏輯運算才與按位運算有相同的行爲。
  • 若是對第一個參數求值就能肯定表達式的結果,邏輯運算符就不會對後面的參數求值。

8.移位運算

通常而言,機器支持兩種形式的右移:邏輯右移和算術右移。邏輯右移在左端補k個 0,算術右移是在左端補k個最高有效位的值。

C 語言標準並無明肯定義應該使用哪一種類型的右移。對於無符號數據(也就是以限定詞 unsigned 聲明的整型對象),右移必須是邏輯的。而對於有符號數據(默認的聲明的整型對 象),算術的或者邏輯的右移均可以。

幾乎全部的編譯器 / 機器組合都對有符號數據使 用算術右移,且許多程序員也都假設機器會使用這種右移。

另外一方面,Java 對於如何進行右移有明確的定義。表達式 x>>k 會將 x 算術右移 k 個位置, 而 x>>>k 會對 x 作邏輯右移。

整數表示

1.整型數據類型
整型數據類型——表示有限範圍的整數,每種類型都能用關鍵字來指定大小,還能夠指定是非負數(unsigned)仍是負數(默認)。這些不一樣大小的分配的字數會根據機器的字長和編譯器有所不一樣。

要用C99中的「long long」類型,編譯是要用 gcc -std=c99

2.無符號數的編碼
注意無符號數的二進制表示的一個重要性質:每一個介於0~2^w-1之間的整數都有惟一一個w爲的值編碼,函數爲一個雙射。

即0-(2^w)-1中的每個整數和長度爲w的位向量是一一對應的。

3.補碼編碼(有符號數的編碼)

關於補碼:將字的最高有效位解釋爲負權。
有符號數的其餘表示方法:
原碼
反碼

4.有符號數和無符號數的轉換

強制類型轉換

從位級角度考慮。

強制類型轉換的結果保持位值不變,只是改變了解釋這些位的方式。即:這些位上的值不變,可是因爲最高有效位的權重發生變化,從而致使結果發生改變。

5.c語言中的有符號數和無符號數及其轉換

轉換原則:底層的位保持不變。

6.擴展一個數字的位表示

擴展——從一個較小的數據類型轉換爲較大的數據類型,同時保持數值不變。

1).零擴展

將一個無符號數轉換爲一個更大的數據類型。只需在開頭加上0便可。

2).符號擴展

將一個補碼數字轉換爲一個更大的數據類型。最高有效位是什麼,就添加什麼。

7.截斷數字

不用額外的位來擴展數值,而是減小表示一個數字的位數。而這麼作可能會改變它的值,這也是溢出的一種形式。

將一個w位的數截斷爲k位數字時,就會丟棄高w-k位。

對於無符號數x來講,截斷它到k位的結果就至關於計算 xmod (2^k)

對於有符號數來講,先按照無符號數截斷,而後再轉化爲有符號數。

整數運算

1.無符號加法 本質上就是模運算,mod 2的w次冪。

考慮兩個非負整數x和y,知足0≤x, y≤2w-1。每一個數都能表示爲w位無符號數字。然而,若是計算它們的和,咱們就有一個可能的範圍0≤x + y≤2w+1-2。表示這個和可能須要w + 1位。這種持續的「字長膨脹」意味着,要想完整地表示算術運算的結果,要對字長作限制。

算數運算溢出:一個算術運算溢出,是指完整的整數結果不能放到數據類型的總長限制中去。

2.補碼加法

兩個數的w位補碼之和與無符號之和有徹底相同的位級表示。

溢出

補碼加法的溢出狀況比無符號運算更爲複雜,分爲正溢出、正常、負溢出。正溢出就是超過正數的最大範圍,負溢出就是超過負數的最大範圍。

但本質仍然是模運算,模掉w位的補碼最高有效位的權重2的w次冪。

3.補碼的非
(1)補碼的非運算

4.無符號乘法
範圍在0≤x, y≤ 2w-1內的整數x和y能夠表示爲w位的無符號數,可是它們的乘積x · y的取值範圍爲0到(2w-1)2 = 22w-2w+1+1之間。這可能須要2w位來表示。不過,C語言中的無符號乘法被定義爲產生w位的值,就是2w位的整數乘積的低w位表示的值。能夠看做等價於計算乘積模2w。

5.補碼乘法
c語言中的有符號乘法是經過將2w位的乘積截斷爲w位的方式實現的。也就是說,須要mod 2的w次冪。
因此,對於無符號和補碼乘法來講,乘法運算的位級表示都是同樣的。

6.乘以常數

在機器運算中,乘法老是很慢的,而加法和移位(左移)是相對較快的。因此在編譯器中,會使用移位和加法運算組合的方式來代替乘以常數因子。這種方法對於無符號運算和補碼運算都是適用的。

7.除以2的冪

機器運算中,除法比乘法更慢。當被除數爲2的整數次冪時,經過右移來解決。右移時須要區分無符號數和補碼。

須要注意:整數除法老是舍入到零

1).無符號數——邏輯右移

無符號數除以2的k次冪,就等同於對其邏輯右移k位。

2).補碼——算術右移

補碼進行算術左移時,須要考慮補碼數的正負,由於整數除法老是舍入到零,無符號數中沒有負數沒必要擔憂,但補碼中有正有負,正數向下舍入到零,負數應該向上舍入到零。因此這裏涉及到在移位前偏置。
也就是說:

x≥0時,除以2的k次冪等價於將x算術右移k位
x<0時,先將x加上(2^k)-1,再算術右移k位
與乘法不一樣,這種右移方法不能推廣到任意常數C。

八、整數運算的總結

計算機執行的「整數運算」其實是一種模運算。
不管運算數是以無符號形式仍是補碼形式表示,都有徹底同樣或者很是相似的位級行爲。
謹慎使用unsigned數據類型,極可能會形成漏洞。

浮點數

浮點表示對形如V=x X (2^y)的有理數進行編碼,對執行:
很是大的數字
很是接近於0的數字
做爲實數運算的近似值
頗有用

一、二進制小數

小數的二進制表示法只能表示那些可以被寫成x X (2^y)的數,其餘的值只能近似的表示。

權重:
以小數點爲界,
左邊第i位,權重爲2的i次冪
右邊第i位,權重爲2的-i次冪

二、IEEE浮點表示

IEEE浮點標準用V=(-1)^s ×M× 2^E 來表示一個數:
符號:s決定這個數是正仍是負。0的符號位特殊狀況處理。
階碼:E對浮點數加權,權重是2的E次冪(可能爲負數)
尾數:M是一個二進制小數,範圍爲1~2-ε或者0~1-ε(ε=1/2的n次冪)

編碼規則:
單獨符號位s編碼符號s,佔1位
k位的階碼字段exp編碼階碼E
n位小數字段frac編碼尾數M(同時須要依賴階碼字段的值是否爲0)

兩種精度:
單精度(float),k=8位,n=23位,一共32位;
雙精度(double),k=11位,n=52位,一共64位。

三種被編碼狀況:(p70)
規格化的
非規格化的
特殊值

  • 規格化的值
    當exp的位模式既不全爲0(數值0),也不全爲1(單精度數值爲255,雙精度數值爲2047)時,都屬於這類狀況。在這種狀況中,階碼字段被解釋爲以偏置(biased)形式表示的有符號整數。也就是說,階碼的值是E = e-Bias,其中e是無符號數,其位表示爲ek-1…e1e0,而Bias是一個等於2k-1-1(單精度是127,雙精度是1023)的偏置值。由此產生指數的取值範圍,對於單精度是-126~+127,而對於雙精度是-1022~+1023。

  • 非規格化的值
    當階碼域爲全0時,所表示的數就是非規格化形式。在這種狀況下,階碼值是E = 1 - Bias,而尾數的值是M = f,也就是小數字段的值,不包含隱含的開頭的1。非規格化值要這樣設置偏置值的緣由是使階碼值爲1-Bias而不是簡單的-Bias彷佛是違反直覺的。咱們將很快看到,這種方式提供了一種從非規格化值平滑轉換到規格化值的方法。

(1)階碼

階碼E = 1-Bias

(2)尾數

尾數M = f(小數字段的值,不包含隱含的1)

(3)非規格化的功能:

提供了一種表示數值0的方法
表示那些很是接近零的數。逐漸溢出。

  • 特殊值

特殊值是在階碼位全爲1的時候出現的。當小數域全爲0時,獲得的值表示無窮,當s = 0 時是+∞,或者當 s = 1時是-∞。當咱們把兩個很是大的數相乘,或者除以零時,無窮可以表示溢出的結果。

3.舍入

由於表示方法限制了浮點數的範圍和精度,浮點運算只能近似地表示實數運算。所以,對於值x,咱們通常想用一種系統的方法,可以找到「最接近的」匹配值x',它能夠用指望的浮點形式表示出來。

IEEE浮點格式定義了四種不一樣的舍入方法:

  • 向偶舍入(默認方法)

即:將數字向上或向下舍入,是的結果的最低有效數字爲偶數。

能用於二進制小數。

  • 向零舍入

即:把整數向下舍入,負數向上舍入。

  • 向下舍入

正數和負數都向下舍入。

  • 向上舍入

正數和負數都向上舍入。

默認的(即向偶舍入)方法能夠獲得最接近的匹配,其他三種可用於計算上界和下界。

四捨六入,五求偶。

4.浮點運算

IEEE標準指定了一個簡單的規則,用來肯定諸如加法和乘法這樣的算術運算的結果。把浮點值x和y當作實數,而某個運算⊙定義在實數上,計算將產生Round (x ⊙ y),這是對實際運算的精確結果進行舍入後的結果。當參數中有一個是特殊值(如-0、-∞或NaN)時,IEEE標準定義了一些使之更合理的規則。例如,定義1/-0將產生-∞,而定義1/+0會產生+∞。

浮點加法不具備結合性,這是缺乏的最重要的羣屬性。
浮點加法知足了單調性屬性:若是a≥b,那麼對於任何a、b以及x的值,除了NaN,都有x + a ≥ x + b。無符號或補碼加法不具備這個實數(和整數)加法的屬性。
對於任何a、b和c,而且a、b和c都不等於NaN,浮點乘法知足下列單調性:

五、c語言中的浮點數

全部的C語言版本提供了兩種不一樣的浮點數據類型:float和double。在支持IEEE浮點格式的機器上,這些數據類型就對應於單精度和雙精度浮點。
較新版本的C語言,包括ISO C99,包含第三種浮點數據類型long double。對於許多機器和編譯器來講,這種數據類型等價於double數據類型。不過對於Intel兼容機來講,GCC用80位「擴展精度」格式來實現這種數據類型,提供了比標準64位格式大得多的取值範圍和精度。

int、float、double相互轉換

int → float 不會溢出但有可能捨入
int/float → double 結果保留精確數值
double → float 可能溢出爲±∞,因爲精確度較小也有可能被舍入
float/double → int 向零舍入,可能溢出。

教材學習中的問題和解決過程

p48怎麼樣讓負數等於正數?
由練習題2.21在負數x後加上U,可使其轉換爲(2^w+x)

課後做業中的問題和解決過程

(p35)2.13
問題:假設有兩個函數bis和bic來實現位設置和位清除操做;只利用這兩個函數實現按位 | 和^操做。

int bis(int x, int y);
int bis(int x, int y);

int bool_or(int x,int y)
{
    int result = bis(x,y);
    return result;
}
int bool_xor(int x,int y)
{
    int result = bis(bic(x,y),bic(y,x));
    return result;
}

解答: x^y = (x&~y) | (~x&y)知識點要掌握

問題:(p51)2.23

#include<stdio.h>
int fun1(unsigned word)
{
    return (int)((word<<24)>>24);
}
int fun2(unsigned word)
{
    return ((int)word<<24)>>24;
}

解決:
fun1()將word進行邏輯左移和右移後的結果轉換爲int型;
fun2()是將word先強制轉換爲int型,再進行的算數左移和右移。

w:0x87654321 fun1(w)=0x00000021,fun2(W)=0x00000021 (先進行左移即右側六個十六進制位補f,以後右移的時候,由於最高有效位是0,因此前側六個十六進制位補0)

(p52)2.25

解決:

以正常的浮點數數組輸入,獲得正常結果,可是輸入0時有報錯,如圖:

解釋:緣由應該在「i<=length-1」與以前聲明的「unsigned length」的矛盾中。由於當輸入的length是0時,length-1=0-1(無符號數運算),即模數加法,獲得的是Umax。而任何數都是小於Umax的,因此比較式恆爲真。則循環會訪問數組a中的非法元素。簡單的處理辦法就是將length聲明爲int型

本週代碼託管截圖

代碼連接

其餘(感悟、思考等,可選)

此次以書上第二章內容爲主,按照老師羅列的重點一一學習。關於這章的內容,不少知識都是看起來很熟悉,咱們都曾學習過或者接觸過,重點仍是須要應用到實踐中,都須要練習。這周主要看的是練習題,對於枯燥的文字知識,仍是題目解答能讓咱們理解更深入,更明確。但在作題過程當中,公式也是很重要的,也須要翻回頭重點看相關公式。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 100/100 2/2 25/25 安裝了虛擬機並學習掌握核心的linux命令
第二週 100/200 1/3 30/55 虛擬機上的C語言編程
第三週 150/350 1/4 10/65 計算機中信息的表示和運算

參考資料

相關文章
相關標籤/搜索