娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

【嵌入式開發】 ARM 匯編 (指令分類 | 偽指令 | 協處理器訪問指令)

發布者:溫馨生活最新更新時間:2024-10-18 來源: cnblogs關鍵字:ARM  匯編  偽指令  協處理器  訪問指令 手機看文章 掃描二維碼
隨時隨地手機看文章

一. ARM 匯編概述

1. 匯編使用位置


匯編位置 : 

-- 啟動代碼 : Bootloader 初始化時對 CPU 和 協處理器 等進行初始化, 此時沒有建立起 C 語言運行環境, 這個時候使用匯編語言執行初始化操作;

-- 效率要求 : 匯編效率高, Linux 內核中, 對效率有特殊要求的地方需要匯編;


2. 匯編分類

(1) ARM 標準匯編


ARM 標準匯編簡介 : 

-- 使用場景 : 適用于ARM公司的匯編器, 適合在 Windows 平臺使用, 如ADS;


(2) GNU匯編

GNU 匯編簡介 : 

-- 使用場景 : 適用于 Linux 平臺交叉編譯工具鏈的匯編器;


3. ARM 匯編程序框架

ARM 匯編框架 : 

-- ARM 匯編框架示例 : 


.section .data
	< 初始化的數據>
.section .bss
	< 未初始化的數據>
.section .text
.global _start
_start:
	<匯編代碼>

-- 程序入口 : '_start:' 是匯編程序的入口, 相當于 main();


-- 標注入口 : 使用 '.global _start' 標注程序入口, 外部才可以識別這是程序入口;

-- 標明代碼段 : '.section .text' 標明這是一個代碼段;

-- 標明 bss 段 : 使用 '.section .bss' 標明bss段, 如果沒有 bss 段 和 數據段, 直接從 .text 開始;


4. 搭建匯編開發調試環境

(1) 匯編程序準備


程序代碼 : 

-- 定義代碼段 : .text ;

-- 定義程序入口 : .globl _start;

-- 代碼示例 : 


.text
.globl _start
_start:
	mov r1,#1
	mov r2,#2
	mov r3,#3


Makefile 代碼 :

-- 鏈接 elf 格式文件 : 設置程序起始位置 6410板子是 0x50008000 地址;

-- 在 arm-linux-ld 指定程序起始地址 : 在 -Ttext 50008000 即可;

-- 如果使用鏈接器腳本指定地址 : 注意第三行指定程序起始地址;


SECTIONS
{
	. = 0x50008000;

	. = ALIGN(4);
	.text :
	{
		led.o	(.text)
		*(.text)
	}

	. = ALIGN(4);
	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }

	. = ALIGN(4);
	.data : { *(.data) }


	. = ALIGN(4);
	.bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
}


-- 代碼示例 : 


all:start.o
	arm-linux-ld -Ttext 0x50008000 -o start.elf $^

%.o:%.S
	arm-linux-gcc -g -o $@ $^ -c

clean:
	rm -rf *.o *.elf

(2) 啟動 JLink 調試

JLink 調試啟動 : 

-- 確保驅動安裝 : 注意 要安裝 Windows 驅動;

-- 連接 JLink : 虛擬機右下角連接 JLink;


-- 啟動 JLinkGDBServer : 

[root@localhost JLink_Linux_V434a]# ./JLinkGDBServer 
SEGGER J-Link GDB Server V4.34a

JLinkARM.dll V4.34a (DLL compiled Aug 31 2011 11:51:40)

Listening on TCP/IP port 2331

J-Link connected
Firmware: J-Link ARM V8 compiled Aug 24 2011 17:23:32
Hardware: V8.00
S/N: 17935099
Feature(s): RDI,FlashDL,FlashBP,JFlash

J-Link found 2 JTAG devices, Total IRLen = 5
JTAG ID: 0x07B76F0F (ARM11)


(2) eclipse 調試環境


搭建 eclipse 調試環境 : 

