彙編(二) -- 寄存器

前言

最近準備學習彙編,而後在B站上看到叫iOS小賢的做者發的視頻挺不錯,打算跟着學,文章是看視頻的筆記,最後有原視頻連接,想看視頻的能夠看看經過連接查看視頻。程序員

寄存器

2990730-13132bfb35556f63.png

  1. 內部部件之間由總線鏈接
  2. 對程序員來講,CPU中最主要部件是寄存器,能夠經過改變寄存器的內容來實現對CPU的控制
  3. 不一樣的CPU,寄存器的個數、結構是不相同的(8086是16位結構的CPU)

通用寄存器

  • ARM64擁有有31個64位的通用寄存器 x0 到 x30,這些寄存器一般用來存放通常性的數據,稱爲通用寄存器(有時也有特定用途)xcode

    • 那麼w0 到 w28 這些是32位的. 由於64位CPU能夠兼容32位.因此能夠只使用64位寄存器的低32位.
    • 好比 w0 就是 x0的低32位!

    模擬器是X86架構,因此用真機測才能看到ARM62的寄存器緩存

屏幕快照 2019-08-04 下午2.18.31.png

  • 一般,CPU會先將內存中的數據存儲到通用寄存器中,而後再對通用寄存器中的數據進行運算
  • 假設內存中有塊紅色內存空間的值是3,如今想把它的值加1,並將結果存儲到藍色內存空間

2990730-853a43b3fc5f733e.png

  • CPU首先會將紅色內存空間的值放到X0寄存器中:mov X0,紅色內存空間
  • 而後讓X0寄存器與1相加:add X0,1
  • 最後將值賦值給內存空間:mov 藍色內存空間,X0

**注:**爲何是64位寄存器,由於CPU是64位的,總線是64位的,一次通電能夠傳遞64位的數據給CPU,也就是8個字節,這個數據CPU存在寄存器中,因此寄存器是64位的。bash

問: 每次計算完又開闢內存空間存放結果?
答:彙編裏面不存在開闢空間,銷燬空間,直接經過內存地址訪問,和高級語言不同。
架構

pc寄存器(program counter)

  • 爲指令指針寄存器,它指示了CPU當前要讀取指令的地址
  • 在內存或者磁盤上,指令和數據沒有任何區別,都是二進制信息
  • CPU在工做的時候把有的信息看作指令,有的信息看作數據,爲一樣的信息賦予了不一樣的意義
  • 好比 1110 0000 0000 0011 0000 1000 1010 1010
  • 能夠當作數據 0xE003008AA
  • 也能夠當作指令 mov x0, x8

0x102aaa928 <+0>: sub sp, sp, #0x10左邊是指令地址,右邊是指令。less

Debug -> Debug Workflow -> View Memory 或者經過快捷鍵:shift+command + m 來調用內存查看界面ide

屏幕快照 2019-08-04 下午2.42.44.png

0x102aaa92c - 0x102aaa928 = 4,因此每一個指令戰4個字節。函數

FF 43 00 D1就是指令sub sp, sp, #0x10的二進制表現形式。性能

能夠在LLDB輸入ni單步往下走,發現依然斷點地址依然和pc寄存器同樣的。學習

屏幕快照 2019-08-04 下午2.45.31.png

輸入register write pc 0x102aaa92c改寫pc寄存器,能夠看到跳轉到改寫後地址的下一個寄存器位置。

屏幕快照 2019-08-04 下午2.52.26.png

  • CPU根據什麼將內存中的信息看作指令?
  • CPU將pc指向的內存單元的內容看作指令
  • 若是內存中的某段內容曾被CPU執行過,那麼它所在的內存單元必然被pc指向過

bl指令

  • CPU從何處執行指令是由pc中的內容決定的,咱們能夠經過改變pc的內容來控制CPU執行目標指令
  • ARM64提供了一個mov指令(傳送指令),能夠用來修改大部分寄存器的值,好比
    • mov x0,#十、mov x1,#20
  • 可是,mov指令不能用於設置pc的值,ARM64沒有提供這樣的功能
  • ARM64提供了另外的指令來修改PC的值,這些指令統稱爲轉移指令,最簡單的是bl指令

注:#後面跟個數字,叫當即數,

bl指令 -- 練習

如今有兩段代碼!假設程序先執行A,請寫出指令執行順序.最終寄存器x0的值是多少?

