嵌入式學習(Day 51:ARM指令/匯編與c語言函數相互調用)

1.Supervisor模式與SVC模式

  • Supervisor模式是ARM處理器的一個特權工作模式,允許執行特權指令和訪問特權資源。
  • SVC模式(Supervisor Call)是與Supervisor模式相關的一個功能或指令,用于從用戶模式切換到Supervisor模式,并觸發系統服務例程的執行。
  • SVC不是一種獨立的工作模式,而是與Supervisor模式協同工作,用于系統調用和異常處理。

????????所以,Supervisor模式和SVC模式在ARM處理器中是不同的概念,但它們之間有密切的關聯。SVC模式使用Supervisor模式的功能來提供系統服務。

2.指令+s的作用,影響N,Z,C,V位

????????ARM指令中的“S”后綴用于指示該指令執行后是否更新程序狀態寄存器(CPSR)的條件標志位。這些標志位可以用于后續的條件判斷或分支操作,從而影響指令的執行順序。

以下是具體功能和詳細解釋:

  • 條件標志位更新:當ARM指令后帶有“S”后綴時,該指令執行后,程序狀態寄存器的條件標志位(如N、Z、C、V等,分別代表負數、零、進位和溢出)將被刷新或更新。這些標志位經常用于對條件進行測試,例如是否溢出、是否進位等。

  • 影響指令執行順序:根據這些條件標志位的變化,程序可以執行不同的分支或循環,從而影響指令的執行順序。例如,可以使用這些標志位來判斷一個加法操作是否導致溢出,然后根據結果選擇不同的后續指令。

  • 指令格式:在ARM指令中,后綴“S”是可選的。當不使用“S”后綴時,指令執行后程序狀態寄存器的條件標志位將不會發生變化。指令的一般格式可以表示為<opcode>{ <cond> } {S}<Rd>,<Rn>{, <operand2> },其中<opcode>是操作碼,<cond>是可選的條件碼,<Rd>是目標寄存器,<Rn>是存放第一操作數的寄存器,<operand2>是第二操作數。

  • 具體示例:以加法指令為例,ADD R3, R5, R8(沒有使用“S”后綴)執行后,條件標志位將不會發生變化;而ADDS R3, R5, R8(使用了“S”后綴)執行后,條件標志位將根據結果刷新。

3.CPSR(程序狀態寄存器)/SPSR(程序狀態保存寄存器)

在ARM架構中,CPSR(Current Program Status Register,當前程序狀態寄存器)和SPSR(Saved Program Status Register,程序狀態保存寄存器)是兩個重要的狀態寄存器,它們在處理器中扮演著關鍵的角色。以下是關于這兩個寄存器的詳細解釋:

????????3.1. CPSR(當前程序狀態寄存器)

????????N和C標志位被“置位”,指的是這些標志位被設置為特定的值以表示某種狀態或條件。

功能與作用

  • CPSR在用戶級編程時用于存儲條件碼。
  • 它包含條件碼標志、中斷禁止位、當前處理器模式以及其他狀態和控制信息。

內容詳解

  • 條件標志位:包括N、Z、C、V等,用于表示指令執行后的狀態,如運算結果的符號、零、進位和溢出等。
  • 中斷禁止位:包括I(IRQ中斷禁止位)和F(FIQ中斷禁止位),用于控制是否允許相應的中斷發生。
  • 處理器模式標志位:指示處理器當前處于哪種模式,如用戶模式、系統模式、中斷模式等。

訪問方式

  • CPSR在任何處理器工作模式下都可以被訪問。

????????3.2. SPSR(程序狀態保存寄存器)

功能與作用

  • SPSR用于保存CPSR的狀態,以便在異常返回后恢復異常發生時的工作狀態。

內容詳解

  • 當特定的異常中斷發生時,SPSR會存放當前CPSR的內容。
  • 在異常中斷退出時,可以使用SPSR來恢復CPSR的狀態。

注意

  • 由于用戶模式和系統模式不是異常中斷模式,所以它們沒有對應的SPSR。
  • 如果在用戶模式或系統模式下嘗試訪問SPSR,將會產生不可預知的后果。