-- 導入工程 : 選擇 Makefile Project With Existing Code;


-- 選擇導入的代碼位置 : 


-- clean 代碼 : 選擇 'Project' --> 'Clean';


-- build 工程 : 選擇 '菜單' --> Project --> Build All 選項即可;

-- 配置 Debug 調試參數 : 




-- 執行調試 : F6 單步調試走兩步, 可以再 Register 視圖中查看寄存器的值, 可以看到 r1 和 r2 被賦值為 1 和 2 了;



二. ARM 指令分類

ARM 匯編手冊 : 



GNU 匯編 與 ARM 標準匯編區別 : 上面的手冊是 ARM 標準匯編手冊, 我們寫的是 GNU 匯編手冊, 有一定區別;

-- 大小寫區別 : ARM 標準匯編 都是大寫的, GNU 匯編可以是小寫字母;


1. 算術和邏輯指令

(1) MOV 指令


MOV 指令簡介 : 賦值操作;

-- 語法格式 : MOV , ;

-- 語法解析 : dest 是目的寄存器, op1 可以是立即數, 也可以是寄存器, 地址等, 等價于 dest = op1;


匯編程序注釋 : 匯編中使用 '@' 符號添加注釋;


示例代碼 : 


.text
.global _start
_start:

@mov 指令范例
mov r1, #8	@將 8 賦值給 r1
mov r2, r1	@將 r1 中的值賦值給 r2
mov r3, #10	@將 10 賦值給 r3 寄存器


(2) MVN 指令


MVN 指令簡介 : 取反賦值操作;

-- 語法格式 : MVN , ;

-- 語法解析 : 將操作數 op1 取反后 賦值給 dest;


指令示例 : 

-- 代碼 : 


.text
.global _start
_start:

@mvn 指令范例
mvn r1, #0b10	@0b10 二進制數取反, 賦值給 r1
mvn r2, #5	@5 十進制數取反, 賦值給 r2
mvn r3, r1	@將 r1 寄存器的值, 賦值給 r3

(3) SUB 指令

SUB 指令簡介 : 減法操作;

-- 語法格式 : SUB , , ;

-- 語法解析 : dest 存放減法結果, op1 是減數, op2 是被減數, dest = op1 - op2;

-- 注意 : dest op1 都不能使用立即數, op2 可以使用立即數;


代碼示例 : 


.text
.global _start
_start:

@sub 指令范例
@sub r1, #4, #2 錯誤示例, 減數不能是立即數, 必須是寄存器
mov r2, #4
sub r1, r2, #4
mov r0, #1
sub r3, r1, r0

(4) ADD 指令


ADD 指令簡介 : 加法操作;

-- 語法格式 : ADD , , ;

-- 語法解析 : dest 存放加法結果, op1 和 op2 是相加的兩個數, dest = op1 + op2;

-- 注意 : dest op1 都不能使用立即數, op2 可以使用立即數;


代碼示例 : 


@add 指令范例
mov r2, #1
add r1, r2, #3


(5) AND 指令


AND 指令簡介 : 邏輯與操作;

-- 語法格式 : AND , , ;

-- 語法解析 : dest 存放邏輯與結果, op1 和 op2 是相與的兩個數, dest = op1 & op2;

-- 注意 : dest op1 都不能使用立即數, 必須使用寄存器, op2 可以使用立即數;


代碼示例 : 


.text
.global _start
_start:

@and 指令范例
mov r1, #5
and r2, r1, #0

mov r1, #5
mov r2, r1, #1


(6) BIC 指令

BIC 指令簡介 : 位清除指令操作;

-- 語法格式 : AND , , ;

-- 語法解析 : dest 存放位清除結果, op1 是被清除的對象, op2 是掩碼;

-- 示例 : 'bic r0, r0, #0b1011', 清除 r0 中的 第0, 1, 3 位, 其余位保持不變, 結果放入 r0 中;

-- 注意 : dest op1 都不能使用立即數, 必須使用寄存器, op2 可以使用立即數; 

