ARM 算數指令

加法	ADD
減法	SUB
取負	NEG
比較	CMP
乘法	MUL
移位	LSL、LSR、ASL、ASR、ROL、ROR

加法和減法

絕大多數微處理器都實現了帶進位的加法指令,能夠將兩個操作數和條件碼寄存器中的進位位加到一起。這條指令會使字長大于計算機固有字長的鏈接運算更加方便。
說明了如何使用帶進位的加法指令實現鏈式運算。如:指令ADD r2,r1,r0將源寄存器r0和r1的內容相加,將結果保存到r2中,該操作產生的進位被保存到進位位中。
在這里插入圖片描述
假設使用32位體系結構的ARM處理器,要處理64位整數并要完成64位加法。上圖(b)說明了64位算術運算中如何使用32位寄存器來傳播進位。兩個64位數已經保存到寄存器r1、r0和r3、r2中。
指令ADDS r4,r0,r2,完成r0+r2并將結果保存到r4中,進位輸出保存到CCR中進位位中。
指令ADC r5,r1,r3將高位的兩個數字相加時,進位位也被加到r1與r3的和中。助記符ADC表示帶進位的加法。

ARM還提供了SBC或帶借位的減法指令來支持擴展精度的減法運算。

逆減法指令RSB:減法指令SUB r1,r2,r3被定義為[r1]<-[r2] – [r3],逆減法指令RSB r1,r2,r3被定義為[r1]<-[r3]-[r2]

取負

取負就是用零減去一個數字。如r0的負數就是0 - [r0]。ARM沒有這樣的取負指令。可以使用逆減法來實現,因為RSB r1,r1,#0等價于NEG r1

比較

通過執行指令CMP Q,P比較P和Q時,將發生顯示比較,這條指令會計算Q-P但
不會保存結果。比較操作會修改CCR的內容,后面的指令會測試CCR的值以決定
按順序繼續執行還是進行跳轉。

考慮下面的例子:
CMP r1,r2 ; r1=r2?
BEQ DoThis ; 如果相等則跳轉到DoThis
ADD r1,r1,#1 ; 否則r1 = r1 + 1
B Next ; 不要忘記跳過THEN部分代碼
.
DoThis SUB r1,r1,#1 ; r1 = r1 -1
Next … ; 兩個分叉匯聚于此

乘法

乘法運算將兩個m位的操作數相乘,得到一個2m位 的積。結果的位長加倍帶
來一個問題。計算機要么自動將結果截斷,32位乘以32位得到一個32位結果。
要么設計一個四操作數指令:兩個源操作數,兩個目的操作數(分別保存結果
的高半部分和低半部分)。而且,二進制補碼加減法運算能得到正確結果,但
乘除法卻不一定,即對有符號和無符號數不能使用同樣的乘法操作。

有些微處理器提供了有符號和無符號乘法操作,以及結果為32位的16位乘法、
結果為64位的32位乘法。

ARM乘法指令MUL Rd,Rm,Rs計算保存在32位寄存器Rm和Rs中的兩個32位有符號數的積,將結果保存在32位寄存器Rd中,僅存放64位積的低32位。當然,應保證結果不超出范圍。如,計算121乘96:
MOV r0,#121 ; 將121加載到r0中
MOV r1,#96 ; 將96加載到r1中
MUL r2,r0,r1 ; r2 = r0 x r1

目的寄存器Rd和源寄存器Rm不用使用相同的寄存器,因為ARM在乘法計算過程中將Rd當作臨時寄存器使用,這是Arm的一個特點。

除了32位乘法指令MUL外,ARM還包括:

UMULL 無符號長整型乘法(Rm x Rd乘積為64位,存放在兩個寄存器中)
UMLAL 無符號長整型乘累加
SMULL 有符號長整型乘法
SMLAL 有符號長整型乘累加

MLA

ARM乘累加指令MLA,先進行乘法,再將乘積與另一個數相加。
MLA指令采用四操作數形式:MLA Rd,Rm,Rs,Rn。RTL定義為[Rd]<-[Rm]x[Rs]+[Rn],32位數與32位數的乘積被截斷為低32位結果。

內積運算

