0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

匯編基礎(chǔ)知識(shí)教程之?dāng)?shù)據(jù)類型與寄存器

jf_78858299 ? 來源: zhangfann ? 作者: 張凡 ? 2023-01-30 15:06 ? 次閱讀

數(shù)據(jù)類型

這是 ARM 匯編基礎(chǔ)知識(shí)系列教程的第二部分,涉及數(shù)據(jù)類型和寄存器。

圖片

與高級(jí)語(yǔ)言類似,ARM支持對(duì)不同數(shù)據(jù)類型的操作。我們可以加載(或存儲(chǔ))的數(shù)據(jù)類型可以是有符號(hào)和無符號(hào)字、半字或字節(jié)。這些數(shù)據(jù)類型的擴(kuò)展是。-h或-sh用于半字,-b或-sb用于字節(jié),而字則沒有擴(kuò)展。有符號(hào)和無符號(hào)數(shù)據(jù)類型之間的區(qū)別是。

有符號(hào)的數(shù)據(jù)類型可以容納正值和負(fù)值,因此范圍較小。

無符號(hào)數(shù)據(jù)類型可以保存大的正值(包括 "零"),但不能保存負(fù)值,因此范圍更廣。

下面是一些例子,說明這些數(shù)據(jù)類型如何與指令Load和Store一起使用。

圖片

大小端

在內(nèi)存中,有兩種查看字節(jié)的基本方法。小端(LE)或大端(BE)。區(qū)別在于一個(gè)對(duì)象的每個(gè)字節(jié)在內(nèi)存中的存儲(chǔ)順序。在像英特爾x86這樣的小端機(jī)器上,最不重要的字節(jié)被存儲(chǔ)在最低地址(最接近零的地址)。在big-endian機(jī)器上,最重要的字節(jié)被存儲(chǔ)在最低地址。ARM架構(gòu)在第3版之前是小-endian,從那時(shí)起,它是雙-endian,這意味著它有一個(gè)允許可切換endianness的設(shè)置。例如,在ARMv6中,指令是固定的小字節(jié),數(shù)據(jù)訪問可以是小字節(jié)或大字節(jié),由程序狀態(tài)寄存器(CPSR)的第9位(E位)控制。

圖片

ARM寄存器

寄存器的數(shù)量取決于ARM的版本。根據(jù)ARM參考手冊(cè),除了基于ARMv6-M和ARMv7-M的處理器外,有30個(gè)通用的32位寄存器。前16個(gè)寄存器可在用戶級(jí)模式下訪問,其他寄存器可在特權(quán)軟件執(zhí)行中使用(ARMv6-M和ARMv7-M例外)。在本系列教程中,我們將處理在任何特權(quán)模式下都可以訪問的寄存器:r0-15。這16個(gè)寄存器可以分成兩組:通用寄存器和特殊用途寄存器。

圖片

圖片

下表展示了ARM寄存器與Intel處理器中的寄存器之間的關(guān)系。

圖片

R0-R12:在普通操作中可用于存儲(chǔ)臨時(shí)值、指針(存儲(chǔ)器的位置)等。例如,R0在進(jìn)行算術(shù)運(yùn)算時(shí)可作為累加器,或用于存儲(chǔ)先前調(diào)用的函數(shù)的結(jié)果。R7在處理系統(tǒng)調(diào)用時(shí)變得非常有用,因?yàn)樗鎯?chǔ)了系統(tǒng)調(diào)用的編號(hào),R11幫助我們跟蹤堆棧上的邊界,作為框架指針(將在后面介紹)。此外,ARM的函數(shù)調(diào)用慣例規(guī)定,函數(shù)的前四個(gè)參數(shù)存儲(chǔ)在寄存器r0-r3中。

R13:SP(堆棧指針)。堆棧指針指向堆棧的頂部。堆棧是一個(gè)用于特定函數(shù)存儲(chǔ)的內(nèi)存區(qū)域,在函數(shù)返回時(shí)被回收。因此,堆棧指針用于分配堆棧的空間,方法是用堆棧指針減去我們要分配的值(以字節(jié)為單位)。換句話說,如果我們想分配一個(gè)32位的值,我們從堆棧指針中減去4。