-- 二進制表示 : 掩碼中 % 在標準匯編中表示二進制, 但是在 GNU 匯編中無法使用, GNU 匯編中使用 0b 代表二進制;


代碼示例 : 


.text
.global _start
_start:

@bic 指令范例
mov r1, #0b101011
bic r2, r1, #0b101	@將r1 的 0, 2 位清除

2. 比較指令

(1) CMP 指令


CMP 指令簡介 : 比較指令;

-- 語法格式 : CMP , ;

-- 語法解析 : 比較結果有三種 op1 > op2 (CPSR N = 0), op1 = op2 (CPSR Z = 1), op1 < op2 (CPSR N = 1), 結果放入 CPSR 寄存器;


代碼示例 : 


.text
.global _start
_start:

@cmp 指令范例
mov r1, #2
cmp r1, #1

mov r1, #2
cmp r1, #3

mov r1, #2
cmp r1, #2

(2) TST 指令


TST 指令簡介 : 比較指令;

-- 語法格式 : TST , ;

-- 語法解析 : op1 和 op2 按位與操作, 結果影響 CPSR 寄存器, 如果結果 不為 0, CPSR 的 Z = 0, 如果結果為0, Z = 1;


代碼示例 : 


.text
.global _start
_start:

@cmp 指令范例
mov r1, #0b101
tst r1, #0b001	@按位與結果是 0b1, 結果不為0, CPSR Z = 0

mov r1, #0b101
tst r1, #0b10	@按位與結果是 0, 結果不為

3. 分支指令


(1) B 指令


B 指令簡介 : 分支指令;

-- 語法格式 : B{條件} 地址;

-- 語法解析 : 如果滿足條件, 就跳轉到 地址 位置, 如果不滿足條件, 就執行下面的語句, 如果沒有條件, 就是 100% 執行;;


代碼示例 : 

-- 條件分析 : gt 是大于條件, 如果 r1 > r2 就走條件分支, 否則就繼續執行下一條;


.text

.global _start

_start:


@b 分支指令范例

mov r1, #6

mov r2, #5

cmp r1, r2 @比較 r1 和 r2 中的值

@b 后可以跟一個條件, {條件} 在 {} 中就是可加可不加, 如果沒有條件就是無條件100%執行

@gt 是大于條件指令, 如果條件滿足會跳轉到 branch1, 如果不滿足就執行下面的指令

bgt branch1

add r3, r1, r2

b end @這里為了不執行 branch1 操作, 直接跳轉到 end 執行


branch1:

sub r3, r1, r2


end:

nop


(2) BL 指令

BL 指令簡介 : 帶連接的分支指令;

-- 語法格式 : BL{條件} 地址;

-- 語法解析 : 如果滿足條件, 就跳轉到 地址 位置, 如果不滿足條件, 就執行下面的語句, 如果沒有條件, 就是 100% 執行;;


代碼示例 : 


.text

.global _start

_start:


@bl 帶連接的分支指令范例

mov r1, #2

cmp r1, #1

@此時跳轉到 func1, func1 執行完程序無法返回, 如果 使用 bl 跳轉, 程序會返回

@b func1

@此時使用 bl 跳轉到 func1 執行, func1 執行完畢后會返回執行下面的語句

bl func1


mov r1, #2

cmp r1, #3


func1:

mov r1, #2

cmp r1, #2


mov r1, #4

cmp r1, #6


4. 移位指令


(1) LSL 指令


LSL 指令簡介 : 邏輯左移指令;

-- 語法格式 : Rx, LSL#2;

-- 語法解析 : 將 Rx 寄存器中的值, 左移2 位;


代碼示例 :


.text
.global _start
_start:

@lsl 左移指令范例
mov r1, #0b1
@將 r1 中的值, 左移 2 位, 放入 r1 寄存器中
mov r1, r1, lsl#2

(2) ROR 指令

ROR 指令簡介 : 循環右移指令;

