【arm】——ARM GCC Inline Assembler Cookbook

arm, assembly

https://www.ic.unicamp.br/~celio/mc404-s2-2015/docs/ARM-GCC-Inline-Assembler-Cookbook.pdf

GCC 的 inline assembly 基本格式是:

asm(code : output operand list : input operand list : clobber list);

也就是一堆用 ':'分開的字串。
其中 ‘code’ 的部份要存取 output operand list , input operand 的內容,是用 % 符號:

%0 代表存取 output operand
%1 代表存去 input operand
最後的’clobber’ 是要告訴 compiler 有哪些 register 被這段 assembly code 修改了。

為了防止 compiler 把這一段 inline assembly code optimize 掉,通常都會加上 volatilr:

asm voltaile(“mov %0, ror #01” : “-r” (result) : “r” (value));

這段 inline assembly,如果之後的部份都沒有資料,就可以不寫,舉例來說:

asm volatile(“mov r0, r0”);

這只是用來delay的code,沒有input, output,也沒有 register 會被修改,所以後面的 部份都不用寫。

但是如果有資料一定要寫,他的前面部份就不可以省略,舉例來說:

asm volatile("" : : : “memory”);

這段inline assembly 不包含任何 code,只是告訴 compiler memory 有可能會被修改。

一般為了好看,建議將一堆 assembly 寫成這樣:

asm volatile(
“mov r0,r0\n\t”
“mov r0,r0\n\t”
“mov r0,r0\n\t”
);

也就是說,分行寫,但是要記得加上 “\n\t” - 這是要讓 compiler listing 時,比較好看。

Input Output Operand

這兩個區域是要告訴 compiler operand 的資料,利用以下 “Constraint” 來通知:
Operand Register 的類型:

f : 是floating point register (有些 cpu 有專屬的 floating point register)
I : 立即定址 immediate operands

J : Indexing constants
K : negative value in rhs
L: negative value in rhs
M : for shift
r : General registers – ARM 一般用這個

Operand Register 的 in/out:

= : Write-only (通常所有的 output operand 都會加這個符號)

  • : Read-Write (inline assemnly 不支援這個符號)

& : Output only - 這個register 只做 output 使用

Output Operand 一定要是 Write-Only。
Input Operand 一定要是 Read-Only。

但是如果要把 input operand 修改後,作為 output operand 的話,要怎麼辦呢?
inline assembly 又不支援 ‘+’ 符號…

用"數字" 來告訴 complier 這一個 operand 共用哪一個 operand,例如:

asm volatile(“mov %0, %0, ror #1” : “=r” (value) : “0” (value));

這個 code 是將’value" right shit 1 bit。
但是用同一個 register 來作就可以。
input operand 用 “0” 告訴 compiler ,使用 第0個operand (就是 output operand)。
所以 input, output 都會用同一個 register (mov %0, %0…)。

Clobbers

把被修改的部份寫在這

asm volatile(
“amsd r3, %1, #3 \n\t”
“eor %0, %0, r3 \n\t”
“addne %0, #4”
: “=r” (len)
: “0” (len)
: “cc”,“r3”
);

例子使用了 r3 作scratch register,所以做完這段 code 後,r3的值會被修改,以在clobber的區域要列出 “r3”。
另外,作邏輯運算後,status 區域也會修改,所以要把"cc"也列上。

還有另一個例子:

asm volatile(
“ldr %0, [%1] \n\t”
“str %2, [%1, #4] \n\t”
: “=&r” (rdv)
: “r” (&table), “r” (wdv)
: “memory”
);

這一段code會update table 的內容,所以要在…

有一點沒寫到,就是 c variable name 都寫在 operand 後面,用括號( )括起來…

在 “Assembler Instruction with C expression operand” ,範例:
asm (“fsinx %[angle],%[output]”
: [output] “=f” (result)
: [angle] “f” (angle));
在operand 前可以用 [name] 寫出’‘將會用這’name’名字稱呼’’。
然後在 code 區域就可以直接用 %[name] 來引用

大概可以這樣說:

assembly code 中,要引用 C 宣告的部份,就要寫在 operand (in/out) 欄位,並且寫號 constrain.
然後用 %0, %1…來使用。
如果是直接存取 register,就直接用 r1, r2, r3… 但是要記得寫在 clobber 欄位。

http://r40eubuntu.blogspot.com/2009/02/arm-gcc-inline-assembler.html

ARM GCC Inline Assembler Cookbook

http://www.ethernut.de/en/documents/arm-inline-asm.html

http://blog.yam.com/registry/article/16464253

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值