R14:LR(鏈接寄存器)。當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),鏈接寄存器被更新為內(nèi)存地址,引用函數(shù)啟動(dòng)的下一條指令。這樣做允許程序在 "子 "函數(shù)完成后返回到啟動(dòng) "子 "函數(shù)的 "父 "函數(shù)。

R15:PC(程序計(jì)數(shù)器)。程序計(jì)數(shù)器根據(jù)所執(zhí)行的指令的大小自動(dòng)遞增。這個(gè)大小在ARM狀態(tài)下總是4字節(jié),在THUMB模式下是2字節(jié)。當(dāng)一個(gè)分支指令被執(zhí)行時(shí),PC保存目標(biāo)地址。在執(zhí)行過程中,PC在ARM狀態(tài)下存儲(chǔ)當(dāng)前指令的地址加8(兩條ARM指令),在Thumb(v1)狀態(tài)下存儲(chǔ)當(dāng)前指令加4(兩條Thumb指令)。這與x86不同,x86的PC總是指向要執(zhí)行的下一條指令。

讓我們看看PC在調(diào)試器中是如何表現(xiàn)的。我們用下面的程序?qū)C的地址存入r0,并包括兩條隨機(jī)指令。讓我們看看會(huì)發(fā)生什么。

圖片

在gdb中我們?cè)赺start處設(shè)定一個(gè)斷點(diǎn)

圖片

如下是運(yùn)行的結(jié)果:

圖片

我們可以看到,PC持有將被執(zhí)行的下一條指令(mov r0, pc)的地址(0x8054)?,F(xiàn)在讓我們執(zhí)行下一條指令,之后R0應(yīng)該持有PC的地址(0x8054),對(duì)嗎?

圖片

...對(duì)嗎?錯(cuò)了??纯碦0中的地址。當(dāng)我們期望R0包含先前讀取的PC值(0x8054)時(shí),它卻包含了比我們先前讀取的PC值(0x805c)提前兩條指令的值。從這個(gè)例子中你可以看到,當(dāng)我們直接讀取PC時(shí),它遵循PC指向下一條指令的定義;但在調(diào)試時(shí),PC指向當(dāng)前PC值前面的兩條指令(0x8054 + 8 = 0x805C)。這是因?yàn)檩^早的ARM處理器總是在當(dāng)前執(zhí)行的指令之前獲取兩條指令。ARM保留這一定義的原因是為了確保與早期處理器的兼容性。

當(dāng)前程序狀態(tài)寄存器

當(dāng)你用gdb調(diào)試一個(gè)ARM二進(jìn)制文件時(shí),你會(huì)看到一個(gè)叫做Flags的東西。

圖片

寄存器$cpsr顯示了當(dāng)前程序狀態(tài)寄存器(CPSR)的值,在它下面可以看到Flagsthumb, fast, interrupt, overflow, carry, zero, and negative。這些標(biāo)志代表了CPSR寄存器中的某些位,并根據(jù)CPSR的值來設(shè)置,激活時(shí)變成粗體。N、Z、C和V位與x86上EFLAG寄存器中的SF、ZF、CF和OF位相同。這些位被用來支持匯編級(jí)的條件和循環(huán)的條件執(zhí)行。我們將在第6部分 "條件執(zhí)行和分支 "中介紹使用的條件代碼。

圖片

上圖顯示了一個(gè)32位寄存器(CPSR)的布局,左邊(<-)是最重要的位,右邊(->)是最小的位。每一個(gè)單元(除了GE和M部分以及空白部分)都是一個(gè)比特的大小。這些一比特的部分定義了程序當(dāng)前狀態(tài)的各種屬性。

圖片

讓我們假設(shè)我們使用CMP指令來比較數(shù)字1和2。結(jié)果是 "負(fù)",因?yàn)?-2=-1。當(dāng)我們比較兩個(gè)相等的數(shù)字時(shí),比如2對(duì)2,Z(零)標(biāo)志被設(shè)置,因?yàn)?-2=0。請(qǐng)記住,CMP指令使用的寄存器不會(huì)被修改,只有CPSR會(huì)根據(jù)這些寄存器相互比較的結(jié)果被修改。

