網站目錄文件查看在線一鍵免費生成網頁網站
計算機基礎
計算機的組成
輸入設備、輸出設備、存儲器、運算器、控制器
- 輸入設備:將其他信號轉換為計算機可以識別的信號(電信號)。
- 輸出設備:將電信號(0、1)轉為人或其他設備能理解的信號。
- 運算器:CPU對信息處理和運算的部件,常進行算術運算和邏輯運算,其核心是算術邏輯單元ALU,CPU中用各種各樣的數(shù)字電路搭配成各種各樣的運算電路,如:加、減法等。
- 控制器:整個計算機的指揮中心
- 存儲器:存放程序和數(shù)據(jù)的部件,也是計算機能夠實現(xiàn)“存儲程序控制”的基礎。
程序:指令的有序集合
ROM: flash (EMMC)、磁盤空間 、掉電不丟失數(shù)據(jù)
只讀存儲器_百度百科
RAM: 內存、掉電丟失數(shù)據(jù)
隨機存取存儲器_百度百科
IO邏輯(輸入/輸出)
計算機系統(tǒng)中的高低電平邏輯1和0,數(shù)據(jù)在計算機中的存儲、傳輸、運算都是以二進制形式進行的。
數(shù)據(jù)的傳輸通過總線真正傳遞的是電信號,高低電平(0、1)。運算在電路中進行,集成電路中運算。
電壓:電壓差 電勢差
模擬信號:模擬信號是連續(xù)的,模擬信號可以是任意數(shù)值狀態(tài);
數(shù)字信號:數(shù)字信號是離散(不連續(xù))的,數(shù)字信號只有“0”和“1”兩種狀態(tài)
三級存儲結構
cache: 速度快、價格貴、容量小、斷電丟失、CPU可以直接訪問。存儲當前正在執(zhí)行的程序中的活躍部分,以便快速地向CPU提供指令和數(shù)據(jù)
基本原理:
高速緩存Cache詳解(西電考研向)_多路組相聯(lián)-CSDN博客
主存儲器:速度、價格、容量介于CACHE和輔助存儲器之間、斷電丟失、CPU可以直接訪問。存儲當前正在執(zhí)行的程序和數(shù)據(jù)
輔助存儲器:速度慢、價格低、容量大、斷電不丟失、cpu不可以直接訪問。存儲暫時不運行的程序和數(shù)據(jù),需要時再傳送到主存
Cache對程序員來說一般會有透明性,也就是程序員其實是看不到Cache的,因此不能對它進行操作。
總線
總線(Bus)是計算機各種功能部件之間傳送信息的公共通信干線,它是由導線組成的傳輸線束, 按照計算機所傳輸?shù)男畔⒎N類,計算機的總線可以劃分為數(shù)據(jù)總線、地址總線和控制總線,分別用來傳輸數(shù)據(jù)、數(shù)據(jù)地址和控制信號(系統(tǒng)總線)。
數(shù)據(jù)總線
(1)是CPU與內存或其他器件之間的數(shù)據(jù)傳送的通道。
(2)數(shù)據(jù)總線的寬度決定了CPU和外界的數(shù)據(jù)傳送速度。
(3)每條傳輸線一次只能傳輸1位二進制數(shù)據(jù)。如: 8根數(shù)據(jù)線一次可傳送一個8位二進制數(shù)據(jù)(即一個字節(jié))。
(4)數(shù)據(jù)總線是數(shù)據(jù)線數(shù)量之和。
地址總線
(1)CPU是通過地址總線來指定存儲單元的。
(2)地址總線決定了cpu所能訪問的最大內存空間的大小。如: 10根地址線能訪問的最大的內存為1024位二進制數(shù)據(jù)(1024個內存單元)
(3)地址總線是地址線數(shù)量之和。
控制總線
(1)CPU通過控制總線對外部器件進行控制。
(2)控制總線的寬度決定了CPU對外部器件的控制能力。
(3)控制總線是控制線數(shù)量之和。
總結:
數(shù)據(jù)總線的寬度決定CPU與其他元器件一次最大傳送的數(shù)據(jù)量;
地址總線的寬度決定CPU的尋址能力;
控制總線決定CPU對其他元器件的控制能力。
例子
DMA總線
DMA(Direct Memory Access)即直接存儲器訪問,使用DMA總線可以不通過CPU直接在存儲器及外設之間進行數(shù)據(jù)傳遞。(不做控制功能)
單片機基礎
單片機簡介
單片機(Single-Chip Microcomputer)是一種集成電路芯片。
微控制單元(Microcontroller Unit;MCU) ,又稱單片微型計算機(Single Chip Microcomputer )或者單片機,其采用集成電路技術將具有數(shù)據(jù)處理能力的中央處理器CPU、隨機存儲器RAM、只讀存儲器ROM、定時器/計時器、多種I/O口和中斷系統(tǒng)等功能集成到一塊硅片上??梢哉f單片機就是一個小而完善的微型計算機系統(tǒng)。
https://www.bilibili.com/video/BV1HW411a7SS/?spm_id_from=333.337.search-card.all.click&vd_source=2820d6227cdfd0cc24c48e011da53b66
SoC(System on Chip),片上系統(tǒng)SoC的定義多種多樣,由于其內涵豐富、應用范圍廣,很難給出準確定義。一般說來, SoC稱為系統(tǒng)級芯片,也有稱片上系統(tǒng),意指它是一個產品,是一個有專用目標的集成電路,其中包含完整系統(tǒng)并有嵌入軟件的全部內容。同時它又是一種技術,用以實現(xiàn)從確定系統(tǒng)功能開始,到軟/硬件劃分,并完成設計的整個過程。SoC就是定制功能版本的MCU
百度百科
單片機型號
51單片機(8051)
STC89C51 宏晶科技 STC AT89C51 ATMEL
宏晶科技公司
宏晶科技_百度百科
ATMEL公司
ATMEL公司_百度百科
32單片機
STM32 意法半導體ST GD32 兆易創(chuàng)新GD
32位處理器 - 處理數(shù)據(jù)寬度是32位的。
處理器位數(shù):CPU單次運算最大處理的數(shù)據(jù)位數(shù)
意法半導體
意法半導體_百度百科
兆易創(chuàng)新
兆易創(chuàng)新科技集團股份有限公司_百度百科
開發(fā)板/最小系統(tǒng)板
開發(fā)板通常是學習用途,功能比較全,接口豐富,是用于研發(fā)、研究、學習的一塊板子。
STM32U5開發(fā)板介紹
最小系統(tǒng)板是個核心板,集成了核心的通用功能,可以根據(jù)需求定制各種不同的底板,通用性較好。再者核心板作為一塊獨立的模塊被分離出來,也降低了開發(fā)的難度,增加了系統(tǒng)的穩(wěn)定性和可維護性通常用于做項目,也可以作為模塊在產品里在直接用。
STM32
簡介
https://www.st.com.cn/zh/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus.html
STM32 | 產品 | STM32 | MCU單片機 | 意法半導體STM | STMCU中文官網
STM32是意法半導體公司生成一款32位的微控制器。
STM32功能強大、性能優(yōu)異、片上資源豐富、功耗低、是一款經典的嵌入式微控制器。
命名規(guī)范
ST | 意法半導體 |
M | 微控制器 |
32 | 32位處理器 |
類型 | F 通用/基礎型 foundation G 多用途型 general-purpose L 低功耗 low power H 高性能 High performance S 簡單/標準型 Standard U超低功耗 |
系列 | 0 精簡系列 1/2/3 增強系列 4/7 高性能系列 |
子型號 | 00/01/02/03/05/07 |
引腳數(shù)量 | K/6-32腳 C/8-48腳 R-64腳 V-100腳 Z-144腳 A-168腳 I-176腳 B-208腳 N-216腳 |
存儲量 | 6 : 32KB 8 : 64KB B :128KB C :256KB D : 384KB E : 512KB G : 1MB I : 2MB |
封裝 | U - UQFN封裝 T - TQFP封裝 |
工作溫度 | 6 - -40 ~ 85度 |
STM32的優(yōu)勢
STM32 | 產品 | STM32 | MCU單片機 | 意法半導體STM | STMCU中文官網
產品型號豐富,可選擇性強;
運算速度快,功耗低;
處理器外設接口豐富;
庫函數(shù)開發(fā)體系學習資料多,應用廣泛。
ARM體系結構
STM32G030采用ARM Cortex-M0+內核架構
STM32U575采用ARM Cortex-M33內核架構
M33內核詳情:
https://www.st.com.cn/content/st_com/zh/arm-32-bit-microcontrollers/arm-cortex-m33.html
想了解其他架構請點擊下方鏈接
馮·諾依曼架構&哈佛架構(嵌入式學習)_馮諾依曼架構-CSDN博客
認識ARM
- ARM代表一個公司
安謀國際科技股份有限公司_百度百科
ARM是一家公司,ARM公司是一家芯片知識產權(IP)供應商,它與一般的半導體公司最大的不同就是不制造芯片且不向終端用戶出售芯片,而是通過轉讓設計方案,由合作伙伴生產出各具特色的芯片。
- ARM可以表示一些處理器的統(tǒng)稱
早期經典處理器:ARM7 ARM9 ARM11
后續(xù)處理器開始以cortex命名
Cortex-X系列
超高性能
Cortex-A系列
針對開放式操作系統(tǒng)的高性能處理器
應用于智能手機、數(shù)字電視、智能平板等高端運用
Cortex-R系列
提供非常高的性能和吞吐量,同時保持精準的時序屬性和可預測的中斷延時,通常用于時序關鍵的應用中
針對實時系統(tǒng)、滿足實時性的控制需求
應于汽車制動系統(tǒng)、動力系統(tǒng)等
Cortex-M系列
為單片機驅動的系統(tǒng)提供了低成本優(yōu)化方案
應用于傳統(tǒng)的微控制器市場、智能傳感器、汽車周邊、物聯(lián)網設備等
- ARM表示一種指令集
指令:能夠指示處理器執(zhí)行命令稱為指令 + - << >>
指令集:處理器能夠識別的指令的集合稱為指令集
ARM指令集:所有指令(機器碼),都專用32bit存儲空間,代碼靈活,指令簡潔,執(zhí)行ARM指令PC每次自加4
Thumb指令集:所有指令(機器碼),都專用16bit存儲空間,代碼靈活,指令簡潔,執(zhí)行ARM指令PC每次自加2
ARM的命名有指令集架構、 處理器架構、 處理器型號三類命名規(guī)則
架構:
arm-v4,arm-v5,arm-v6,arm-v7(32Bits),arm-v8(64Bits)
架構指支持的匯編指令集(不同架構,匯編指令集不同)
問:目前主流處理器架構?
ARM架構、Intel X86/X64架構、MIPS架構、RISC-V(開源)
指令集(RISC和CISC)
精簡指令集(RISC)-->微處理器
只保留常用的的簡單指令,硬件結構簡單,復雜操作一般通過簡單指令的組合實現(xiàn),一般指令長度固定,且多為單周期指令。
RISC處理器在功耗、體積、價格等方面有很大優(yōu)勢,所以在嵌入式移動終端領域應用極為廣泛
舉例:如有加法運算器 ,沒有乘法運算器 3*3 ---》3+3+3
復雜指令集(CISC)-->電腦CPU
不僅包含了常用指令,還包含了很多不常用的特殊指令,硬件結構復雜,指令條數(shù)較多,一般指令長度和周期都不固定
CISC處理器在性能上有很大優(yōu)勢,多用于PC及服務器等領域
Cortex-M33的寄存器
(1)通用寄存器
R0-R12:13個通用寄存器。其中 R0-R7為低端寄存器,可作為16位或32 位指令操作數(shù),R8-R12為高端寄存器,只能用作32位操作數(shù)
R13:棧指針寄存器 SP(the stark pointer),它用于訪問堆棧內存(例如,堆棧PUSH或POP操作)。
R14:鏈接寄存器LR(the link register),用于存儲子程序或者函數(shù)調用的返回地址
R15:程序計數(shù)器PC(the program counter register)存儲下一條將要執(zhí)行的指令的地址。
(2)特殊寄存器
xPSR:組合程序狀態(tài)寄存器,該寄存器由三個程序狀態(tài)寄存器組成
應用程序狀態(tài)寄存器 (APSR):保存程序計算結果的狀態(tài)標志 N負數(shù)標志 Z零標志 C進位借位標志 V溢出標志
中斷程序狀態(tài)寄存器 (IPSR):包含當前ISR(中斷服務程序)的異常編號
執(zhí)行程序狀態(tài)寄存器 (EPSR):包含Thumb狀態(tài)位
CONTROL:控制寄存器
控制處理器處于線程模式時,使用哪個堆棧
=0,使用MSP 處理器模式時,固定使用MSP
=1,使用PSP
CPU運行原理
根據(jù)下載的程序運行,程序是指令的有序集合
一條指令(機器碼)的執(zhí)行通常分為三個階段:
1)取指:控制器將PC寄存器中的值發(fā)送給內存,內存將對應地址中的指令(機器碼)傳送回CPU的指令寄存器IR中
2)譯碼:指令譯碼器對IR中的指令進行識別,將指令(機器碼)解析(翻譯)成具體的運算操作(+/-/*...)
3)執(zhí)行:控制器控制運算器中對應的運算單元進行運算,運算結果寫入寄存器
注意:PC每取地址一次,自加一次。PC的值自動增加使PC指向內存中的下一條指令
思考:
1.運算器不同,處理指令不同。不同的處理器上如何運行同一個c語言程序?
- 假設指令集有乘法指令,結果并沒有乘法運算器,怎么辦?
指令流水線
指令的執(zhí)行是按照流水線
取指--》取指器 根據(jù)PC值取指令
譯碼--》譯碼器
執(zhí)行--》執(zhí)行器
以上三個器件,都是單周期的器件,三個器件的工作是獨立
指令1 指令2 指令3 指令4 指令5
1 取指
2 譯碼 取指
3 執(zhí)行 譯碼 取指
4 執(zhí)行 譯碼 取指
5 執(zhí)行 譯碼 取指
6 執(zhí)行 譯碼
7 執(zhí)行
PC永遠指向當前取指指令的地址,一旦取到指令,pc后移4byte,保存下一條指令地址。
指令流水線機制的引入確實能夠大大的提升指令執(zhí)行的速度,但在實際執(zhí)行程序的過程中很多情況下流水線時是無法形成的,比如芯片剛上電的前兩個周期、執(zhí)行跳轉指令后的兩個周期等。
所以指令流水線的引入以及優(yōu)化只能使平均指令周期不斷的接近1而不可能真正的達到1,且流水線級數(shù)越多芯片設計的復雜,程度就越高,芯片的功耗就越高。
編譯原理
gcc編譯流程分為四個步驟:
1:預編譯處理:主要是進行宏替換和拷貝包含的頭文件到本文件
2:編譯:檢查代碼的規(guī)范性,是否有語法錯誤等,沒錯的話將代碼編譯成匯編語言
3:匯編:將匯編文件轉換成二進制目標文件
4:鏈接:鏈接庫函數(shù)生成可執(zhí)行文件
機器碼(二進制)是處理器能直接識別的語言,不同的機器碼代表不同的運算指令,處理器能夠識別哪些機器碼是由處理器的硬件設計所決定的,不同的處理器機器碼不同,所以機器碼不可移植
匯編語言是機器碼的符號化,即匯編就是用一個符號來代替一條機器碼,所以不同的處理器匯編也不一樣,即匯編語言也不可移植
C語言在編譯時我們可以使用不同的編譯器將C源碼編譯成不同架構處理器的匯編,所以C語言可以移植
ARM的數(shù)據(jù)類型
char(字節(jié)):8位
halfword(半字):16位
word(全字):32位
doubleword:64位(cortex-a)
quadword:128位(ARM-v8)
ARM-v7架構:32bit處理器
ARM-v8架構:64bit處理器
處理器的32位和64位什么含義?
32位:一條指令可以進行32位數(shù)據(jù)的運算
64位:一條指令可以進行64位數(shù)據(jù)的運算
字節(jié)序
大端對齊
低地址存到高地址,高地址存放到低地址
小端對齊
低地址存到低地址,高地址存放到高地址
注:ARM一般使用的是小端對齊
ARMv8-M的指令集
ARM處理器支持兩種指令集:ARM 和 Thumb。
ARM指令集 32位精簡指令集; 指令長度固定;
降低編碼數(shù)量產生的耗費,減輕解碼和流水線的負擔;
Thumb指令集指令寬度16位;
Thumb指令集是ARM指令集的一個子集;
與32位指令集相比,大大節(jié)省了系統(tǒng)的存儲空間;(密度高)
Thumb指令集不完整,所以必須配合ARM指令集一同使用。
?Arm Cortex-M處理器中使用的指令集稱為Thumb指令集。這個指令集包含一系列擴展。Cortex-M33的指令集是Cortex-M23處理器指令集的超集。為了便于項目遷移,以前的Cortex-M處理器中可用的所有指令在Armv8-M架構中也可用。一般來說,Cortex-M處理器中的指令集提供了向上兼容的特性。例如:Cortex-M23的指令集是Cortex-M0/M0+處理器中指令集的超集。
?Cortex-M33的指令集是Cortex-M3和Cortex-M4處理器指令集的超集。除了雙精度浮點指令和緩存預加載指令外,Cortex-M7處理器支持的所有指令都可以在Cortex-M33中使用。(注:Cortex-M33沒有雙精度FPU選項或緩存存儲器控制器功能。)向上兼容性是Cortex-M處理器家族的一個重要特征,因為它提供了軟件的可重用性和可移植性。Armv8-M基線指令集中使用的許多指令的大小都是16位。這使得高代碼密度成為可能。對于一般的數(shù)據(jù)處理和控制任務,程序代碼可以主要由16位指令(而不是32位)組成,以減少程序內存的大小。
問:Thumb指令集和ARM指令集的區(qū)別?
系統(tǒng)架構
系統(tǒng)主要由以下幾個模塊組成 :
● 二個主模塊 :
– Cortex-M0+ 內核及先進高性能總線 (AHB bus)
– 通用 DMA (通用的直接存儲器存取)
● 三個從模塊 :
– 內部 FLASH
– 內部SRAM
– AHB和AHB到APB的連接橋,所有的外設都掛在APB總線上
問:flash和SRAM的區(qū)別?
Flash存儲器是一種非易失性存儲器,可以在掉電之后保存數(shù)據(jù),通常用于存儲程序代碼。Flash存儲器的可寫入次數(shù)有限,且需要執(zhí)行擦除操作才能寫入新的數(shù)據(jù),因此,在使用過程中需要注意擦寫周期和數(shù)據(jù)備份問題。
SRAM存儲器則是一種易失性存儲器,具有相對較快的讀寫速度和無限的讀寫次數(shù),但掉電時將會丟失所有內容。SRAM存儲器主要用于暫存數(shù)據(jù)和臨時變量,讀寫操作由CPU直接完成,訪問速度較快。
單片機的Flash存儲器和SRAM存儲器通常都嵌入在單片機芯片內部,能夠方便地實現(xiàn)對程序和數(shù)據(jù)的讀寫操作。通常,編譯器會將程序代碼燒錄到Flash存儲器中,并使用SRAM存儲器來存儲變量、函數(shù)堆棧和其他臨時數(shù)據(jù)。
問:什么是外設?如何理解片上外設(片上資源)?
與傳統(tǒng)的外設不同,片上外設通常具有以下優(yōu)點:
高效性:片上外設能夠與主處理器實現(xiàn)高速的數(shù)據(jù)傳輸,響應時間短,執(zhí)行效率高。
集成度高:片上外設多個模塊都嵌入到處理器芯片內部,極大地降低了PCB面積和電路復雜度。
低功耗:處理器和片上外設采用相同的工藝,能夠滿足高密度和低功耗的需求。
可靠性高:提高了整體系統(tǒng)的可靠性和穩(wěn)定性,也降低了電磁干擾的可能。
問:AHB和APB的區(qū)別?
AHB(高級高性能總線)是高速總線,是一種系統(tǒng)總線,它主要負責連接處理器、DMA等一些內部接口。AHB系統(tǒng)由主模塊、從模塊和基礎結構3部分組成,整個AHB總線上的傳輸都由主模塊發(fā)出,由從模塊負責回應。
APB(高級外設總線)是低速總線,它主要負責連接外圍設備,它又分為APB1和APB2,它的總線架構不像 AHB支持多個主模塊,在APB里面唯一的主模塊就是APB橋。
如何開發(fā)
開發(fā)環(huán)境搭建
STM32CubeMX
ST公司出品 工具鏈接
工具鏈接 https://www.st.com/zh/development-tools/stm32cubemx.html
STM32CubeMX是一種圖形工具,通過分步過程可以非常輕松地配置STM32微控制器和微處理器,以及為Arm? Cortex?-M內核或面向Arm? Cortex?-A內核的特定Linux?設備樹生成相應的初始化C代碼。
作用及功能:
(1)工程項目搭建和配置
(2)直觀選擇微控制器
(3)圖形化引腳功能配置、引腳沖突提示
(4)動態(tài)配置時鐘樹
(5)動態(tài)設置參數(shù)和初始化
Keil uVision5
Keil Product Downloads
Keil μVision 5 也稱MDK-ARM、Realview MDK
MDK ——》Microcontroller Development Kit
MDK包含以下幾個部分:
μVision5:一種集成開發(fā)環(huán)境,提供了多種不同的功能,如編輯器、編譯器、調試器等。
ARM編譯器:一種嵌入式ARM C / C++編譯器,可在多種不同的微控制器平臺上運行。
Device Family Pack:一種特定于屬于不同微控制器平臺/系列/型號的軟件包,包括庫文件、設備描述文件等。
Debugger:一款高級調試器,支持多種不同的調試功能,如單步調試、斷點調試、內存映射等。
STM32環(huán)境獲取及搭建
具體安裝步驟見以下文件
STM32環(huán)境搭建
軟件介紹
【Keil5教程及技巧】耗時一周精心整理萬字全網最全Keil5(MDK-ARM)功能詳細介紹【建議收藏-細細品嘗】-CSDN博客
匯編語言
c語言中哪些代碼可以生成匯編指令?
1》帶#號預處理,輔助編譯器怎么編譯,編譯什么內容
預處理器是C語言編譯器的一個組成部分,它在編譯代碼之前對代碼進行處理。預處理器指令以#號開頭,告訴編譯器在編譯代碼之前執(zhí)行一些操作。其中,#include指令用于將頭文件包含到源代碼中,#define指令用于定義宏。預處理器的主要作用是輔助編譯器編譯代碼。 例如在編譯時將頭文件中的函數(shù)聲明插入到源代碼中,或者將宏替換為實際的值。預處理器處理完代碼后,編譯器將生成目標代碼,最終生成可執(zhí)行文件。
2》帶;號的語句,可以編譯生成指令
在編譯器中,分號是語句結束的標志,編譯器會將分號之前的語句編譯成指令并添加到指令序列中。
匯編整體分類
1》指令:編譯完生成一條機器碼存儲在內存單元當中,CPU執(zhí)行時能完成對應的操作(類似于C中的語句)
2》偽操作(相當于c中的#的內容,告訴編譯器怎么編譯):不會生成機器碼也不會占用內存,其作用是告訴編譯器怎樣編譯(類似于C中的預處理指令)
3》偽指令:不是指令,編譯器在編譯時將其替換成等效的指令 (如:cpu中沒有乘法器,對應沒有乘法指令,3*3 ---》用加法器實現(xiàn)3+3+3,替換實現(xiàn))
匯編中注釋代碼用@或;注釋一行 ,/* */注釋一段代碼
指令分類
1.數(shù)據(jù)處理指令: 對數(shù)據(jù)進行邏輯、算數(shù)運算
2.跳轉指令: 實現(xiàn)程序的跳轉,實質是修改PC
3.Load/Store指令: 對內存的讀寫操作
4.狀態(tài)寄存器傳送指令: 對狀態(tài)寄存器進行讀寫操作
5.異常中斷產生指令: 觸發(fā)軟中斷,常用于內核的系統(tǒng)調用 //SWI:軟中斷
6.協(xié)處理器指令: 操作協(xié)處理器的指令
//如3*3 ---》用加法器實現(xiàn)3+3+3,比較慢。我們可以外接一個協(xié)處理器(乘法器)(每個協(xié)處理器的功能比較單一),協(xié)處理器指令就是操作這個協(xié)處理器的,用的比較多的cp15協(xié)處理器。
程序編寫
AREA STACK, NOINIT, READWRITE
__initial_spAREA RESET, DATA, READONLY
__Vectors DCD __initial_sp DCD main AREA |.text|, CODE, READONLYENTRY
mainloopB loop END
解釋:
1. AREA STACK, NOINIT, READWRITE: 這一行指定了一個名為STACK的內存區(qū)域,它用于存儲堆棧。NOINIT表示這個內存區(qū)域在程序啟動時不需要初始化,READWRITE表示這個內存區(qū)域可以被讀取和寫入。
2. __initial_sp: 這一行定義了一個名為`__initial_sp`的符號,它表示堆棧指針的初始值。在這里,它被定義為堆棧的起始地址。通常,這個符號會在鏈接腳本中進一步定義為實際的堆棧內存區(qū)域的起始地址。
3. AREA RESET, DATA, READONLY: 這一行指定了一個名為RESET的內存區(qū)域,用于存儲重置向量表。DATA表示這個區(qū)域包含數(shù)據(jù),READONLY表示這個區(qū)域只能被讀取。
4. __Vectors DCD __initial_sp: 這一行定義了一個重置向量表,用于指示程序啟動時應該執(zhí)行的操作。`DCD`表示存儲一個雙字(32位)的數(shù)據(jù)。在這里,第一個雙字存儲的是堆棧指針的初始值,即__initial_sp。
5. DCD main: 這一行將程序的入口地址(main函數(shù))添加到重置向量表中。這意味著程序在啟動時將跳轉到main函數(shù)開始執(zhí)行。
6. AREA |.text|, CODE, READONLY: 這一行指定了一個名為.text的內存區(qū)域,用于存儲代碼。CODE表示這個區(qū)域包含代碼,READONLY表示這個區(qū)域只能被讀取。
7. ENTRY main: 這一行指定了程序的入口點為main函數(shù)。這意味著程序將從`main`函數(shù)開始執(zhí)行。
8. loop B loop: 這一行是一個無限循環(huán),它會不斷地跳轉到`loop`標簽所在的位置,導致程序永遠循環(huán)執(zhí)行這條指令。
9. END: 這一行表示程序的結束。
數(shù)據(jù)搬移指令
MOV R0,#1 ;MOV搬移指令 相當于R0=1
MOV R1,R0 ; R1=R0
AREA STACK, NOINIT, READWRITE
__initial_spAREA RESET, DATA, READONLY
__Vectors DCD __initial_sp DCD main AREA |.text|, CODE, READONLYENTRY
mainMOV R0,#1MOV R1,R0
loopB loop END
驗證
注意:需要連接上LINK,記得先裝驅動
如果是立即數(shù),前邊必須加#
什么是立即數(shù)?
立即數(shù)的概念
立即數(shù)(Immediate Value)是在計算機編程和匯編語言中常見的一種操作數(shù)類型。它是指在指令中直接編碼的數(shù)值,而不是存儲在內存或寄存器中的值。立即數(shù)通常是常量或者由程序員明確指定的值,可以直接參與到算術運算、邏輯運算或者數(shù)據(jù)處理中,無需從其他地方讀取。
尋址方式:
尋址方式_百度百科
立即數(shù)是保存在指令中的數(shù),取指令的同時將值取過去,和普通變量的區(qū)別是,變量保存在內存中的數(shù)據(jù),需要單獨取值運算。
立即數(shù)的本質:立即數(shù)是包含在指令當中的數(shù)據(jù)(即屬于指令的一部分)
立即數(shù)的優(yōu)點:讀取指令的同時也將立即數(shù)讀取到了內存中,速度快
立即數(shù)的缺點:數(shù)量有限
注:使用mov 給寄存器里面存放值的時候,#號后面需是有效數(shù)(1:立即數(shù),2:取反之后是立即數(shù)),如果不是立即數(shù)需要用ldr指令進行存放。
LDR R0,=0X12345678
算術運算指令
MOV R0,#1
MOV R1,#2
ADD R2,R1,R0;加法---->R2=R1+R0;
SUB R2,R1,R0;減法---->R2=R1-R0;
MUL R2,R1,R0;乘法---->R2=R1*R0;
邏輯運算指令
MOV R0,#1
MOV R1,#2
MOV R2,#3
AND R3,R1,R0 ;與---->R3=R1&R0
ORR R3,R1,R0 ;或---->R3=R1|R0
EOR R3,R1,R0 ;異或---->R3=R1^R0
LSL R3,R2,R1 ;左移---->R3=R2<<R1
LSR R3,R2,R1 ;右移---->R3=R2>>R1
xPSR狀態(tài)寄存器
N (Negative) - 負標志:如果最近的算術操作的結果是負數(shù),此位被置位。
Z (Zero) - 零標志:如果最近的算術或邏輯操作的結果是零,此位被置位。
C (Carry) - 進位標志:如果最近的加法或乘法操作產生了進位,或者減法操作產生了借位,此位被置位。
V (Overflow) - 溢出標志:如果最近的有符號整數(shù)運算產生了溢出,此位被置位。
Q (Saturation) - 飽和標志:如果一個飽和運算發(fā)生了飽和,此位被置位(僅在支持飽和運算的指令集架構中有效)。
GE (Greater Equal) - 大于等于標志:這是四個位(GE[3:0]),用于比較兩個操作數(shù),分別對應無符號和有符號的比較結果。
除了這些條件碼標志,APSR還包含一些控制位,如:
I (Interrupt Disable) - 中斷禁止標志:如果被置位,硬件中斷被屏蔽。
F (Fast Interrupt Disable) - 快速中斷禁止標志:如果被置位,快速中斷(FIQ)被屏蔽。
T (Thumb) - Thumb標志:如果被置位,處理器處于Thumb狀態(tài);否則,它處于ARM狀態(tài)。
MOV R0,#1 ;指令
MOV R1,#2 ;指令
;默認情況下數(shù)據(jù)運算不會對條件位(NZCV)產生影響,我們可以在指令后添加后綴'S'
SUBS R2,R0,R1 ;加S并使用減法指令產生負數(shù),驗證N位,發(fā)現(xiàn)被置位
;測試Z和減法C位
MOV R0,#1 ;指令
MOV R1,#1 ;指令
SUBS R2,R0,R1 ;加S并使用減法指令產生0,驗證Z位,發(fā)現(xiàn)Z和C都被置1,因為減法時產生借位C會被置0,結果0沒有借位
;測試加法C位
MOV R0,#0XFFFFFFFE ;0XFFFFFFFE不是立即數(shù),但是編譯沒有報錯,看一下仿真里編譯窗口里,MOV被替換為MVN了,數(shù)也變了
MOV R1,#3
ADDS R2,R1,R0 ;加法指令產生了進位(注意這里是32位),C位被置1
;驗證V
LDR R0,=0X7FFFFFFE ;0X7FFFFFFE加了3之后產生溢出
MOV R1,#3 ;0X7FFFFFFE加了3之后產生溢出
ADDS R2,R1,R0 ;加法指令產生了進位(注意這里是32位),V位被置1
分支/跳轉指令
B (Branch):這是一個基本的無條件跳轉指令,用于將程序計數(shù)器(PC)設置為指令中指定的地址,從而跳轉到程序的其他部分執(zhí)行。語法:B <label>,其中<label>是跳轉的目標標簽。
BL (Branch with Link):這個指令不僅跳轉到指定的地址,還將當前指令的下一個指令的地址(即返回地址)保存到鏈接寄存器(LR,通常是R14)中。這允許在跳轉后通過返回指令(如MOV PC, LR)返回到跳轉前的位置。語法:BL <label>。
不保存返回地址
jump
LDR R3,=0X11111111
LDR R2,=0X22222222
LDR R1,=0X33333333
LDR R0,=0X44444444
main
LDR R0,=0X11111111
LDR R1,=0X22222222
LDR R2,=0X33333333
LDR R3,=0X44444444
LDR R4,=0X08000008
B jump
保存返回地址
jump
LDR R3,=0X11111111
LDR R2,=0X22222222
LDR R1,=0X33333333
LDR R0,=0X44444444
MOV PC,LR
main
LDR R0,=0X11111111
LDR R1,=0X22222222
LDR R2,=0X33333333
LDR R3,=0X44444444
LDR R4,=0X08000008
BL jump
LDR R0,=0X11111111
LDR R1,=0X22222222
LDR R2,=0X33333333
LDR R3,=0X44444444
load/store指令
單寄存器操作指令 ldr / str
對內存的讀寫操作,將運算結果從cpu寫到內存
LDR R1,=0XFF00FF00
LDR R2,=0X20000000
STR R1,[R2] ;把R1當中的數(shù)存到R2的地址中
LDR R3,[R2] ;把內存R2地址中的數(shù)據(jù)讀取到CPU R3寄存器中
索引形式
1> 前索引
MOV R1,#0XFFFFFFFF
MOV R2,#0X20000000
STR R1,[R2,#8] ;基址加變址尋址
講原理加法器 R2加8,如果STR R1,[R2] 也走加法器 R2+0
所以可以根據(jù)匯編的語法格式反思CPU的硬件設計
比如 int a[10] 編譯器只知道a的首地址,其他的沒統(tǒng)計,如a[6] 找地址可以a
2>后索引
MOV R1,#0XFFFFFFFF
MOV R2,#0X20000000
STR R1,[R2],#4 ; 將R1寄存器的內容存到【R2】地址,然后R2=R2+4
這樣做的目的可以做連續(xù)存儲,壓棧時用的比較多 存完一個數(shù),他就把地址自動指向下一個了
3>自動索引(前后索引)
MOV R1,#0XFFFFFFFF
MOV R2,#0X20000000
STR R1,[R2,#4]! ; 將R1寄存器的內容存到【R2+4】地址,然后R2=R2+4
LDR同樣支持三種索引方式
批量寄存器操作指令ldm/stm
將r1到r4中的值存儲到r0指向地址空間中,連續(xù)16個字節(jié)的地址空間
stm r0, {r1-r4}
LDR R1,=0X1LDR R2,=0X2LDR R3,=0X3LDR R4,=0X4LDR R0,=0X20000000STM R0!,{R1-R4}
LDR R1,=0X1LDR R2,=0X2LDR R3,=0X3LDR R4,=0X4LDR R0,=0X20000000STM R0!,{R1-R3,R4}
LDR R1,=0X1LDR R2,=0X2LDR R3,=0X3LDR R4,=0X4LDR R0,=0X20000000STM R0!,{R1,R3,R2,R4}
棧的操作指令 stmfd / ldmfd
棧的種類
空棧(Empty)
棧指針指向的地址是空的,在棧中存儲數(shù)據(jù)時,可以直接存儲,存儲完成之后需要將棧指針再次指向空的位置。
滿棧(Full)
棧指針指向的地址有數(shù)據(jù),在棧中存儲數(shù)據(jù)時,需要先將棧指針,指向一個空的位置,然后在存儲數(shù)據(jù)。
增棧(Ascending)
棧指針向高地址方向移動
減棧(Descending)
棧指針向低地址方向移動
操作棧的方式
滿增棧,滿減棧,空增棧,空減棧
FA:Full Ascending 滿增
FD:Full Descending 滿減
EA:Empty Ascending 空增
ED:Empty Descending 空減
ARM默認采用的是滿減棧
stmfd/ldmfd<code> sp!, {寄存器列表}
stmfd sp!, {r1-r4}(寫) (壓棧)
ldmfd sp!, {r0-r3}(讀) (出棧)
LDR R1,=0X11111111
LDR R2,=0X22222222
LDR R3,=0X33333333
LDR R4,=0X44444444
ADD SP,SP,#0X100 ;將棧指針地址增加,默認是0X20000000
STMFD SP!,{R1-R4} ;壓棧
LDMFD SP!,{R0-R3} ;出棧
程序中運用
stmfd sp!, {r1-r4,lr}(寫) (壓棧)
ldmfd sp!, {r1-r4,pc}(讀) (出棧) //r1-r4出棧給r1-r4, 將lr的值出棧給pc
MY_ADD
STMFD SP!,{R1-R4,LR} ;壓棧
LDR R1,=6
LDR R2,=8
ADD R5,R1,R2
LDMFD SP!,{R1-R4,PC} ;出棧
main
LDR R1,=0X11111111
LDR R2,=0X22222222
LDR R3,=0X33333333
LDR R4,=0X44444444
ADD SP,SP,#0X100 ;將棧指針地址增加,默認是0X20000000
BL MY_ADD
ADD R5,R1,R2
push/pop指令
JUMP
PUSH {R1-R4,LR} ;壓棧
LDR R1,=0X11111111
POP{R0-R3,PC} ;出棧main
LDR R1,=0X11111111
LDR R2,=0X22222222
LDR R3,=0X33333333
LDR R4,=0X44444444
ADD SP,SP,#0X100 ;將棧指針地址增加,默認是0X20000000
BL JUMP
-棧的應用-》葉子函數(shù)的調用過程
葉子函數(shù)是指一個函數(shù)內部沒有調用其他函數(shù)的函數(shù),也就是說,它是程序調用樹的末端節(jié)點,不依賴于其他函數(shù)。
F
PUSH {R1,R2,LR} ;壓棧
MOVS R1,#5
MOVS R2,#4
ADDS R3,R1,R2
POP{R1,R2,PC} ;出棧main
ADD SP,SP,#0X100
MOVS R1,#3
MOVS R2,#2
BL F
ADDS R3,R1,R2
T
B T
-棧的應用-》非葉子函數(shù)的調用過程
非葉子函數(shù)是指一個函數(shù)內部調用了其他函數(shù)的函數(shù),也就是說,它不是程序調用樹的末端節(jié)點,可以被其他函數(shù)調用。
F
PUSH {R1,R2,LR} ;壓棧
MOVS R1,#5
MOVS R2,#4
BL D
ADDS R3,R1,R2
POP{R1,R2,PC} ;出棧
D
PUSH {R1,R2,LR} ;壓棧
MOVS R1,#7
MOVS R2,#6
ADDS R3,R1,R2
POP{R1,R2,PC} ;出棧
main
ADD SP,SP,#0X100
MOVS R1,#3
MOVS R2,#2
BL F
ADDS R3,R1,R2
T
B T
專用寄存器操作指令(了解)
ADD SP,SP,#0X100
MOVS R1,#3
MOVS R2,#2
MRS R3,PSR ;讀PSR的內容
LDR R4,=0XF0123456
MSR PSR,R4 ;向PSR寫內容
MRS R3,PSR
異常中斷產生指令(了解)
不講,因為咱們用不到 一般用到的人寫內核的
CPU執(zhí)行完這個指令后產生一個軟中斷
協(xié)處理器指令(了解)
操作協(xié)處理器的指令(一般用不到-----協(xié)助cpu處理數(shù)據(jù))
1.數(shù)據(jù)運算
2.內存訪問
3.與主處理器通信
MRC 將協(xié)處理器中寄存器的內容讀取到ARM處理器的寄存器中
MCR 將ARM理器中寄存器的內容讀取到協(xié)處理器的寄存器中
協(xié)處理器指令
- 協(xié)處理器數(shù)據(jù)運算指令
CDP
- 協(xié)處理器儲存器訪問指令
STC 將協(xié)處理器中的數(shù)據(jù)儲存到存儲器
LDC 將存儲器中的數(shù)據(jù)讀取到協(xié)處理器中
- 協(xié)處理器寄存器傳送指令
MRC 將協(xié)處理器中寄存器的數(shù)據(jù)傳送到ARM處理器中的寄存器
MCR 將ARM處理器寄存器中的數(shù)據(jù)讀取到協(xié)處理器寄存器中
偽指令
本質:本身不是指令,但是cpu替換成等效的操作。
舉例1:
延時一個指令周期(耗時一條指令的時間) (cpu沒有這個指令)
NOP ;執(zhí)行NOP和MOV R0,R0一個效果,執(zhí)行NOP,cpu替換成MOV R0,R0
MOV R0,R0
舉例2:
LDR的兩種形式
;->指令
LDR R1,[R2]
;->偽指令
LDR R1,=0x12345678 ;R1 = 0x12345678
;可以將任何一個32bit的數(shù)據(jù)放入寄存器
偽操作
指令是arm公司規(guī)定的,而偽操作是編譯器規(guī)定的,不同的編譯器偽操作指令不同。
(后期我們學的linux,用linux的編譯器)