第10部分 Linux ARM彙編 定址方式

2021-10-06 20:55:47 字數 4267 閱讀 4672

都遵循gas彙編器的語法。

mov ro, #1234

mov r0, r1

lsl:邏輯左移,移位後暫存器空出的低位補0。

lsr:邏輯右移,移位後暫存器空出的高位補0。

asr:算術右移,移位過程中,符號位保持不變,如果源運算元是正數,則空出的高位補0,否則補1.

ror:迴圈右移,移位後移除的低位填入空出的高位。

rrx:帶擴充套件的迴圈右移,運算元右移一位,移位空出的高位用c標誌的值填充。

mov r0, r1, lsl #2

r1暫存器左移兩位賦值給r0,指令執行後,r0=r1*4。

ldr r0, [r1]

將r1暫存器的數值作為位址,取出此位址中的值賦給r0暫存器。

ldr r0, [r1, #-4]

暫存器r1的陣列減去4作為位址,取出此位址中的值賦值給r0。

ldmia r0,

ldm是資料載入指令,指令的字尾ia表示每次執行完載入操作後r0暫存器的值自增1個字。指令執行後,r1=[r0],r2=[r0+#4],r3=[r0+#8],r4=[r0+#12]。

ldmfa/stmfa

ldmea/stmea

ldmfd/stmfd

ldmed/stmed

stmfd sp1,

將r1-r7,lr入棧,多用於儲存子程式現場。

ldmfd sp1,

將資料出棧,放入r0-r7,lr暫存器,多用於恢復程式現場。

ldmia/stmia

ldmda/s***a

ldmib/stmib

ldmdb/s***b

ldmia r0!,

從r0暫存器的儲存單元中讀取3個字到r1-r3暫存器中。

stmia r0!,

儲存在r1-r3暫存器的內容到r0指向ed儲存單元。

ldmia/ldmda中i表示increasing,d表示decreasing,a表示after,b表示before。

bl next

...next:

...bl next是跳到next標號處執行,這裡的bl就是採用相對定址,標號next是偏移量。

定義load.s檔案如下:

.data;//資料段

.balign 4 /* 四個位元組對齊 */

myvar1: /* 定義變數myvar1 */

.word 3 /* 值為'3' */

.balign 4 /* 四個位元組對齊 */

myvar2: /* 定義變數myvar2 */

.word 4 /* 值為'4' */

.text /* -- **段*/

.balign 4 /* 四個位元組對齊 */

.global main

main:

ldr r1, addr_of_myvar1 /* r1 ← &myvar1 */

ldr r1, [r1] /* r1 ← *r1 */

ldr r2, addr_of_myvar2 /* r2 ← &myvar2 */

ldr r2, [r2] /* r2 ← *r2 */

add r0, r1, r2 /* r0 ← r1 + r2 */

bx lr

/* 資料位址 */

編譯:

as -g -o load.o load.s

gcc -o load load.o

原始碼如下:

.data;//資料段

.balign 4 /* 四個位元組對齊 */

myvar1: /* 定義變數myvar1 */

.word 0 /* 值為'0' */

.balign 4 /* 四個位元組對齊 */

myvar2: /* 定義變數myvar2 */

.word 0 /* 值為'0' */

.text /* -- **段*/

.balign 4 /* 四個位元組對齊 */

.global main

main:

ldr r1, addr_of_myvar1 /* r1 ← &myvar1 */

mov r3,#3

str r3,[r1]//將r3中值保持到[r1],就是myvar1值=3

ldr r2, addr_of_myvar2 /* r2 ← &myvar2 */

mov r3,#4

ldr r3, [r2] /* r3 ← *r2 */

ldr r1, addr_of_myvar1 /* r1 ← &myvar1 */

ldr r1,[r1];// r1=myvar1值

ldr r2, addr_of_myvar2 /* r2 ← &myvar2 */

ldr r2, [r2] /* r2 ← *r2 ,就是r2=0*/

add r0, r1, r2 /* r0 ← r1 + r2 ,就是3+0=3*/

bx lr

/* 資料位址 */

as -g -o store.o store.s

gcc -o store store.o

實現了將,

執行驗證;

#./store

#echo $?

結果一致。

.arch armv8-a

.data;//資料段

.balign 4 /* 四個位元組對齊 */

myvar1: /* 定義變數myvar1 */

.word 3 /* 值為'3' */

.balign 4 /* 四個位元組對齊 */

myvar2: /* 定義變數myvar2 */

.word 4 /* 值為'4' */

.text /* -- **段*/

.balign 4 /* 四個位元組對齊 */

.global main

main:

ldr r1, addr_of_myvar1 /* r1 ← &myvar1 */

ldr r1, [r1] /* r1 ← *r1 */

ldr r2, addr_of_myvar2 /* r2 ← &myvar2 */

ldr r2, [r2] /* r2 ← *r2 */

add r0, r1, r2 /* r0 ← r1 + r2 */

mov x8, 93

svc 0

/* 資料位址 */

編譯:as -g -o load64.o load64.s

gcc -o load64 load64.o

.data;//資料段

.balign 4 /* 四個位元組對齊 */

myvar1: /* 定義變數myvar1 */

.word 0 /* 值為'0' */

.balign 4 /* 四個位元組對齊 */

myvar2: /* 定義變數myvar2 */

.word 0 /* 值為'0' */

.text /* -- **段*/

.balign 4 /* 四個位元組對齊 */

.global main

main:

ldr x1, addr_of_myvar1 /* r1 ← &myvar1 */

mov x3,#3

str x3,[x1]//將r3中值保持到[r1],就是myvar1值=3

ldr x2, addr_of_myvar2 /* r2 ← &myvar2 */

mov x3,#4

ldr x3, [x2] /* r3 ← *r2 */

ldr x1, addr_of_myvar1 /* r1 ← &myvar1 */

ldr x1,[x1];// r1=myvar1值

ldr x2, addr_of_myvar2 /* r2 ← &myvar2 */

ldr x2, [x2] /* r2 ← *r2 ,就是r2=0*/

add x0, x1, x2 /* r0 ← r1 + r2 ,就是3+0=3*/

mov x8, 93

svc 0

/* 資料位址 */

as -g -o store64.o store64.s

gcc -o store64 store64.o

第11部分 Linux ARM彙編 執行分支

在32位的arm架構系統中,通用暫存器中有乙個暫存器比較特殊,就是r15,它也是pc暫存器。pc是program counter。也叫做ip,instruction pointer。當arm處理器執行一條指令時,在其執行結束時可能會發生兩件事。如果指令沒有修改pc,則pc只會增加4,因為在32位ar...

windows10 部分教程

一 如何給電腦分割槽 若電腦為乙個c盤 桌面右鍵單擊此電腦 選擇管理 選擇磁碟管理 右鍵單擊c盤 選擇壓縮卷 輸入壓縮空間量 1gb 1024mb 選擇壓縮 出現未分配的磁碟 右鍵單擊未分配磁碟 選擇新建簡單卷 選擇下一步多次 更改卷標即為新磁碟名稱 二 如何自定義工作列 對工作列右鍵單擊即可設定 ...

Microformats教程 第3部分

本文首發於 http www.lunaticsun.com article microformats three 目前,這個系列已經有兩篇文章了,它們是 什麼是microformats microformats教程 第1部分 microformats教程 第2部分 在這一部分中,我們將討論一種全新的...