1 編程語言的發(fā)展史
1.1 機器語言
??計算機的硬件作為一種電路元件揭芍,它的輸出和輸入只能是有電或者沒電,也就是所說的高電平和低電平透绩,所以計算機傳遞的數(shù)據(jù)是由“0” 和“1”組成的二進制數(shù)深寥,所以說二進制的語言是計算機語言的本質。計算機發(fā)明之初,人們?yōu)榱巳タ刂朴嬎銠C完成自己的任務或者項目,只能去編寫“0”压储、“ 1”這樣的二進制數(shù)字串去控制電腦,其實就是控制計算機硬件的高低電平或通路開路源譬,這種語言就是機器語言集惋,例如下面的0、1代碼就分別代表了四則運算:
加:0100 0000
減:0100 1000
乘:1111 0111 1110 0000
除:1111 0111 1111 0000
??直觀上看瓶佳,機器語言十分晦澀難懂芋膘,其中的含義往往要通過查表或者手冊才能理解鳞青, 使用的時候非常痛苦霸饲,尤其當你需要修改已經(jīng)完成的程序時,這種看起來無序的機器語言會讓你無從下手臂拓,也很難找到程序的錯誤厚脉。而且,不同計算機的運行環(huán)境不同胶惰,指令方式操作方式也不盡相同傻工,所以當你在這種機器語言就有了特定性,只能在特定的計算機上執(zhí)行孵滞,而一旦換了機器就需要重新編程中捆,這極大的降低了程序的使用和推廣效率。但由于機器語言具有特定性坊饶,完美適配特定型號的計算機泄伪,故而運行效率遠遠高過其他語言。機器語言匿级,也就是第一代編程語言蟋滴。
1.2 匯編語言
??因此染厅,為了解決以上種種難題,匯編語言就此營運而生津函,匯編語言(Assembly Language)是任何一種用于電子計算機肖粮、微處理器、微控制器或其他可編程器件的低級語言尔苦,亦稱為符號語言涩馆。在匯編語言中,用助記符代替機器指令的操作碼蕉堰,用地址符號或標號代替指令或操作數(shù)的地址凌净。在不同的設備中,匯編語言對應著不同的機器語言指令集屋讶,通過匯編過程轉換成機器指令冰寻。特定的匯編語言和特定的機器語言指令集是一一對應的,不同平臺之間不可直接移植皿渗。
??例如斩芭,四則運算在匯編語言中的表現(xiàn)如下形式:
加:INC EAX 對應的機器語言: 0100 0000
減:DEC EAX 對應的機器語言: 0100 1000
乘:MUL EAX 對應的機器語言:1111 0111 1110 0000
除:DIV EAX 對應的機器語言:1111 0111 1111 0000
1.3 高級語言
??在編程語言經(jīng)歷了機器語言,匯編語言等更新之后乐疆,人們發(fā)現(xiàn)了限制程序推廣的關鍵因素——程序的可移植性划乖。需要設計一個能夠不依賴于計算機硬件,能夠在不同機器上運行的程序挤土。這樣可以免去很多編程的重復過程琴庵,提高效率,同時這種語言又要接近于數(shù)學語言或人的自然語言仰美。在計算機還很稀缺的50年代迷殿,誕生了第一個高級編程語言。當時計算機的造價不菲咖杂,但是每天的計算量又有限庆寺,如何有效的利用計算機有限的計算能力成為了當時人們面對的問題。同時诉字,因為資源的稀缺懦尝, 計算機的運行效率也成為了那個年代工程師追尋的目標。為了更高效的使用計算機壤圃,人們設計出了高級編程語言陵霉,來滿足人們對于高效簡潔的編程語言的追求。
例如:C\C++\Java\OC\Swift伍绳,更加接近人類的自然語言
比如C語言:
加:A+B 通過編譯器 0100 0000
減:A-B 通過編譯器 0100 1000
乘:A*B 通過編譯器 1111 0111 1110 0000
除:A/B 通過編譯器 1111 0111 1111 0000
??我們的代碼在終端設備上是這樣的過程:
其中:
- 匯編語言與機器語言一一對應踊挠,每一條機器指令都有與其對應的匯編指令。
- 匯編語言可以通過編譯得到機器語言墨叛,機器語言也可以通過反匯編得到匯編語言止毕。(針對特定平臺上的機器指令所對應的匯編指令)
- 高級語言可以通過編譯得到匯編\機器語言模蜡,但是匯編\機器語言幾乎不可能還原成高級語言。(這是因為不同的高級語言編譯后產(chǎn)生的匯編語言可以相同扁凛,同一種高級語言不同的代碼段產(chǎn)生的匯編語言也可以相同忍疾,這就造成了匯編語言反編譯成高級語言的困難。)
2 匯編語言的特點谨朝、用途及種類
2.1 特點
- 可以直接訪問卤妒、控制各種硬件設備,比如存儲器字币、CPU等则披,能最大限度地發(fā)揮硬件的功能。
- 能夠不受編譯器的限制洗出,對生成的二進制代碼進行完全的控制士复。
- 目標代碼簡短,占用內存少翩活,執(zhí)行速度快阱洪。
- 匯編指令是機器指令的助記符,同機器指令一一對應。每一種CPU都有自己的機器指令集\匯編指令集菠镇,所以匯編語言不具備可移植性冗荸。
- 知識點過多,開發(fā)者需要對CPU等硬件結構有所了解利耍,不易于編程蚌本、調試及維護。
- 不區(qū)分大小寫隘梨,比如mov和MOV是一樣的程癌。
2.2 用途
- 編寫驅動程序、操作系統(tǒng)(比如Linux內核的某些關鍵部分)出嘹。
- 對性能要求極高的程序或者代碼片段席楚,可與高級語言混合使用(內聯(lián)匯編)咬崔。
- 軟件安全税稼。
- 病毒分析與防治。
- 逆向\加殼\脫殼\破解\外掛\免殺\加密解密\漏洞\黑客垮斯。
- 理解計算機系統(tǒng)的最佳起點和最有效途徑郎仆。
- 為編寫高效代碼打下基礎。
- 弄清代碼的本質兜蠕。
2.3 種類
目前討論比較多的匯編語言有:
8086匯編(8086處理器是16bit的CPU)
Win32匯編
Win64匯編
ARM匯編(嵌入式扰肌、Mac、iOS)
??我們iPhone里面用到的是ARM匯編熊杨,但是不同的設備也有差異曙旭,因CPU的架構不同盗舰,如下圖所示:
3. 學習匯編語言必備基礎知識
3.1 CPU硬件結構
3.2 APP/程序執(zhí)行過程圖
其中硬件相關最為重要的是CPU以及內存,在匯編指令集中桂躏,大部分指令都是直接對CPU以及內存進行操作的钻趋。
3.3 總線
3.3.1 總線的工作流程
??總線其實就是一根根導線的集合,分為:地址總線剂习、數(shù)據(jù)總線以及控制總線蛮位。
當CPU需要從內存中讀寫數(shù)據(jù)的時候,通過控制總線傳入讀寫內存數(shù)據(jù)的操作命令鳞绕,然后通過地址總線傳入的地址讀寫內存中相應地址的數(shù)據(jù)失仁,如果是讀操作就將獲取到的數(shù)據(jù)通過數(shù)據(jù)總線傳給CPU,如果是寫操作就將數(shù)據(jù)通過數(shù)據(jù)總線存儲到地址總線所記錄的內存的地址中们何,如下圖所示:
3.3.2 地址總線
??地址總線的寬度決定了CPU的尋址能力萄焦,8086的地址總線寬度是20,所以尋址能力是1M( 2的20次方 )冤竹。也就是說內存的大小限制決定了地址總線的寬度楷扬,地址總線所讀取的內存的最大地址不能超過內存存儲數(shù)據(jù)的最大存儲總量。
3.3.3 數(shù)據(jù)總線
??數(shù)據(jù)總線的寬度決定了CPU的單次數(shù)據(jù)傳送量贴见,也就是數(shù)據(jù)傳送速度烘苹,8086的數(shù)據(jù)總線寬度是16,所以單次最大傳遞2個字節(jié)的數(shù)據(jù)片部。
3.3.4 控制總線
??控制總線的寬度決定了CPU對其他器件的控制能力镣衡、能有多少種控制。
3.4 內存
- 內存地址空間的大小受CPU地址總線寬度的限制档悠。8086的地址總線寬度為20廊鸥,可以定位220個不同的內存單元(內存地址范圍0x00000~0xFFFFF),所以8086的內存空間大小為1MB辖所。
- 0x00000~0x9FFFF:主存儲器惰说。可讀可寫缘回。
- 0xA0000~0xBFFFF:向顯存中寫入數(shù)據(jù)吆视,這些數(shù)據(jù)會被顯卡輸出到顯示器∷盅纾可讀可寫啦吧。
- 0xC0000~0xFFFFF:存儲各種硬件\系統(tǒng)信息。只讀拙寡。
3.5 進制
3.5.1 如何學習進制
??在學習會匯編的時候我們需要經(jīng)常查看指令執(zhí)行的地址授滓,以及一些二進制數(shù)據(jù),因此對于進制的學習也是非常必要的。
??我們在學習進制的時候般堆,總是以十進制為依托去考慮其他進制在孝,需要運算的時候也總是先轉換為十進制,其實這種學習方法是錯誤的淮摔,每一種進制其實都是完美的浑玛,要向學號進制首先要忘掉十進制,也要忘掉進制間的轉換噩咪。
3.5.2 進制的定義
- 八進制由8個符號組成:0 1 2 3 4 5 6 7 逢八進一
- 十進制由10個符號組成:0 1 2 3 4 5 6 7 8 9 逢十進一
- N進制就是由N個符號組成:逢N進一
??其實這些符號不一定是寫死的顾彰,可以是自己定義的,例如:什么時候1 + 1等于3呢胃碾?
??當你如此定義十進制的符號就可以做的:0 1 3 6 9 A B Q X 4 傳統(tǒng)我們定義的十進制和定義的十進制不一樣涨享,那么這10個符號如果我們不告訴別人,別人是無法知道我們這些符號具體的表示意義的仆百,這樣就可以用來加密厕隧。
3.5.3 進制的運算
- 八進制加法表
1+1 = 2
1+2 = 3 2+2 = 4
1+3 = 4 2+3 = 5 3+3 = 6
1+4 = 5 2+4 = 6 3+4 = 7 4+4 = 10
1+5 = 6 2+5 = 7 3+5 = 10 4+5 = 11 5+5 = 12
1+6 = 7 2+6 = 10 3+6 = 11 4+6 = 12 5+6 = 13 6+6 = 14
1+7 = 10 2+7 = 11 3+7 = 12 4+7 = 13 5+7 = 14 6+7 = 15 7+7 = 16 - 八進制的乘法表
11 = 1
12 = 2 22 = 4
13 = 3 23 = 6 33 = 11
14 = 4 24 = 10 34 = 14 44 = 20
15 = 5 25 = 12 35 = 17 45 = 24 55 = 31
16 = 6 26 = 14 36 = 22 46 = 30 56 = 36 66 = 44
17 = 7 27 = 16 37 = 25 47 = 34 57 = 43 67 = 52 77 = 61
3.5.4 進制的轉換
二進制:1 0 1 1 1 0 1 1 1 1 0 0
三個一組轉換為八進制:101 110 111 100
八進制: 5 6 7 4
四個一組轉換為十六進制:1011 1011 1100
十六進制: b b c
將二進制轉換為十六進制寫起來就沒那么麻煩了,因此俄周,我們經(jīng)常使用十六形式來簡寫二進制吁讨。
3.6 數(shù)據(jù)的寬度
??數(shù)學上的數(shù)字,是沒有大小限制的峦朗,可以無限的大建丧。但在計算機中,由于受硬件的制約波势,數(shù)據(jù)都是有長度限制的(我們稱為數(shù)據(jù)寬度)翎朱,超過最多寬度的數(shù)據(jù)會被丟棄。
計算機中常見的數(shù)據(jù)寬度
- 位(Bit):1個位就是1個二進制位尺铣,0或者1拴曲。
- 字節(jié)(Byte):1個字節(jié)由8個Bit組成(8位),內存中的最小單元Byte凛忿。
- 字(Word):1個字由2個字節(jié)組成(16位)澈灼,這2個字節(jié)分別稱為高字節(jié)和低字節(jié)。
- 雙字(Doubleword):1個雙字由兩個字組成(32位)店溢。