ARM乘累加操作使用一條指令完成乘法和加法運算,支持內積計算。
假設向量a有n個元素a1,a2,…,an,向量b有n個元素b1,b2,…,bn,則a與b的內積就是標量s=a x b = a1 x b1 + a2 x b2 +…+ an x bn
下面代碼段展示MAL指令計算兩個n元素向量Vector1和Vector2的內積:
n EQU 4
MOV r4,#n ; r4為循環計數器
MOV r3,#0 ; 將內積清零
ADR r5,Vector1 ; r5指向Vector1
ADR r6,Vector2 ; r6指向Vector2

	Loop	LDR	r0,[r5],#4	; REPEAT 讀向量Vector1的一個元素并更新指針LDR	r1,[r6],#4	;	讀取向量Vector2的相應元素MLA	r3,r0,r1,r3	;	乘累加操作r3= r3 + r0 x r1SUBS	r4,r4,#1		;	循環計數器遞減(更新CCR)BNE	Loop		; UNTIL所有計算完畢

位操作

邏輯操作也叫位操作,這些操作被應用到寄存器的每一位。微處理器一般只支持AND(與)、OR(或)、NOT(非)和EOR或(異或)操作。

下面說明了對r1=110010102和 r0=000011112進行的邏輯操作:
在這里插入圖片描述
邏輯運算的典型應用就是數據合并,即把多個變量合并到一個寄存器或存儲單元中。

假設寄存器r0包含8位數bbbbbbxx,寄存器r1包含8位數bbbyyybb,寄存器r2包、
含8位數zzzbbbbb,x、y、z代表需要的位,b是不需要的位。希望把這些位合并
得到最后結果zzzyyyxx。通過以下代碼可以到達目的:
AND r0,r0,#2_00000011 ; 保留2位xx,其他屏蔽
AND r1,r1,#2_00011100 ; 保留3位yyy,其他屏蔽
AND r2,r2,#2_11100000 ; 保留3位zzz,其他屏蔽
OR r0,r0,r1 ; 合并r1和r0得到000yyyxx
OR r0,r0,r2 ; 合并r2和r0得到zzzyyyxx

假設有一個8位二進制串abcdefgh,需要b、d兩位清零,a、e、f三位置1,h位
取反。可以通過AND、OR和EOR操作完成:

AND	r0,r0,#2_10101111		; 清除b和d位,得到a0c0efgh
OR	r0,r0,#2_10001100		; a、e、f位置1,得到10c011gh
EOR	r0,r0,#2_00000001		; b位取反,得到10c011gh(h取反)

位清楚指令BIC

ARM提供了位清除指令BIC,將第一個操作數與第二個操作數的反碼進行與操作。如,IBC r0,r1,r2實現了:

如果BIC第二個操作數中某位為0,則將第一個操作數中對應的位復制到目的操作數中,如果第二個操作數中某位為1,則把目的操作數中對應的位清零。

如果r1=10101010且r2=00001111,則BIC r0,r1,r2的結果為:
在這里插入圖片描述

可用BIC指令對寄存器的最低位字節清零。指令BIC r0,r1,#0xFF把寄存器r1中的32位復制到寄存器r0中,然后把r0中的第0~7位清零。

移位操作

移位操作就是把字中的位向左或向右移動一個或多個位置。當移位一個位串時,串的一端的位會被丟棄,并在另外一端補充新的位,如:

在這里插入圖片描述
這里的移位是邏輯移位

在這里插入圖片描述
所有微處理器都支持邏輯移位操作。有些支持向左或向右移動一位,其他的支持多位移位。如
果移位的位數在指令中被編碼為常量,這種移位叫作靜態移位,在運行時不能改變移位位數,
如果移位的位數由寄存器的值指定,則叫作動態移位,可以在程序運行時修改移位的位數。

移位的典型應用是從一個字中提取特定的位。假設有一個8位的串bxxxxbbb,x表示要提取的位,
b表示無需關心的位。下面代碼提取所需要的位且將其右對齊:
LSR r0,r0,#3 ; r0右移3位,得到000bxxxx
AND r0,r0,#2_00001111 ; 屏蔽不需要的位,得到0000xxxx

