微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > arm汇编指令整理

arm汇编指令整理

时间:11-09 来源:互联网 点击:

器传输中,基地址可以在传输前或者传输后递增或者递减:STMIA r10,{r1,r3-r5,r8}

后缀IA还可以是IB,DA或者DB。这里I表示递增(increment),D表示递减(decrement),A表示后(after),B表示前(before)。

无论是哪种情况,编号最小的寄存器与最低存储器地址间进行传输,编号最大的寄存器与最高存储器地址间进行传输。寄存器出现在列表中的次序是无关紧要的。而且,ARM总是以递增存储器地址的方式进行顺序存储器访问。所以,递减传输实际上是先进行一个减操作,然后在数据传输中进行地址递增操作。

除非是特别指定,传输完成后基地址寄存器的值是不变的。如果要更新基地址寄存器,必须用!(感叹号)特别指明: LDMDB r11!,{r9,r4-r7},指令执行后r11=原来r11中的值-12。

http://blog.csdn.net/xiaomt_rush/article/details/6501711

12.ldrex

在 include/asm-arm/spinlock.h 下有這麼一段

#if __LINUX_ARM_ARCH__ <6
#errorSMP not supported on pre-ARMv6 CPUs
#endif

好啦,前提就是:只有ARM core版本>=6才可以繼續:

all spin lock primitives 到最後都是使用下面這個基本型:

static inline void__raw_spin_lock(raw_spinlock_t *lock)
{
unsigned longtmp;

1 __asm____volatile__(
2"1: ldrex %0, [%1]\n"
3" teq %0, #0\n"
4" strexeq %0, %2, [%1]\n"
5" teqeq %0, #0\n"
6" bne 1b"
7 : "=&r" (tmp)
8 : "r" (&lock->lock), "r" (1)
9: "cc");

smp_mb();
}

[指令重點]:

ldrex 指令是 core 6 以後才有的,跟 strex 配成一對指令,可以請 bus 監控從 ldrex 到 strex 之間有無其他的 CPU 或 DMA 來存取這個位址 ,若有的話,strex 會在第一個 register 裡設定值為 1(non-exclusive by this CPU) 並且令 store 動作失敗,若沒有,strex 會在第一個 register 裡設定值為 0(exclusive access by this CPU) 並且令 store 動作成功。

Code Trace Discussion:

Line 1: __volatile__ 告訴 compiler ,不要對這塊 assembly template 做最佳化動作,因為我們裡面有 loop 讀取 memory 動作,最佳化的結果可能導致 compiler 用一個 register 來 cache 它的值,不會老老實實的去讀 memory... ,這不是我們想要的動作喔!

Line 2: 把 lock 讀到 tmp,並請 bus monitor 這個 memory。

Line 3: 測試 lock 是否為 0,若非 0,表示 lock 已經被別人取得了,則 Line 4,5 都不做了,然後 Line 6 一定 branch,做 spin 的動作。若為 0,表示有機會取得 lock,繼續做 Line 4.5.。

Line 4:重點來了!,核對 bus monitor 的結果,若是exclusive access 則 tmp 設為 0 並且把 1 儲存到 lock,若是 non-exclusive access(有其他 CPU 來動過)則 tmp設為 1並且不做儲存 lock 的動作。

Line 5: 測試 tmp。

Line 6: 若 tmp 為 0 表示剛剛對 lock 動作是 exclusive,可以離開迴圈,若 tmp 為 1,則做 spin 動作。

Line 7: tmp 用 register 來操作,同時是 input 及 output 令它為 %0。

Line 8: &lock->lock 用 register 來操作 ,令它為 %1,值 1 用 register 來操作 ,令它為 %2。

Line 9: 此 template 會改到 condition code,加入 clobber list 以告訴 compiler 有這回事。

好了,終於看完了,真的很佩服那些 coding 的 kernel hackers ....

思考問題: ARM v6 以前有個 SWP 指令可以 lock bus and swap memory ,一樣可以用來完成 exclusive access ,但是比起 ldrex,strex 這對指令有什麼缺點呢?

SWP lock bus,其他 CPU 所有動作都不能做,但是 ldrex,strex就不會有這種現象,使用 ldrex,strex 時若其他 CPU不來 access 這個特定的 memory 就可以平行的做動作,增加平行執行的 performance。

13.swi

SWI,即software interrupt软件中断。该指令产生一个SWI异常。意思就是处理器模式改变为超级用户模式,CPSR寄存器保存到超级用户模式下的SPSR寄存器,并且跳转到SWI向量。其ARM指令格式如下:

SWI{cond} immed_24

Cond域:是可选的条件码 (参见 ARM汇编指令条件执行详解).

immed_24域:范围从 0 到 224-1 的表达式, (即0-16777215)。用户程序可以使用该常数来进入不同的处理流程。

一、方法1:获取immed_24操作数。

为了能实现根据指令中immed_24操作数的不同,跳转到不同的处理程序,所以我们往往需要在SWI异常处理子程序中去获得immed_24操作数的实际内容。获得该操作数内容的方法是在异常处理函数中使用下面指令:

LDR R0,[LR,#-4]

该指令将链接寄存器LR的内容减去4后所获得的值作为一个地址,然后把该地址的内容装载进R0。此时再使用下面指令,imm

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top