總結

  • CPSR是ARM處理器中的核心寄存器之一,用于存儲處理器的狀態信息,并在各種模式下提供對中斷和其他功能的控制。
  • SPSR作為CPSR的備份,用于在異常處理過程中保存和恢復處理器的狀態。這兩個寄存器共同確保了ARM處理器在各種復雜操作中的穩定性和可靠性。

4.跳轉指令和加載指令

???4.1跳轉指令(b/bl/bx)

????????b:無條件跳轉指令;

? ? ? ? bl:用于函數調用,并保存返回地址。

????????bl和b之間的區別就在于bl會在lr寄存器中保存回來的地址。

? ? ? ? bx:回到調用處;

? ? ? ? bxgt:滿足gt條件時,回到調用處。

??bx?基于寄存器的內容進行跳轉,并支持 ARM/Thumb 切換。

4.2 加載指令(LDR)

  • LDR指令
    • 功能:用于從內存中讀取一個32位的字數據到目的寄存器中。
    • 格式LDR{條件} 目的寄存器, <存儲器地址>
    • 示例
      • LDR R0, [R1]:將存儲器地址為R1的字數據讀入寄存器R0。
      • LDR R0, [R1, #8]:將存儲器地址為R1+8的字數據讀入寄存器R0。
    • 特點
      • 尋址方式靈活多樣,支持直接地址、基址加偏移量等。
      • 當程序計數器PC作為目的寄存器時,指令從存儲器中讀取的字數據被當作目的地址,從而可以實現程序流程的跳轉。
    • bic指定位清零指令:
    • BIC{S}<c> <Rd>, <Rn>, #<const>;將rn中的字數據const為1的比特清零,把結果放入rd
      • orr指定位置位指令:
      • ORR{S}<c> <Rd>, <Rn>, #<const>

5.ARM中常見的數據處理指令

  • ADD

    • 含義:加法指令。
    • 使用:將兩個寄存器或立即數與一個寄存器相加,并將結果存儲在一個寄存器中。
    • 示例ADD R1, R2, R3?將?R2?和?R3?的值相加,并將結果存儲在?R1?中。
  • SUB

    • 含義:減法指令。
    • 使用:從一個寄存器中減去另一個寄存器或立即數,并將結果存儲在一個寄存器中。
    • 示例SUB R1, R2, R3?從?R2?中減去?R3?的值,并將結果存儲在?R1?中。

ARM指令集中的數據處理指令是用于在寄存器中執行數學運算、邏輯運算以及數據傳送的指令。這些指令在ARM架構中扮演著核心角色,允許CPU高效地執行各種計算任務。以下是一些ARM中常見的數據處理指令,按照其功能分類進行歸納:

  1. 數據傳送指令
    • MOV指令:用于將一個寄存器或立即數的值傳送到另一個寄存器。例如,MOV R1, R0 將寄存器R0的值傳送到寄存器R1。
    • MVN指令:是數據取反傳送指令,將一個寄存器或立即數的反碼傳送到目標寄存器。例如,MVN R0, #0 將立即數0取反后傳送到寄存器R0。
  2. 算術運算指令
    • ADD指令:用于將兩個寄存器或立即數相加,并將結果存放到目的寄存器中。例如,ADD R0, R1, R2 將R1和R2的值相加后存放到R0。
    • ADC指令:帶進位的加法指令,用于將兩個寄存器或立即數相加,并加上CPSR中的C條件標志位的值,然后將結果存放到目的寄存器中。
  3. 邏輯運算指令(雖然參考文章中沒有直接提及邏輯運算指令,但它們是數據處理指令的重要部分):
    • AND指令:用于將兩個寄存器或立即數進行邏輯與運算。
    • ORR指令:用于將兩個寄存器或立即數進行邏輯或運算。
    • EOR指令:用于將兩個寄存器或立即數進行邏輯異或運算。
  4. 比較指令
    • CMP指令:用于比較兩個寄存器或立即數的值,并更新CPSR中的條件標志位,但不保存運算結果。
    • CMN指令:將一個寄存器或立即數的取反值與另一個寄存器或立即數進行比較,并更新CPSR中的條件標志位。
  5. 移位指令(雖然參考文章中沒有直接提及移位指令,但它們也是數據處理指令的一部分):
    • LSL指令:邏輯左移指令,將寄存器的內容向左移動指定的位數。
    • LSR指令:邏輯右移指令,將寄存器的內容向右移動指定的位數。
    • ASR指令:算術右移指令,在移位時保留符號位。
  6. 特殊數據處理指令
    • MOVS指令:與MOV指令類似,但會更新CPSR中的條件標志位。
    • BIC指令:位清零指令,用于將某個寄存器中的特定位清零。

這些指令共同構成了ARM指令集中的數據處理部分,允許開發者在ARM架構的CPU上執行各種復雜的計算任務。需要注意的是,ARM指令集在不同的版本(如ARMv7、ARMv8等)中可能會有所不同,上述指令是ARM指令集中常見的和通用的部分。

6.棧的實現類型:

2440實現保護和恢復現場使用的棧是數組棧,即用一段連續的內存空間為棧提供空間。從數組棧的具體實現來看入棧的方式有四種做法:

  • 空增:先寫入數據,再讓棧指針自增;(棧指針平時指向空)
  • 空減:先寫入數據,再讓棧指針自減;(棧指針一開始指向棧頂)
  • 滿增:先讓棧指針自增,再寫入數據;(棧指針平時指向最高層數據)
  • 滿減:先讓棧指針自減,再寫入數據。(棧指針指向棧頂的上一個空位置)

????????arm體系采用的方案是滿減,但是在進行操作之前,我們必須告訴2440棧底的位置,這里我們把棧底設置為0x40001000,從地址0x40000000開始的0x1000這段內存空間對應的是2440內部的一段ram,總共4k。實際能夠使用的內存空間為[0x40000000~0x40000FFF],設置棧底指針寄存器: ldr sp =0x40001000

? ? ? ? 6.1入棧保護指令stmfd(STMDB)

STMFD<c> <Rn>{!}, <registers>

其中Rn表示棧底指針寄存器,<?registers?>表示需要入棧保護的寄存器,!表示入棧之后sp自動自減。如:

stmfd sp!, {r0, r1, r2, r3-r12, lr}???????????????;保護現場

6.2出棧恢復指令ldmfd(LDM/LDMIA/)

LDMFD<c> <Rn>{!}, <registers>

中Rn表示棧底指針寄存器,<?registers?>表示需要入棧保護的寄存器,!表示出棧之后sp自動自增。如:

ldmfd sp!, {r0, r1, r2, r3-r12, lr}?? ;恢復現場

7.匯編與C語言代碼互相調用規則

7.1在匯編中調用c語言編寫的函數

????????設有c語言定義的函數void func_c(void);在匯編代碼中調用該函數,只需用import導入聲明函數名即可,之后就可以使用bl指令調用該函數,注意,既然是調函數,就一定要保護現場。

????????7.2 向c函數傳參

向c函數傳參的方法很簡單,如果參數個數小于等于4個,就直接用r0~r3傳參,c函數返回值通過r0寄存器返回:

設有c函數:

????????int add_c(int a, int b, int c, int d)

????????{

????????return a + b + c + d;

??}

如果參數個數大于4個,從第五個參數開始就需要通過棧來傳參(前4個參數傳參,通過r0-r3傳參,返回值用r0傳參)

在c語言中調用匯編編寫的函數類似,不過在匯編中用export聲明函數,同時需要在c語言中用extern聲明函數,按照標準,調用者負責保護現場和恢復現場

傳參方法于此類似

8.切換ARM內核的工作模式

? ? ? ? mrs:讀取CPSR的狀態;

? ? ? ? msr:寫入CPSR寄存器。

????????切換工作方式的思路很簡單,由于內核的工作模式是由cpsr寄存器的低5位來設置的,那么就可以先把cpsr讀出來,更改低5位之后再設置進去。這里讀取cpsr使用mrs指令,寫cpsr寄存器用msr指令,需要注意的是在keil環境下寫cpsr需要寫成: ??msr cpsr_c r0;將r0的值寫入到cpsr寄存器

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

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

相關文章

1、Redis系列-Redis高性能原理詳解

Redis高性能原理詳解 Redis是一款高性能的內存數據庫&#xff0c;廣泛應用于需要快速讀寫訪問的數據密集型應用中。它的高性能得益于多方面的設計和優化。以下是Redis高性能實現的詳細解釋&#xff1a; 1. 單線程架構 Redis采用單線程架構來處理客戶端請求&#xff0c;這與傳…

服務器流量收發測試-續篇

文章目錄 一、概述二、普通java工程1&#xff0c;pom文件2&#xff0c; 定時任務3&#xff0c;打包4&#xff0c;jar運行 三、打包docker鏡像1&#xff0c;鏡像打包配置docker環境&#xff1a;2&#xff0c;連接遠程鏡像倉庫 四、部署運行1. 容器運行2. 單容器多次運行jar3. 容…

大模型應用研發基礎環境配置(Miniconda、Python、Jupyter Lab、Ollama等)

老牛同學之前使用的MacBook Pro電腦配置有點舊&#xff08;2015 年生產&#xff09;&#xff0c;跑大模型感覺有點吃力&#xff0c;操作起來有點卡頓&#xff0c;因此不得已撿起了塵封了快兩年的MateBook Pro電腦&#xff08;老牛同學其實不太喜歡用 Windows 電腦做研發工作&am…

04_記錄鎖

記錄鎖&#xff08;Record Lock&#xff09; 文章目錄 記錄鎖&#xff08;Record Lock&#xff09;簡介原理加鎖流程鎖類型使用場景示例與其他鎖的對比結論 簡介 MySQL 中的記錄鎖&#xff08;Record Lock&#xff09;是行級鎖的一種&#xff0c;用于鎖定數據庫表中的特定行。…

從零開始做題:老照片中的密碼

老照片中的密碼 1.題目 1.1 給出圖片如下 1.2 給出如下提示 這張老照片中的人使用的是莫爾斯電報機&#xff0c;莫爾斯電報機分為莫爾斯人工電報機和莫爾斯自動電報機&#xff08;簡稱莫爾斯快機&#xff09;。莫爾斯人工電報機是一種最簡單的電報機&#xff0c;由三個部分組…

SelfReg-UNet:解決UNet語義損失,增強特征一致性與減少冗余的優化模型

SelfReg-UNet&#xff1a;解決UNet語義損失&#xff0c;增強特征一致性與減少冗余的優化模型 提出背景拆解類比&#xff1a;整理書架語義一致性正則化內部特征蒸餾為什么 UNet 會有語義損失&#xff1f; 提出背景 論文&#xff1a;https://arxiv.org/pdf/2406.14896 代碼&…

c++內存管理_復習

new與placement new new&#xff1a; 先調用operator new(大小)&#xff0c;而operator new()會調用malloc嘗試分配內存&#xff0c;失敗則調用_callnewh()來釋放內存&#xff0c;直至分配成功 可以設置分配失敗的處理函數&#xff1a;將寫好的處理函數作為參數傳入set_new_han…

Vue3 使用 Vue Router 時,params 傳參失效

前言&#xff1a; 在寫項目的時候&#xff0c;使用了 vue-router 的 params 進行傳參&#xff0c;但是在詳情頁面中一直獲取不到參數。原因&#xff1a;Vue Router 在2022-8-22的那次更新后&#xff0c;使用這種方式在新頁面上無法獲取&#xff01; 正文&#xff1a; 在列表頁進…

deeplabcut

import pandas as pd import h5py import pickle import json import os # 讀取 CSV 文件 csv_file_path /mnt/data/CollectedData_dlc.csv csv_data pd.read_csv(csv_file_path) # 讀取 H5 文件 h5_file_path /mnt/data/CollectedData_dlc.h5 with h5py.File(h5_file_pat…

LeetCode題練習與總結:只出現一次的數字Ⅱ--137

一、題目描述 給你一個整數數組 nums &#xff0c;除某個元素僅出現 一次 外&#xff0c;其余每個元素都恰出現 三次 。請你找出并返回那個只出現了一次的元素。 你必須設計并實現線性時間復雜度的算法且使用常數級空間來解決此問題。 示例 1&#xff1a; 輸入&#xff1a;n…

K8S日常運維手冊

Kubernetes&#xff08;簡稱 K8S&#xff09;是一種廣泛使用的容器編排平臺&#xff0c;能夠自動化部署、擴展和管理容器化應用。對于運維人員來說&#xff0c;掌握 Kubernetes 的日常運維技能是確保系統穩定運行的關鍵。本文將介紹一些 Kubernetes 日常運維的基本操作與技巧&a…

虛擬機裝入kali linux

VMware 首先需要先安裝VMware Workstation Pro可以根據這篇文章來下載VMware 下載kali linux Installer Images VS Virtual Machines Installer Images&#xff08;安裝鏡像&#xff09;Virtual Machines&#xff08;虛擬機&#xff09; 直接訪問硬件&#xff0c;定制內核…

Matlab|【防騙帖】考慮時空相關性的風電功率預測誤差建模與分析

目錄 1 主要內容 2 部分程序 3 下載鏈接 1 主要內容 這個程序《考慮時空相關性的風電功率預測誤差建模與分析》畫的圖片非常漂亮&#xff0c;和原文獻基本一致&#xff0c;但是實際上內容并未實現出來&#xff0c;主要就是利用現有的風電預測的數據和結果做了相關的圖&#…

【數據結構】(C語言):鏈表

鏈表&#xff1a; 基本單位是節點。節點至少兩部分&#xff1a;數據&#xff0c;下一個數據的地址。頭指針head&#xff0c;始終指向鏈表的第一個節點。若沒有節點&#xff0c;則headNULL。鏈表在內存中是非連續的。不能使用索引&#xff08;下標&#xff09;查找元素。只能從…

解決:Xshell通過SSH協議連接Ubuntu服務器報“服務器發送了一個意外的數據包,received:3,expected:20”

下圖所示&#xff1a; 日志也基本看不出來問題在哪&#xff0c;只是說斷開了連接大概是驗證失敗。有幸在某論壇評論區找到了原因&#xff0c;是因為我的xshell版本太低了而服務器的ssh版本太高&#xff0c;高版本的ssh默認屏蔽了一部分不太安全的算法導致建立連接的時候驗證失敗…

C++ 14新特性個人總結

variable templates 變量模板。這個特性允許模板被用于定義變量&#xff0c;就像之前模板可以用于定義函數或類型一樣。變量模板為模板編程帶來了新的靈活性&#xff0c;特別是在定義泛化的常量和元編程時非常有用。 變量模板的基本語法 變量模板的聲明遵循以下基本語法&am…

解決Vue+Vite打包后Leaflet的marker圖標不顯示的問題

前言 用Leaflet寫關于WebGIS的開發&#xff0c;用Vite或者webpack打包&#xff0c;打包后會找不到圖標&#xff0c;如下所示。 直言的說&#xff0c;筆者去網上搜了搜&#xff0c;其實收到一個比較好是答案。網址如下。 &#xff08;完美解決~&#xff09;關于VueLeaflet添加…

eslint 與 prettier 的一些常見的配置項(很詳細)

目錄 1、eslint 常見配置項&#xff08;語法規范&#xff09; 2、 prettier 常見的配置項&#xff08;格式規范&#xff09; 代碼規范相關內容看小編的該文章&#xff0c;獲取對你有更好的幫助 vsCode代碼格式化&#xff08;理解eslint、vetur、prettier&#xff0c;實現格式…

IDEA啟動報錯:Abnormal build process termination...

一、問題描述 因為項目需要&#xff0c;同時打開了兩個idea&#xff0c;突然發現一個啟動的時候報錯&#xff0c;有點莫名其妙&#xff0c;剛還好好的&#xff0c;為啥就不能用了&#xff0c;一頓百度找方法&#xff0c;試了各種方法&#xff0c;像重新安裝jdk、重啟系統發現都…

TensorFlow開源項目

歡迎來到 Papicatch的博客 文章目錄 &#x1f349;TensorFlow介紹 &#x1f349;主要特點和功能 &#x1f348;多語言支持 &#x1f348;靈活的架構 &#x1f348;分布式訓練 &#x1f348;跨平臺部署 &#x1f348;強大的工具鏈 &#x1f348;豐富的社區和生態系統 &a…