_A:
    mov x0,#0xa0
    mov x1,#0x00
    add x1, x0, #0x14
    mov x0,x1
    bl _B
    mov x0,#0x0
    ret

_B:
    add x0, x0, #0x10
    ret

複製代碼

咱們來寫試試看,在xcode中建立文件,格式選擇Assembly File

.text告訴編譯器在text段,也就是代碼段,.global表示是全局的。 在.m文件中須要加上方法聲明int A();,這樣編譯才能經過,由於asm.s是源文件,編譯的會連接到全局函數_A。

屏幕快照 2019-08-04 下午3.07.22.png

屏幕快照 2019-08-04 下午3.46.18.png

在A()打斷點

屏幕快照 2019-08-04 下午3.09.43.png

輸入s進入函數A

屏幕快照 2019-08-04 下午3.15.03.png

咱們能夠看到x0就是a0,此時x1是50輸入ni單步往下走,x1變成0

屏幕快照 2019-08-04 下午3.18.41.png

add x1, x0, #0x14是把x0加上14而後賦值給x1,這樣x1就變成b4。

屏幕快照 2019-08-04 下午3.21.36.png

mov x0, x1是把x1的值賦值給x0,這樣x0和x1都是b4。

屏幕快照 2019-08-04 下午3.24.32.png

接下來bl 0x102df2c00跳轉到B函數。

屏幕快照 2019-08-04 下午3.26.55.png

而後一直輸入ni,會發現死循環了,至於爲何以後會解釋。

關於CPU&寄存器的補充

寄存器

CPU除了有控制器、運算器還有寄存器。其中寄存器的做用就是進行數據的臨時存儲。

CPU的運算速度是很是快的,爲了性能CPU在內部開闢一小塊臨時存儲區域,並在進行運算時先將數據從內存複製到這一小塊臨時存儲區域中,運算時就在這一小快臨時存儲區域內進行。咱們稱這一小塊臨時存儲區域爲寄存器。

對於arm64系的CPU來講, 若是寄存器以x開頭則代表的是一個64位的寄存器,若是以w開頭則代表是一個32位的寄存器,在系統中沒有提供16位和8位的寄存器供訪問和使用。其中32位的寄存器是64位寄存器的低32位部分並非獨立存在的。

**注:**若是你改了x0寄存器,w0寄存器也會改,由於32位的寄存器是64位寄存器的低32位部分並非獨立存在的。

高速緩存

iPhoneX上搭載的ARM處理器A11它的1級緩存的容量是64KB,2級緩存的容量8M.

CPU每執行一條指令前都須要從內存中將指令讀取到CPU內並執行。而寄存器的運行速度相比內存讀寫要快不少,爲了性能,CPU還集成了一個高速緩存存儲區域.當程序在運行時,先將要執行的指令代碼以及數據複製到高速緩存中去(由操做系統完成).CPU直接從高速緩存依次讀取指令來執行.

數據地址寄存器

數據地址寄存器 數據地址寄存器一般用來作數據計算的臨時存儲、作累加、計數、地址保存等功能。定義這些寄存器的做用主要是用於在CPU指令中保存操做數,在CPU中當作一些常規變量來使用。 ARM64中

  • 64位: X0-X30, XZR(零寄存器)
  • 32位: W0-W30, WZR(零寄存器)

注意: 有一種特殊的寄存器段寄存器:CS,DS,SS,ES四個寄存器來保存這些段的基地址,這個屬於Intel架構CPU中.在ARM中並無

**注:**之前內存使用段劃分的,如今是平滑狀態,從0到最後,只是文件裏面分段,內存中再也不有段了。

浮點和向量寄存器

由於浮點數的存儲以及其運算的特殊性,CPU中專門提供浮點數寄存器來處理浮點數

2990730-37dee6fae913d736.png

  • 浮點寄存器 64位: D0 - D31 32位: S0 - S31
    如今的CPU支持向量運算.(向量運算在圖形處理相關的領域用得很是的多)爲了支持向量計算系統了也提供了衆多的向量寄存器.

  • 向量寄存器 128位:V0-V31

以上講的都是ARM64寄存器,附上8086的寄存器

  • 都是16位的
  • 能夠存放2個字節

6850908-ef6c9773663b620b.png

參考:
寄存器
關於CPU&寄存器的補充
彙編(二)
彙編(三)

相關文章
相關標籤/搜索