《汇编语言》- 来自底层的较量 - 温故而知新
在學校時,可能大部分同學的入門語言都是c語言,但是往往或多或少的都會學習過匯編語言。然而那個時候的我們,覺得匯編真的是太難了,而且意義貌似也不大。
而如今,工作之后,發現一些道理,越是基礎的,越能體現你的不凡。所以,我再次打開了這本書,來回味當年的苦澀。
先做些讀后總結吧,這應該也是能快速體現獲得多少知識的表現!
一、匯編語言能干什么?僅次于機器語言?
計算機工作是由一系列的機器指令進行驅動工作的,這些指令是一系列二進制數字 0101000110,對應計算機的高低電平,而這些機器指令的集合就是機器語言,這已經是最底層,和硬件一對一了已經。
很明顯,這樣的機器語言是反人類的。只有天才和瘋子才有能力去把控他。
于是匯編語言產生了。匯編語言就是將一些難于記憶的0100100轉換為便于記憶的格式,讓人能夠稍微理解點。如 將寄存器bx的內容送到ax中,對應的機器指令是: 100001001110110000(完全不知道是啥玩意,如果真要細究,那么你就得去查看其電路連接了),而變成匯編指令后: mov ax, bx 。哈哈,是不是容易理解多了。所以,我也總結出一個道理,其實所謂的困難與簡單,真的只是相對的,沒有對比就沒有傷害!
回到前面的問題,匯編語言能干什么? 這個問題有點low了,機器語言都能干成的事,匯編都能干?但是,機器語言這么牛逼嗎?難道現在這么多高科技的東西機器語言都能干嗎?這是廢話,所有語言轉到最后,都是機器語言,沒有機器語言干不了的事,也可以說,沒有匯編干不了的事,只是咱功力不夠,哈哈!
匯編主要有三類指令:1)匯編指令(機器碼助記符,與機器指令一一對應,如果可以,其實只要這玩意你就可以操作計算機所有硬件了); 2)偽指令(沒有對應機器碼,由編譯器執行,計算機不執行,也就是說被編譯器轉換成了一組或更多的機器碼去了,現代高級語言編譯器都是干這事兒的); 3)?其他符號(如+-*/,和第二個一樣,由編譯器識別轉換)
二、要編寫匯編,有哪些基礎知識要了解?(我覺得這比語言本身更有意思)
存儲器,其作用僅次于CPU,CPU進行運算,它進行記憶。
存儲單元,內存或外存中比較小的存儲塊(因為我也不清楚是不是最小的塊,哈哈,反正默認情況下操作的都是內存塊都是它或者它的倍數)。
CPU對存儲器讀寫,需進行3步交互:定位存儲單元的地址(地址信息);選擇器件,讀或寫的命令(控制信息);對器件讀或寫的數據(數據信息)。
地址總線,地址總線的數量,決定了CPU可操作的內存最大值(這個和有的操作系統用不了很大的內存有點像,也可以解釋為什么有的手機最大只能擴展xxG內存了);
數據總線,它的寬度(數量)決定了CPU與外界的傳送速度(數據總線越寬,一次能傳送的數據量越大,速度越快)。
控制總線,它的數量決定了對外部器的控制方式數量。
了解以上這些,也算是對硬件的一些理解,及對真正代碼作用的深層次理解吧!
三、匯編所能操作的東西有哪些?(這和寫代碼還不太一樣)
寄存器,這是整個匯編操作的核心,絕大部分的操作,都是對寄存器的操作。
對于學習,我們更多的是了解原理,教科書也沒有將最新的設備拿出來為難我們。
針對8086CPU,有14個寄存器,分別為: AX, BX, CX, DX, SI, DI, SP, BP, IP, CS, SS, DS, ES, PSW.。
ABCD-X,通用寄存器,存儲一般性數據。 不過,在匯編中,CX 有個特殊功能,用于存儲 loop的循環次數。 這里的寄存器都有分高低位,H、L分別表示高低。示例:
mov ax, 11 ; 將11送入寄存器ax mov bl, 3 ; 將3送入bl寄存器 add ax, 5 ; 將ax寄存器的值加3段寄存器,注意段的概念,段最根本的來源是CPU給出的內存單元的物理地址方式決定的,8086CPU方式為(段地址x16+偏移地址=物理地址)。但是實際的段劃分是人為的概念,10000H~100FFH 可以是個段,10000H~10080H也可以是個段。
CS、IP 是最關鍵的兩個寄存器,它們指示了當前 要讀取指令的地址,CS是段地址,IP是指令指針寄存器。 CSx16+IP 就是CPU當前要執行的指令。換個通俗的話,要讓CPU執行什么命令,只要改變這兩個寄存器的值,就可以做到了。(有一種皇帝的感覺,哈哈),但是CPU不可能提供 mov cs, 11h? 等命令操作,使用jmp cs:ip 進行更改值,從而跳轉到想執行的命令處。
DS 寄存器是用于存儲數據的段地址,比如要讀取某段數據中的值,那么就要先DS指向那里的地址,再加上偏移地址 [...],就可以進行數據讀取了(ES作為附加段寄存器,與DS功能一致,在段太多的情況,可以視情況選用即可),如:
mov bx, 1000h ; 將1000h送入bx寄存器中 mov ds bx ; 將段地址指向 bx的值指定的值,mov ds, 1h 是不合法的 mov al, [0] ; 將0號內存單元的值送入al寄存器中SS, SP, BP 是棧相關寄存器。CPU提供的棧機制,這真是個偉大的發明,雖然看起來很簡單。
入棧過程
出棧過程
在語言層面表現出來就是,push, pop 兩個命令,任意時刻,SS:SP都指向棧頂元素。 push 時, SP=SP-2,pop時,如果有接收的寄存器則先將棧頂值送入,然后 SP=SP+2,指向下面一個單元。 這有什么用呢? 當然有用,它可以用來臨時保存各種數據,然后再插入功能執行完成后,進行現場的恢復,事實上,大部分時候是這么用的。
四、真正的匯編是什么樣的?(其實到這里,個人覺得已經有點近高級語言了)
大家都說,學語言都是從hello world 開始的,然而在匯編這里好像行不通,應該這太難了,哪能入門呢!入門如下:
assume cs:codesg ; 將寄存器與代碼段關聯 codesg segmentstart: mov ax, 0123h ; 寄存器送入值mov bx, 0457hadd ax, bx ; ax + bx 寄存器值相加add ax, ax ; 算 ax 的平方mov ax, 4c00hint 21h ; 程序結束返回 codesg ends end start ; 指定程序入口標號為 start? 段前綴,可以直接將某指定的跨段的內存單元讀取到。
mov ax, ds:[bx] ; 段地址在ds中,偏移地址在 bx中, ds: cs: ss: ... 等為段前綴 mov ax, cs:[bx] mov ax, ss:[bx] mov ax, es:[bx] mov ax, ss:[0] mov ax, cs:[0]一個定位代碼地址的樣例,如何定位代碼的內存地址(我覺得能夠說出某數據在內存中的位置是件很酷的事情,絕對夠你裝逼)?
assume cs:codesg ; 將寄存器與代碼段關聯,其開始地址即為cs:[0],后續地址只需要進行加減推演即可知道你想知道的代碼的內存地址了 codesg segmentdw 0123h,0456h,0789h,0987hstart: mov bx, 0add ax, 0 add cx, 4s: add ax, cs:[bx]add bx, 2loop smov ax, 4c00hint 21h codesg ends end start?
SI, DI?寄存器,它的功能與 BX寄存器 相似,但是這兩個寄存器無法分成兩個8位的寄存器,即不能像 BX 可分成 BH BL一樣,SI/DI不能分成 SH SL。SI是源變址寄存器,DI是目的變址寄存器。在串處理指令中,SI用作隱含的源串地址,默認在DS中;DI用做隱含的目的串地址,默認在ES中;此時不能混用。
BP: 是和堆棧指針SP聯合使用的,作為SP校準使用的,只有在尋找堆棧里的數據和使用個別的尋址方式時候才能用到比如說,堆棧中壓入了很多數據或者地址,你肯定想通過SP來訪問這些數據或者地址,但SP是要指向棧頂的,是不能隨便亂改的,這時候你就需要使用BP,把SP的值傳遞給BP,通過BP來尋找堆棧里數據或者地址.
PSW?寄存器,標志寄存器,存儲各種運算狀態標志,配合運算類型進行相應取舍,從而得到相關需要的結果。比如,機器中沒有正負,只有標志。下圖中空白位為未使用的標志位,也可以從另一個層面來說,標志位不在多,在精。
OF(11位-overflow flag-溢出標志位)
DF(10位-direction flag-方向標志位)
IF(9位-interrupt flag-中斷標志位)
TF(8位-trap flag-陷阱標志位)
SF(7位-sign flag-負號標志位)
ZF(6位-zero flag-零值標志位)
AF(4位-auxiliary carray flag-輔助進位標志位)
PF(2位-parity flag-奇偶標志位)
CF(0位-carry flag-進位標志位)
使用pushf, popf 進行標志狀態的暫存。
五、另一個層面的功能?(創世紀的功能)
中斷。使用中斷,可以使CPU能放下當前的工作,轉而去處理中斷的請求,處理完成后,繼續回到這里繼續執行。中斷的功能舉足輕重啊!
內中斷。BIOS中斷全程例程。
int n 可以指定中斷號。 中斷向量表保存了中斷源對應的處理程序的入口。使用iret返回中斷之前的位置。
CPU與外部器件之間通信使用端口。
in al, 20h ; 從20h端口中讀入一個字節 out 20h, al ; 往20h端口定稿一個字節CMOS RAM芯片。
外中斷。隨時接收外設輸入的到達,即通過中斷機制來完成。中斷是偉大的!
?
匯編還是有好些編程技巧,但是本文并沒有講許多語言層面的東西。因為,越是技巧性性的東西,我覺得現代的語言已經夠多了,咱也沒必要在匯編上去花費太多功夫。
了解匯編,不是想用來寫什么牛逼的功能,而是讓自己更清楚的明白自己在做的是什么事情。
我覺得有必要好好了解!
轉載于:https://www.cnblogs.com/yougewe/p/8011911.html
總結
以上是生活随笔為你收集整理的《汇编语言》- 来自底层的较量 - 温故而知新的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 优达学城数据分析笔记1--------数
- 下一篇: 将前端文件和Go程序打包