ARM沒有獨立的移位指令,移位是作為其他指令的一部分來實現的。ARM允許對寄存器-寄存
器型指令的第二個操作數進行移位。如,指令ADD r0,r1,r2,LSL #4,先寄存器r2邏輯左移4位,
然后將移位結果與寄存器r1相加。

算術移位

算術移位將操作數視作一個有符號二進制補碼。可以用來完成除以2(右移一
位)或乘以2(左移一位)等運算。算術移位的目的是在進行移
位運算時保留二進制補碼數的符號,移位運算代表乘以或除以2的冪。
算術左移與邏輯左移是等價的。算術右移會保留符號位,每次右移后符號位會
自動復制。

例如,如果將8位數11001110算術左移一位,得到10011100(最低位補0),而
算術右移一位得到11100111(符號位被復制)。一個整數算術左移m位相當于
乘以2m,而算術右移m位相當于除以2m。

循環移位

循環移位操作把寄存器的內容看作一個LSB(最低位)和MSB(最高位)相鄰的環。如上圖
(c),進行移位操作時,從一端移出的位會從另一端進來。與邏輯移位和算術移位相比,循
環移位不會丟失位。
例如,如果將8位數11001110循環左移一位,得到10011101,移出的位也被復制到進位寄存器。

有些處理器實現了另一種循環操作,叫作擴展循環移位或帶進位的循環移位。這種操作與循環
移位一樣,只不過循環時包含了進位位。
如下圖,移出的位被復制到進位位,原來的進位位變成了被移出的位:
在這里插入圖片描述

ARM移位操作的實現

ARM沒有獨立的移位操作。實際上,移位操作與其他數據處理操作組合到一起,可以在使用第
二個操作數之前將其移位。
下圖描述了ARM的移位機制,在第二個源操作數的數據通路上增加了一個桶形移位器:
在這里插入圖片描述
考慮第二個源操作數被移位的ADD操作的例子:
在這里插入圖片描述
將r2與r1相加之前,先將r2的內容邏輯左移一位,因此該操作等價于
在這里插入圖片描述
如果僅希望對寄存器進行移位操作,而不需要進行其他數據處理,可以使用下面指令:
MOV r3,r3, LSL #1

由于可以完成動態移位,也可使用指令MOV r4,r3,LSL r1,以r1為移位位數對r3
進行移位,結果送入r4。

假設r0中的數為0.00000010101111….,希望規格化為0.101…,如果用寄存器r1
表示指數,則執行MOV r0,r0,LSL r1可以在一個周期內完成規格化操作。

除了僅允許移動一位RRX指令外,ARM支持靜態和動態移位。靜態移位在編程
時就已經確定了移位的位數,而動態移位允許在執行代碼時改變移位位數。如,
指令MOV r3,r3,LSL r2以r2的值為移位位數對r3進行邏輯左移。r2的值被看作模
32的數,因為移位不能超過32次。

ARM僅實現了以下5種移位操作
LSL 邏輯左移
LSR 邏輯右移
ASR 算術右移
ROR 循環右移
RRX 帶進位的循環右移(移位一次)

盡管沒有循環左移操作,可以借助循環右移實現。
下面說了4位二進制數的循環左移和循環右移。經過4次循環移位,操作數沒有
變化。循環左移和循環右移是對稱的。對于32位數,循環左移n位等價于循環
右移32-n位。
循環右移 循環左移
1101 開始 1101 開始
1110 循環右移1次 1011 循環左移1次
0111 循環右移2次 0111 循環左移2次
1011 循環右移3次 1110 循環左移3次
1101 循環右移4次 1101 循環左移4次
ARM沒有實現帶進位的循環左移操作,通過指令ADCS r0,r0,r0可以實現帶進位
的循環左移,因為它把r0與r0以及進位位一起相加,并將結果保存在r0中(即
結果為2 x [r0] + C),左移等價于乘以2,把進位位移動到最低位等價于加上進
位位,得到2 x [r0] + C,指令后添加S會強制更新CCR,確保進位輸出被加載到C
位。因此ADCS r0,r0,r0與RXL r0等價。

指令編碼——洞察ARM體系結構

簡單的看一下ARM的移位操作是如何編碼的,下圖給出了ARM數據處理指令的二進制編碼,遵循RISC體系結構 的一般模式:包括一個操作數、兩個寄存器操作數以及第三個多目的操作數。寄存器操作數r源和r目的定義了第一個源操作數和目的寄存器。0~11位是第二個源操作數的編碼:
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/79565.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/79565.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/79565.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JAVA---集合ArrayList

集合 1. 自動擴容 &#xff0c;集合長度可變 2. 只可以存引用數據類型&#xff0c;如果要存基本數據類型&#xff0c;需要將其轉換成對應的包裝類 ArrayList 定義在 java.util 下的&#xff0c;實現了 List 接口。ArrayList 內部以動態數組的形式存儲元素&#xff0c;這意…

Scrapy框架之【settings.py文件】詳解

settings.py 文件的主要作用是對 Scrapy 項目的全局設置進行集中管理。借助修改這個文件中的配置項&#xff0c;你可以對爬蟲的行為、性能、數據處理等方面進行靈活調整&#xff0c;而無需修改爬蟲代碼。 ①默認英文注釋settings.py # Scrapy settings for douban project # …

Java變量學習筆記

Java變量 -為什么需要變量&#xff1f; 一個程序就是一個世界 變量是程序的基本組成單位 不論是使用哪種高級程序語言編寫程序,變量都是其程序的基本組成單位&#xff0c;比如: //變量有三個基本要素(類型名稱值) class Test{public static void main(String [largs){int a1;…

數據結構*隊列

隊列 什么是隊列 是一種線性的數據結構&#xff0c;和棧不同&#xff0c;隊列遵循“先進先出”的原則。如下圖所示&#xff1a; 在集合框架中我們可以看到LinkedList類繼承了Queue類&#xff08;隊列&#xff09;。 普通隊列&#xff08;Queue&#xff09; Queue中的方法 …

Nginx — 防盜鏈配置

防盜鏈簡述 防盜鏈是一種保護網絡資源所有者權益的技術手段&#xff0c;旨在防止未經授權的用戶或網站通過直接鏈接的方式盜用資源&#xff0c;以下是關于防盜鏈的簡述&#xff1a; 原理 基于請求頭驗證&#xff1a;服務器通過檢查請求頭中的特定字段&#xff0c;如Referer字…

【淺學】Windows下ffmpeg+nginx+flv將本地視頻推流在本地搭建的Web前端頁面中播放,超詳細步驟

Nginx安裝和配置 下載nginx-1.19.3-http-flv 模塊預編譯包并解壓放在d盤&#xff0c;路徑就跟安裝步驟里說的一樣(如下圖)&#xff0c;不然會有其他問題出現。 打開conf/nginx.conf&#xff0c;查看RTMP和http相關的配置&#xff0c;確認端口號和路由名稱 ffpemg推流視頻…

Ubuntu-tomcat安裝部署

https://blog.csdn.net/weixin_43877427/article/details/144697087 Linux下Tomcat安裝與配置_tomcat linux安裝及配置教程-CSDN博客 一、下載Tomcat 1、官網下載 進入后根據自己需要選擇不同的版本&#xff0c;點擊download 進入后&#xff0c;在下圖標注的里邊選擇要下載…

希洛激活器策略思路

在復雜多變的外匯市場中&#xff0c;交易者常常尋求有效的工具來輔助決策。 希洛激活器作為一種綜合性的技術指標&#xff0c;結合了江恩理論、CCI&#xff08;商品通道指數&#xff09;和MACD&#xff08;移動平均收斂發散指標&#xff09;&#xff0c;旨在為交易者提供更為全…

n8n工作流自動化平臺的實操:本地化高級部署

一、本地高級部署 1.下載 docker pull docker.n8n.io/n8nio/n8n 2.運行 docker volume create n8n_data docker run -dit --name n8n -p 5678:5678 -v n8n_data:/home/node/.n8n -e N8N_SECURE_COOKIEfalse -e N8N_RUNNERS_ENABLEDtrue -e N8N_ENFORCE_SETTINGS_FIL…

vector和string的迭代器

1. 迭代器的本質 (1) 標準要求 C 標準要求 std::string 和 std::vector 的迭代器必須是 隨機訪問迭代器&#xff08;Random Access Iterator&#xff09;。 指針天然滿足隨機訪問迭代器的所有操作&#xff08;如 、--、n、* 等&#xff09;&#xff0c;因此可以直接用指針實現…

PyCharm代理配置全攻略:系統設置+Python運行環境一鍵搞定

文章目錄 1. 設置系統代理1.1 作用范圍1.2 使用場景1.3 設置步驟 2. 設置 python 運行/調試代理2.1 作用范圍2.2 使用場景2.3 設置步驟 Pycharm 工具作為一款強大的 IDE&#xff0c;其代理配置在實際開發中也是必不可少的&#xff0c;下面介紹下如何配置 Pycharm 的代理。 1. …

stm32 g031g8 flash擦除函數被坑

先記錄一下在擦除的時候由于調用了這個FLASH_PageErase(FLASH_BANK_1, secpos); 導致擦除不成功&#xff0c;寫入失敗。 下面的擦除有問題// 使用 FLASH_PageErase 擦除該頁while ((FLASH->SR & FLASH_SR_BSY1) ! 0); // 等待空閑FLASH_PageErase(FLASH_BANK_1, secpo…

深度學習與 PyTorch 基礎

筆記 1 深度學習簡介 1.1 深度學習概念 深度學習是機器學習的一類算法, 以人工神經網絡為結構, 可以實現自動提取特征 深度學習核心思想是人工神經網絡為結構, 自動提取特征 1.2 深度學習特點 自動提取特征 解釋性差 大量數據和高性能計算能力 非線性轉換(引入非線性因…

【Unity】XLua訪問C#文件

創建NPC.cs&#xff1a; public class NPC { public string name; public int age; public void Say() { Debug.Log("Say:我是未被修改的"); } public static void Say() { Debug.Log("Static Say:我是未被修改的"); } public void Say2(int a) { Debug.Lo…

【第十六屆藍橋杯省賽】比賽心得與經驗分享(PythonA 組)

文章目錄 一、我的成績二、我的備賽經歷三、如何備賽&#xff08;個人觀點&#xff09;1. 基礎語法2. 數據結構3. 算法4. 數學 四、做題技巧與注意事項五、我的題解試題A 偏藍 &#x1f3c6;100%試題B IPV6 &#x1f3c6;0%試題C 2025圖形 &#x1f3c6;100%試題D 最大數字 &am…

基于Springboot+Mysql的校園博客系統(含LW+PPT+源碼+系統演示視頻+安裝說明)

系統功能 管理員功能&#xff1a;首頁、個人中心、博主管理、文章分類管理、文章信息管理、舉報投訴管理、系統管理&#xff1b;博主功能&#xff1a;首頁、個人中心、文章信息管理、舉報投訴管理、我的收藏管理&#xff1b;前臺首頁功能&#xff1a;首頁、文章信息、系統公告…

第三次作業(密碼學)

#include <stdio.h> #include <stdlib.h> // 計算最大公約數 int gcd(int a, int b) { while (b ! 0) { int temp b; b a % b; a temp; } return a; } // 計算模冪運算 int mod_pow(int base, int exponent, int modulus) { …

3.0/Q1,Charls最新文章解讀

文章題目&#xff1a;Association between outdoor artificial light at night and metabolic diseases in middle-aged to older adults-the CHARLS survey DOI&#xff1a;10.3389/fpubh.2025.1515597 中文標題&#xff1a;夜間戶外人工光與中老年人代謝性疾病的關聯-CHARLS調…

MATLAB 中zerophase函數——零相位響應

零相位響應&#xff08;Zero-Phase Response&#xff09;是指濾波器的幅度函數&#xff0c;但相位為零。濾波器的相位響應為零&#xff0c;意味著不同頻率的信號通過濾波器后&#xff0c;其相位不發生任何變化&#xff0c;即信號的波形在時間軸上沒有偏移。 零相位響應指的是當…

馬克思最基本的哲學思想--改造世界以實現人的自由全面發展--deepseek

馬克思的哲學思想可以概括為“改造世界以實現人的自由全面發展”&#xff0c;這句話看似簡單&#xff0c;卻包含了其哲學的核心邏輯。我們可以從三個層面展開分析&#xff1a; 1. “改造世界”——實踐是哲學的終極使命 馬克思在《關于費爾巴哈的提綱》中寫道&#xff1a; “哲…