匯編語言1:基礎知識


  這個假期開始系統學習匯編語言,采用跟隨視頻教程的方式,所用教程是網易雲課堂中的《匯編語言從0開始》,講者是workWork。該課程一共有167個課時,每個課時從幾分鍾到十幾分鍾不等,時間不長,短小精悍,反饋及時,讓人有動力一直看下去。這門課程很適合零基礎的同學,因為在正式編程前,講者用了大量時間講述基礎性的知識,包括二進制十進制十六進制、CPU執行指令的過程、寄存器的講解、棧的使用等等。我個人認為,即使你已經不算零基礎了,認真地看完這些課程,鞏固一下基礎知識也是必要的。我之前看過一本基於Linux的教材,因為Linux采用的是AT&T風格,與DOS/Windows的Intel風格有很大差異,所以即使也寫過幾個匯編小程序,但始終覺得對於寄存器、指令/數據長度以及棧的概念懵懵懂懂,基礎並沒有打好。我建議大家如果是初學者,還是先從DOS/Windows平台的匯編開始學習比較好,尤其是要使用Windows XP中的debug程序反復練習,這樣可以在編程之前打好堅實的基礎。
  下面對編程之前的基礎知識做一個小小的總結。

一、十進制、二進制和十六進制

       二進制之所以重要,是因為整個計算機體系就是建立在二進制的基礎上的,實際上所有的指令和數據在計算機中存儲和運算的形式就是二進制。十六進制之所以重要,是因為查看內存中的指令和數據時,是以十六進制顯示的。一個十六進制數字,實際上相當於四個二進制數字的表示。這方面需要掌握以下幾個知識點:
  • 十進制與二進制的相互轉換/快速轉換
  • 十進制與十六進制的的相互轉換/快速轉換
  • 十六進制與二進制的相互轉換/快速轉換

  基礎的相互轉換就不說了,即使對於初學者也應該是容易掌握的。說一下快速轉換的方法。

  1. 十進制快速轉換成二進制

  首先對於二進制來說,位於最末一位的1表示加1,右數第二位表示加2,依次類推為4、8、16、32、64。對於100以內的十進制數,只能是由以上幾個數字相加得成。那么我們就可以開始湊了。比如98,可以寫成64+32+2,再把對應位置為1,即1100010。
  1. 十進制快速轉換成十六進制

  這個方法只能用在小於256的數。很簡單,先用該數除以16,得到一個結果和一個余數。比如81=5*16+1,則十六進制表示為51H。
  1. 十六進制和二進制的快速轉換

  上文說過一個十六進制數字可以由四個二進制數來表示,比如7EH,就是把7用二進制表示,E用二進制表示,即0111 1110。反之亦然,二進制轉換成十六進制時,每四個數字划分即可。
  最后,記住一個式子:
  字節byte = 2個十六進制數字 = 8個二進制數字 = 8比特bit

二、CPU、寄存器和指令執行

  1. 地址信息、數據信息和控制信息

  6個小題,掌握了就可以了。
          (1)1個CPU的尋址能力為8KB,那么它的地址總線寬度為  13
          8KB = 8*1024字節,總共是2的13次方
          (2)1KB的存儲器有 1024 個存儲單元,存儲單元的編號從 0 到 1023
          (3)1KB的存儲單元可以存儲 1024*8 bit,1024  Byte 
          (4)1GB, 1MB, 1KB 分別是        2^30    2^20   2^10    Byte
          (5)地址線有16根,尋址能力為64KB,20根,1MB,24根,16MB,32根,4GB
          (6)數據線有8根,一次可以傳送數據為1Byte,16根,2Byte,32根,4Byte
  1. 寄存器

          (1)通用寄存器

  ax = ah + al
  bx = bh + bl
  cx = ch + cl
  dx = dh + dl
  一般用來存放數據,對於ax來說,能表示最大值為FFFFH,即0-66535。ax是16位,AH是8位,ah最大可表示FFH,即0-255。對於ax存放的數據是一個字,即兩個字節。而一個地址當中只能存放一個字節,即1個字需要2個地址連續的內存單元存放,高位地址存放高位字節,低位地址存放低位字節

          (2)用於表示地址的寄存器

  段地址:偏移地址
  ds            si
  es            di
  ss            bp
  cs            ip
      sp
      bx
  物理地址 = 基礎地址 + 偏移地址
  基礎地址 = 段地址 * 16(10H)
  其中cs:ip表示讀取指令的地址,ds 是段寄存器,一般以ds:[0]的形式表示要使用的數據所在的地址。
  1. 指令執行

  讀取指令的地址為cs:ip。

          (1)指令執行的過程:

  ①CPU從cs:ip所組成的地址中讀取指令,將這個指令存放在指令緩存器中;
  ②ip = ip + 所讀指令的字節數;
  ③執行指令緩存器中的內容,回到步驟1,重復這個過程。

          (2)指令執行要完成的任務:

  ①數據在什么位置?
  ②處理數據;
  ③把處理過后的結果儲存起來。

三、debug指令

          r 顯示寄存器內容
          d 顯示內存中的內容
               段地址:偏移地址 - 偏移地址
          u 將內存中內容翻譯成匯編指令
          a 向當前內存中寫指令(匯編指令)
          e 加上段地址:偏移地址,即向當前內存中寫入內容(16進制)

四、棧

  棧就是一段連續的內存空間,遵循后進先出的准則。棧的操作有兩個,分別是入棧和出棧。棧的地址由ss:sp表示。入棧指令是push加地址,出棧指令是pop加地址。注意push和pop指令后加的地址是待入棧數據的地址/出棧后數據存放的地址。ss:sp永遠指向棧頂數據,可以由程序員修改決定。注意使用棧時一定要防止越界。
  push -> SP - 2 -> SS:SP 字型數據存入
  pop   ->  SS:SP字型數據取出 ->  SP - 2

五、基本的匯編指令

  1. 移動指令

          mov 寄存器,數據
          mov 寄存器,寄存器
          mov 寄存器,內存單元
          mov 內存單元,寄存器
          mov 段寄存器,寄存器
          mov 寄存器,段寄存器
  1. 運算指令

          add 寄存器,數據
          add 寄存器,寄存器
          add 寄存器,內存單元
          add 內存單元,寄存器
          sub
  1. 轉移指令

          轉移指令能夠修改ip或cs,例如jump 2000:0,實際上就是把cs改成2000,ip改成0,那么下一條指令就是從2000:0開始執行。

六、編程前的總結

  1. 關於寄存器與地址表示

          CS:IP   和指令有關
          DS:[0] [1] …  和數據有關
          SS:SP  臨時性數據(棧)
  1. 關於指令執行的過程

          通過匯編指令修改CPU中寄存器中的內容。需要考慮的問題有:
          (1)數據在哪里?
          (2)數據的長度:字節型數據 字型數據    AX BX CX DX   AH AL BH BL
          (3)數據的處理    ADD    SUB
          (4)數據存放到哪里?
  1. 關於程序員的工作

          數據是我們程序自己安排,存放在哪里也要自己安排,指令在哪里也要自己安排——相比高級語言,匯編語言給程序員絕對的自由,然而自由的代價是謹慎,匯編語言比高級語言更容易出現種種問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM