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