-- 語法格式 : Rx, ROR#2;

-- 語法解析 : 將 Rx 寄存器中的值 循環右移 2 位;


代碼示例 : 


.text
.global _start
_start:

@ror 循環右移指令范例
mov r1, #0b11
@結果是 ob1000...0001
mov r1, r1, ror#1


5. 程序狀態字訪問指令


程序狀態字 : CPSR 和 SPSR;

-- 注意 : 程序狀態字 不能使用 通用寄存器的語句 如 MOV 等訪問, 必須使用 程序狀態寄存器的 專用指令 讀寫;


代碼示例 : 


.text
.global _start
_start:

@mrs 指令范例
@rs 是 將 s -> r, sr 是 r -> s
mrs r0, cpsr	@將 cpsr 中的數據搬移到 r0 中
orr r0, #0b100	@將 cpsr 中的第三位置為1
msr cprs, r0

6. 存儲器訪問指令

(1) STR 指令


STR 指令簡介 : 將 寄存器中的值 保存到 內存中;

-- 語法格式 : str r0, 地址;

-- 語法解析 : 將 R0 寄存器中的值 保存到 內存地址中;;


代碼示例 : 


.text
.global _start
_start:

@str 指令范例
mov r0, #0xff
@將 r1 值改為 50000000 (OK-6410)
str r0, [r1]


-- 調試 : 添加地址監控, 在 Memory 視圖中進行監控;

(2) LDR 指令



LDR 指令簡介 : 將 寄存器中的值 保存到 內存中;

-- 語法格式 : ldr r0, 地址;

-- 語法解析 : 將 內存地址中 存放的值 加載入 r0 中;


代碼示例 : 


@ldr 指令范例
mov r0, #0xff
@將 r1 值改為 50000000 (OK-6410)
str r0, [r1]
ldr r0, [r1]

7. 以上所有代碼示例


以上所有代碼示例 : 便于調試學習;


.text

.global _start

_start:


@ldr 指令范例

mov r0, #0xff

@將 r1 值改為 50000000 (OK-6410)

str r0, [r1]

ldr r0, [r1]


@str 指令范例

mov r0, #0xff

@將 r1 值改為 50000000 (OK-6410)

str r0, [r1]


@mrs msr 指令范例

@rs 是 將 s -> r, sr 是 r -> s

mrs r0, cpsr @將 cpsr 中的數據搬移到 r0 中

orr r0, #0b100 程序入口, 用法 '.globol _start', 注意前面加上點;@將 cpsr 中的第三位置為1

msr cprs, r0


@ror 循環右移指令范例

mov r1, #0b11

@結果是 ob1000...0001

mov r1, r1, ror#1


@lsl 左移指令范例

mov r1, #0b1

@將 r1 中的值, 左移 2 位, 放入 r1 寄存器中

mov r1, r1, lsl#2


@bl 帶連接的分支指令范例

mov r1, #2

cmp r1, #1

@此時跳轉到 func1, func1 執行完程序無法返回, 如果 使用 bl 跳轉, 程序會返回

@b func1

@此時使用 bl 跳轉到 func1 執行, func1 執行完畢后會返回執行下面的語句

bl func1


mov r1, #2

cmp r1, #3


func1:

mov r1, #2

cmp r1, #2


mov r1, #4

cmp r1, #6


@b 分支指令范例

mov r1, #6

mov r2, #5

cmp r1, r2 @比較 r1 和 r2 中的值

@b 后可以跟一個條件, {條件} 在 {} 中就是可加可不加, 如果沒有條件就是無條件100%執行

@gt 是大于條件指令, 如果條件滿足會跳轉到 branch1, 如果不滿足就執行下面的指令

bgt branch1

add r3, r1, r2

b end @這里為了不執行 branch1 操作, 直接跳轉到 end 執行


branch1:

sub r3, r1, r2


end:

nop


@cmp 指令范例

