x86匯編基礎-Move指令和基本尋址

本文的立意僅僅是討論基本的x86匯編語法,。所以我要重申這里的匯編教程并不是深入研究匯編,本人也沒有那么大的能耐。學習基礎的匯編主要達到以下的程度即可。

  • 讀懂常用的運算符指令
  • 讀懂存儲和加載指令
  • 了解x86和x86_64常用的寄存器的用途。
  • 了解基本的尋址模型。

了解基本的匯編以后,有什么用?

  • 加深你對C/C++的編譯器行為和大部分內部操作大有益處
  • 讓你了解到用C/C++實現(xiàn)的高層算法在匯編層面實現(xiàn)細節(jié)。
  • 讓你更深入地了解函數(shù)棧調用的細節(jié),能夠寫出高效的代碼。

其實我這里可以提一個問題?你知道 以下簡單的語句它們在計算機底層做了寫什么操作嗎?
int *a=123; 或
double b=456;
double *pp=b;

如果你心中沒有明確的答案,請不要蠻目自信地欺騙自己C/C++的功底是如何如何地扎實.....,我自己都沒自信心敢這么說?如果你打算專職用C/C++寫算法實現(xiàn)的,那么基本的匯編功底是必須的。

之前我也寫過一篇關于x64的匯編教程提交到寄存器和系統(tǒng)調用的基本關系《匯編語言基礎:寄存器和系統(tǒng)調用》


上面的圖例是一個比較完整的示意圖,通常在IA32或x86_64中主要集中討論CPU中的寄存器與主內存的數(shù)據(jù)交換,而其他的外部寄存器不在本文的討論范圍之內。

加載與存儲

在匯編中mov指令主要用于在主內存(RAM)和寄存器之間傳輸數(shù)據(jù),按照傳遞的方向可以分為兩類

  • 加載(Load)指令:從主內存(RAM)寄存器傳輸數(shù)據(jù),以一個給定的內存地址作為參數(shù),他從內存中獲取該地址位置存儲的數(shù)據(jù),并將該數(shù)據(jù)放入寄存器
  • 存儲(Store)指令:即從寄存器中緩存的內存地址中所指向的目標位置,并將另外一個寄存器中緩存的數(shù)據(jù)保存到該目標位置,我們可以把內存看作已經(jīng)編了號的數(shù)組,而通過索引就是內存地址,通過指定的內存地址可以在特定位置中的修改內存中的數(shù)據(jù)。

IA32中的寄存器

在IA32架構中有八個寄存器,其中有6個是通用的寄存器,另外兩個是esp和ebp有特殊的用途,如你對棧有所了解的話,就知道esp是始終指向棧頂?shù)?,ebp始終指向棧底。對于EAX,EBX,ECX和EDX寄存器,也會通常使用小字節(jié)的數(shù)據(jù)類型。 例如,EAX的最低有效2字節(jié)可被視為稱為AX的16位寄存器。 AX的最低有效字節(jié)可以用作單個8位寄存器,稱為AL,而AX的最高有效字節(jié)可以用作單個8位寄存器,稱為AH。 這些名稱指的是相同的物理寄存器。 當將兩個字節(jié)的數(shù)量放入DX中時,更新將影響DH,DL和EDX的值。 這些子寄存器主要是較舊的16位版本指令集的保留。 但是,在處理小于32位(例如1字節(jié)ASCII字符)的數(shù)據(jù)時,它們有時很方便。


圖片來源于網(wǎng)絡

mov指令的長度分類

根據(jù)操作數(shù)的字長可以分為三個版本的mov指令

  • movl Source Dest : L表示可以移動4個字節(jié)
  • movw Source Dest: W表示可以移動2個字節(jié)
  • movb Source Dest: B表示可以移動1個字節(jié)

mov指令的操作數(shù)

并且在移動指令中會用到兩個操作數(shù),Source表示移動的數(shù)據(jù)源,Dest表示移動的數(shù)據(jù)最后到達的位置。
通常在x86用的比較頻繁的mov指令版本是32位的movl,這里就以 movl Source Dest為例子

mov指令的操作數(shù)通常分為三類

  • 立即數(shù)(Immediate) 可以將其視為常數(shù),和C語言的常量類似,但是以“$”為前綴,例如0x400,-500
  • 寄存器(Register)可以是以上8個整數(shù)寄存器中的其中一個,例如:“%eax”,“%edx”,當我們執(zhí)行類似“movl %eax %edx”這種情況下,eax寄存器就成為源參數(shù),而edx寄存器就成為目標參數(shù),其含義是獲取eax中的內容并存儲在edx中。
  • 內存(Memory):而內存作為操作數(shù)通常是由寄存器緩存給定的內存地址來間接去操作的,該地址占用4個字節(jié),例如(%eax),當寄存器在一個括號中,我們就說eax持有一個指向RAM中的某個位置的地址,你可以類比為類似C/C++中的指針變量,的那么 movl (%eax) %ebx 表示的是什么意思呢?你可以考慮一下表示什么意思?