這是GDB中的情況(安裝了GEF)。在這個(gè)例子中,我們比較寄存器r1和r0,其中r1=4,r0=2。這是執(zhí)行了cmp r1, r0操作后的標(biāo)志的情況。

進(jìn)位標(biāo)志被設(shè)置,因?yàn)槲覀冇胏mp r1, r0來比較4和2(4-2)。相反,如果我們使用cmp r0, r1來比較一個(gè)較小的數(shù)字(2)和一個(gè)較大的數(shù)字(4),則負(fù)標(biāo)志(N)被設(shè)置。

下面是ARM信息中心的一段摘錄:

APSR包含以下ALU狀態(tài)標(biāo)志。

N - 當(dāng)操作的結(jié)果為負(fù)數(shù)時(shí)設(shè)置。

Z - 當(dāng)操作的結(jié)果為零時(shí)設(shè)置。

C - 當(dāng)操作的結(jié)果是Carry時(shí)設(shè)置。

V--當(dāng)操作引起溢出時(shí)設(shè)置。

carry在以下情況被設(shè)置:

如果加法的結(jié)果大于或等于2^32

如果減法的結(jié)果是正數(shù)或零

作為移動(dòng)或邏輯指令中的內(nèi)聯(lián)移位操作的結(jié)果。

如果加法、減法或比較的結(jié)果大于或等于2^31,或小于2^31,則發(fā)生溢出。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • ARM
    ARM
    +關(guān)注

    關(guān)注

    134

    文章

    9097

    瀏覽量

    367555
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5343

    瀏覽量

    120366
  • 匯編
    +關(guān)注

    關(guān)注

    2

    文章

    214

    瀏覽量

    25934
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    芯片解密基礎(chǔ)知識(shí):串行端口的控制寄存器

    芯片解密基礎(chǔ)知識(shí):串行端口的控制寄存器 串行端口控制寄存器有哪些類型?各自的工作方式是什么?下面由IC解密工程師詳解各類型的串行端口控制
    發(fā)表于 03-30 11:27

    MSP-ESP430G2常用數(shù)據(jù)類型及字節(jié)數(shù)值范圍基礎(chǔ)知識(shí)補(bǔ)充

    瘋狂的大柚柚帶你玩轉(zhuǎn)MSP-ESP430G2(基礎(chǔ)篇)(六)基礎(chǔ)知識(shí)補(bǔ)充常用數(shù)據(jù)類型數(shù)據(jù)類型字節(jié)數(shù)值范圍Char1-128~127Unsigned char10`255short2-32768
    發(fā)表于 02-15 07:25

    數(shù)據(jù)寄存器,數(shù)據(jù)寄存器是什么意思

    數(shù)據(jù)寄存器,數(shù)據(jù)寄存器是什么意思 數(shù)據(jù)寄存器數(shù)據(jù)
    發(fā)表于 03-08 14:38 ?1.3w次閱讀

    匯編語(yǔ)言教程-段寄存器的說明語(yǔ)句

    匯編語(yǔ)言教程-段寄存器的說明語(yǔ)句   在匯編語(yǔ)言源程序中可以定義多個(gè)段,每個(gè)段都要與一個(gè)段寄存器建立一種對(duì)應(yīng)關(guān)系。建立這
    發(fā)表于 03-27 17:17 ?1405次閱讀

    匯編語(yǔ)言學(xué)習(xí)課件_微處理基礎(chǔ)知識(shí)

    匯編語(yǔ)言學(xué)習(xí)課件 第二章 微處理基礎(chǔ)知識(shí) 2.1 Intel公司80x86系列微處理簡(jiǎn)介 2.2 程序可見寄存器組 2.3 存儲(chǔ)
    發(fā)表于 12-31 10:39 ?0次下載

    python教程之變量和簡(jiǎn)單數(shù)據(jù)類型

    本文檔的主要內(nèi)容詳細(xì)介紹的是python教程之變量和簡(jiǎn)單數(shù)據(jù)類型。
    發(fā)表于 04-26 08:00 ?7次下載
    python教<b class='flag-5'>程之</b>變量和簡(jiǎn)單<b class='flag-5'>數(shù)據(jù)類型</b>

    Windows編程之數(shù)據(jù)類型綜述

    Windows編程之數(shù)據(jù)類型綜述
    發(fā)表于 08-24 15:03 ?5次下載

    [從零學(xué)習(xí)匯編語(yǔ)言] -寄存器詳解

    語(yǔ)言基礎(chǔ)知識(shí)梳理一、 存儲(chǔ)與通用寄存器1. 存儲(chǔ)每一天清晨,當(dāng)我們?cè)趬?mèng)中醒來的時(shí)候,記憶就會(huì)填充大腦的空白,我們會(huì)想起最近做過的一些重要的事情,當(dāng)然也有些小的事情無法準(zhǔn)確的記憶起,
    發(fā)表于 11-26 20:51 ?8次下載
    [從零學(xué)習(xí)<b class='flag-5'>匯編</b>語(yǔ)言] -<b class='flag-5'>寄存器</b>詳解

    第二章(1) 初識(shí)P0,P1并口 數(shù)據(jù)類型,常量定義方法,特殊功能寄存器定義

    1.認(rèn)識(shí)P0與P1,數(shù)據(jù)類型,常量定義方法,特殊功能寄存器定義2.P0和P1區(qū)別及介紹
    發(fā)表于 12-31 19:57 ?6次下載
    第二章(1) 初識(shí)P0,P1并口  <b class='flag-5'>數(shù)據(jù)類型</b>,常量定義方法,特殊功能<b class='flag-5'>寄存器</b>定義

    Verilog HDL語(yǔ)言的數(shù)據(jù)類型和運(yùn)算符

    reg是寄存器數(shù)據(jù)類型的關(guān)鍵字,是數(shù)據(jù)存儲(chǔ)單元的抽象,通過賦值語(yǔ)句可以改變寄存器存儲(chǔ)的值。reg型數(shù)據(jù)常用來表示always模塊內(nèi)的指定信號(hào)
    的頭像 發(fā)表于 05-18 10:34 ?2502次閱讀

    四種類型的 JTAG 數(shù)據(jù)寄存器介紹

    本文將介紹四種類型的 JTAG 數(shù)據(jù)寄存器,分別是: Boundary Scan Register (BSR) 邊界掃描寄存器 Bypass Register (BR) 旁路
    發(fā)表于 02-07 10:01 ?3641次閱讀

    解析一些常見的寄存器

    數(shù)據(jù)寄存器(Data Register,DR)又稱數(shù)據(jù)緩沖寄存器數(shù)據(jù)寄存器用于存放操作數(shù),其位
    的頭像 發(fā)表于 02-09 14:47 ?5528次閱讀
    解析一些常見的<b class='flag-5'>寄存器</b>

    Go匯編基礎(chǔ)知識(shí)

    不同體系結(jié)構(gòu)的 CPU,其內(nèi)部寄存器的數(shù)量、種類以及名稱可能大不相同,這里我們只介紹 AMD64 的寄存器。AMD64 有 20 多個(gè)可以直接在匯編代碼中使用的寄存器,其中有幾個(gè)
    的頭像 發(fā)表于 04-20 11:12 ?1098次閱讀

    Verilog最常用的2種數(shù)據(jù)類型

    Verilog 最常用的 2 種數(shù)據(jù)類型就是線網(wǎng)(wire)與寄存器(reg),其余類型可以理解為這兩種數(shù)據(jù)類型的擴(kuò)展或輔助。
    的頭像 發(fā)表于 05-29 16:27 ?2337次閱讀
    Verilog最常用的2種<b class='flag-5'>數(shù)據(jù)類型</b>

    寄存器分為基本寄存器和什么兩種

    寄存器是計(jì)算機(jī)中用于存儲(chǔ)數(shù)據(jù)的高速存儲(chǔ)單元,它們是CPU內(nèi)部的重要組成部分。寄存器可以分為基本寄存器和擴(kuò)展寄存器兩種
    的頭像 發(fā)表于 07-12 10:31 ?1374次閱讀