[1] [2] [3]
關鍵字:ARM  匯編  偽指令  協處理器  訪問指令 引用地址:【嵌入式開發】 ARM 匯編 (指令分類 | 偽指令 | 協處理器訪問指令)

上一篇:基于WINCE6.0+S3C2443的camera驅動
下一篇:【嵌入式開發】ARM 芯片簡介 (ARM芯片類型 | ARM處理器工作模式 | ARM 寄存器 | ARM 尋址)

推薦閱讀最新更新時間:2025-05-22 17:59

ARM GCC 內嵌匯編手冊
關于這篇文檔 對于基于ARM的RISC處理器,GNU C編譯器提供了在C代碼中內嵌匯編的功能。這種非常酷的特性提供了C代碼沒有的功能,比如手動優化軟件關鍵部分的代碼、使用相關的處理器指令。 這里設想了讀者是熟練編寫ARM匯編程序讀者,因為該片文檔不是ARM匯編手冊。同樣也不是C語言手冊。 這篇文檔假設使用的是GCC 4 的版本,但是對于早期的版本也有效。 GCC asm 聲明 讓我們以一個簡單的例子開始。就像C中的聲明一樣,下面的聲明代碼可能出現在你的代碼中。 /* NOP 例子 */ asm( mov r0,r0 ); 該語句的作用是將r0移動到r0中。換句話講他并不干任何事。典型的就是NOP指令,作用就是短時的延時。 請接著閱
[單片機]
<font color='red'>ARM</font> GCC 內嵌<font color='red'>匯編</font>手冊
ARM匯編匯編中proc、endp、ret、near、far指令用法
子程序名 PROC NEAR ( 或 FAR ) …… ret 子程序名 ENDP (1)NEAR屬性(段內近調用): 調用程序和子程序在同一代碼段中,只能被相同代碼段的其他程序調用; FAR屬性(段間遠調用): 調用程序和子程序不在同一代碼段中,可以被相同或不同代碼段的程序調用. (2)proc是定義子程序的偽指令,位置在子程序的開始處,它和endp分別表示子程序定義的開始和結束兩者必須成對出現。 (3)ret指令的內部操作是:棧頂字單元出棧,其值賦給IP寄存器。即實現了一個程序的轉移,將棧頂字單元保存的偏移地址作為下一條指令的偏移地址。
[單片機]
ARM的BIN文件反匯編方法
最近在調試uboot的代碼時,用的新版本的uboot,lowlevel_init函數里是空的,而且在鏈接文件中也沒有發現對lowlevel_init.o的鏈接。在bl lowlevel_init 之前和之中加了兩個電燈,發現在bl之后的部分并沒有被執行,所以想看看具體程序有沒有運行這個函數。在網上找反匯編bin文件的時候發現有朋友提供的方法,很好用。 使用arm-linux 工具鏈里面的arm-linux-objdump 就能反匯編 cd到bin文件所在的目錄, 在命令行下輸入: arm-linux-objdump -D -b binary -m arm xxx.bin xxx.asm 參數: -D 反編譯所有代碼 -m 主機類
[單片機]
基于Android的ARM匯編語言系列之六:NEON指令集與VFP指令
章節列表 之一:ARM匯編語言開篇 之二:C/C++程序生成ARM匯編程序的過程分析 之三:ARM匯編語言程序結構 之四:ARM處理器的尋址方式 之五:ARM指令集與Thumb指令集 之六:NEON指令集與VFP指令集 NEON指令集與VFP指令集是ARM指令集的擴展,多用于多媒體編程和浮點運算。 一 Android平臺使用NEON指令集與VFP指令集 Android NDK從r3版本開始也添加了對NEON指令集與VFP指令集的支持。使用方法如下所示: 1 運行時檢測處理器是否支持NEON指令集與VFP指令集 Android NDK提供了一個cpufeatures的庫來讓開發者在運行時檢測處理器是否支持NE
[單片機]
第1天-ARM匯編指令LDR/STR
寄存器裝載和存儲 LDM LDR STM STR SWP 它們可能是能獲得的最有用的指令。其他指令都操縱寄存器,所以必須把數據從內存裝載寄存器并把寄存器中的數據存儲到內存中。 傳送單一數據 使用單一數據傳送指令(STR 和 LDR)來裝載和存儲單一字節或字的數據從/到內存。尋址是非常靈活的。 首先讓我們查看指令格式: LDR{條件} Rd, 地址 將內存地址中的值讀出來放到寄存器Rd中 STR{條件} Rd, 地址 將寄存器Rd中的值讀出來放到內存地址中 LDR{條件}B Rd, 地址 STR{條件}B Rd, 地址 指令格式 這些指令裝載和存儲 Rd 的值從/到指定的地址。如果象后面兩個指令那樣還指定了 B
[單片機]
曝:蘋果啟用全新R1協處理器
既然新一代iPhone在創新上沒有太多的看點,那么A13處理器會不會給我們帶來一些驚喜呢?   據外媒最新報道稱,蘋果將為2019款iPhone增加全新協處理器,代號為Rose(玫瑰)或R1。還不清楚蘋果是否會使用“玫瑰”或R1進行宣傳,或者根據A13的命名方式,直接使用R13這個名字。   從曝光的資料看,R1將比運動協處理器集成的傳感器更多,所以其會取代M系列的地位,同時還支持IMU、藍牙5.1、超寬帶(UWB)和相機(包括運動捕捉和光學追蹤)傳感器數據。   這也意味著,R1協處理器加入后,蘋果預計會為iPhone推出防丟貼類產品。從之前曝光的細節看,A13處理器可能還是六核設計,單核提升相比A12提升幅度大,而多核提
[手機便攜]
STM32新建匯編工程
學習stm32過程中,發現網上絕大部分的教程都是C語言的教程,當然在所有公司的嵌入式開發過程中也是絕大部分使用的都是C語言,但是也會有一部分需要直接操作內核寄存器的需求,例如RTOS中切換任務的時候,也確實沒有找到有人專門用匯編語言做項目,故而專門用匯編語言實現一些外設的操作,以此來熟練掌握匯編語言,方便后續繼續學習rtos或者深入單片機的內核做一些研究,文章會記錄開發的流程和實現的代碼,有任何問題也請指出,方便一起學習,共同進步 新建匯編工程 第一步點擊工程,新建,由于我的開發板是如下的型號,所以選擇對應的芯片 新建工程 第二步選擇啟動文件,keil官方給芯片提供了啟動文件,按照如下選擇,啟動文件是匯編語言實現的,主要的
[單片機]
單片機課程設計一匯編語言實現四位數計算器
匯編語言(英語:assembly language):是任何一種用于電子計算機、微處理器、微控制器,或其他可編程器件的低級語言。 在不同的設備中,匯編語言對應著不同的機器語言指令集。 一種匯編語言專用于某種計算機系統結構,而不像許多高級語言,可以在不同系統平臺之間移植。 Keil: 是美國Keil軟件公司出品的支持8051系列單片機架構的一款IDE(集成開發環境)。 AT89C51:是一種帶4K字節FLASH存儲器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低電壓、高性能CMOS 8位微處理器,俗稱單片機。 普中開發版原理圖: 題目:電子計算器 基
[單片機]
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 秦皇岛市| 昌江| 彭阳县| 襄樊市| 铜梁县| 中宁县| 凤山市| 张北县| 海阳市| 左贡县| 萨迦县| 元谋县| 寿宁县| 德格县| 淮南市| 栾川县| 静乐县| 双流县| 巢湖市| 长垣县| 上杭县| 台山市| 高雄县| 乐平市| 青铜峡市| 沁阳市| 上蔡县| 峨边| 永州市| 黄陵县| 忻城县| 金川县| 城步| 枣庄市| 巢湖市| 宜川县| 杭州市| 泌阳县| 青河县| 织金县| 密山市|