mov的操作數(shù)組合

movl指令通過不同類型的操作數(shù)組合,能夠表達出不同類型的指令類型的。


mov的參數(shù)組合
  • 例如源參數(shù)是立即數(shù),而目標參數(shù)是的寄存器,即“movl $123,%eax ”表示將常量保存在寄存器eax中,等價于C/C++聲明并初始化一個變量例如
     int a=123;
    
    其實在C編譯器對每個聲明的基本數(shù)據(jù)類型的變量會映射到一個寄存器中,例如一個int類型4字節(jié),會選擇一個32位的寄存器類裝載int整數(shù)等待CPU中的運算單元(AU)處理。
  • 源參數(shù)是立即數(shù),而目標參數(shù)是一個主內存中的地址,即“movl $123,%(eax) ”表示將常量保存到eax寄存器中的存儲的內存位置所指向的內存位置,同理等價的C/C++語句如下:
    int *a=123;
    
  • 源參數(shù)是寄存器,而目標參數(shù)也是寄存器,例如“movl %edx,%eax”其實就是在寄存器之間拷貝數(shù)據(jù)。
  • 源參數(shù)是寄存器,而目標參數(shù)是內存。其實就是一種存儲類型,例如“movl %eax,(%edx)”,表示當前寄存器eax中的數(shù)據(jù)寫回主內存中的某個位置,而這個位置是由寄存器edx保存的地址所指向的。
  • 源參數(shù)是內存,而目標參數(shù)是寄存器,例如“movl (%edx),%eax”這是從內存中加載數(shù)據(jù)到eax寄存器當中。因此表示加載指令的其中一種。

可能你會想到最后一種,有從“內存”到“內存”傳遞的指令類型嗎?單一的一條指令是不可能的。只能通過兩步實現(xiàn)

  • 首先“內存”到“寄存器”例如:“movl (%edx),%eax
  • 然后“寄存器”到“內存” 例如:“movl %eax,(%ecx)

基本的內存尋址模型

間接訪問
就是“(R)”這種格式,R表示一個寄存器名稱。寄存器中保存著一個內存地址,我們用mov指令操作主內存時,只能通過使用該寄存器中的內容去實現(xiàn)對該地址指向的RAM中位置進行讀/寫操作。對于操作系統(tǒng)來說,內存其實就是一個連續(xù)的字節(jié)數(shù)組,每個字節(jié)都有對應的編號,而這個編號就是內存地址,也可以理解為該字節(jié)數(shù)組的索引。

我們用“RAM”表示主內存,那么 (R) 其實等價于 RAM[Reg[R]],

那么“movl (%edx),%eax”類似這樣的指令的含義到這里應該不用多說了吧!

移位尋址
英文名稱叫“Displacement”,這個其實就是在間接尋址表達式的基礎是加上一個有符號的整數(shù)N。在匯編中抽象的移位尋址表達式“N(R)

我們用“RAM”表示主內存,那么 N(R) 其實等價于 RAM[Reg[R]+N],

那么具體的例子就是

  • 例如 “-4(%ebp)”:表示ebp寄存器中緩存的內存地址向低地址方向移動了4個字節(jié)
  • 例如“8(%ebp)”:表示ebp寄存器中緩存的內存地址向高地址方向移動8個字節(jié)。
  • 那么像這種“movl 4(%esp),%ecx”其實就是寄存器esp的指針向高地址方向偏移4個字節(jié)后的個新的地址,從該新地址指向的內存位置獲取數(shù)據(jù)并保存到寄存器ecx。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 1.地址總線,數(shù)據(jù)總線,控制總線在哪里,它們有什么作用?答:它們都是cpu連接外部組件的線路。地址總線:地址總線A...
    MagicalGuy閱讀 1,677評論 0 1
  • Return-Oriented-Programming(ROP FTW) Author: Saif El-Sher...
    RealSys閱讀 3,527評論 0 2
  • Java原子類中CAS的底層實現(xiàn) - GoldArowana - 博客園 Java原子類中CAS的底層實現(xiàn) 從Ja...
    聽一首老歌閱讀 835評論 0 1
  • 寄存器 用于解決處理器與內存之前的數(shù)據(jù)存儲效率問題存在的。IA-32平臺寄存器核心組有下面幾種. 通用寄存器 8個...
    dodomix閱讀 1,824評論 0 0
  • 《中國式眾籌》中第四章“眾籌十一個常見問題”:先找人,還是先找場地? 對于這個問題,我認為應該先選人,后選地...
    朝夕得閑大王閱讀 375評論 0 2

友情鏈接更多精彩內容