“ARM inline Assembler”的版本间的差异
来自个人维基
free6d1823(讨论 | 贡献) |
free6d1823(讨论 | 贡献) |
||
(未显示1个用户的4个中间版本) | |||
第14行: | 第14行: | ||
result = (value >> 1) | result = (value >> 1) | ||
+ | example: sets the current program status register of the ARM CPU. | ||
+ | <source lang="c"> | ||
+ | asm("msr cpsr,%[ps]" : : [ps]"r"(status)); | ||
+ | </source> | ||
+ | int status; | ||
+ | ps (r2) = status | ||
+ | cpsr = ps | ||
+ | For ARM processors, GCC 4 provides the following constraints. | ||
+ | {| class="wikitable" style="width:75%" | ||
+ | ! Constraint !! Usage in ARM state !! Usage in Thumb state | ||
+ | |- | ||
+ | || f || Floating point registers f0 .. f7 || Not available | ||
+ | |- | ||
+ | || h|| Not available|| Registers r8..r15 | ||
+ | |- | ||
+ | ||G ||Immediate floating point constant ||Not available | ||
+ | |- | ||
+ | ||H ||Same a G, but negated ||Not available | ||
+ | |- | ||
+ | ||I ||Immediate value in data processing instructions e.g. ORR R0, R0, #operand ||Constant in the range 0 .. 255 e.g. SWI operand | ||
+ | |- | ||
+ | ||J ||Indexing constants -4095 .. 4095 e.g. LDR R1, [PC, #operand] ||Constant in the range -255 .. -1 e.g. SUB R0, R0, #operand | ||
+ | |- | ||
+ | ||K ||Same as I, but inverted ||Same as I, but shifted | ||
+ | |- | ||
+ | ||L ||Same as I, but negated ||Constant in the range -7 .. 7 e.g. SUB R0, R1, #operand | ||
+ | |- | ||
+ | ||l ||Same as r ||Registers r0..r7 e.g. PUSH operand | ||
+ | |- | ||
+ | ||M ||Constant in the range of 0 .. 32 or a power of 2 e.g. MOV R2, R1, ROR #operand ||Constant that is a multiple of 4 in the range of 0 .. 1020 e.g. ADD R0, SP, #operand | ||
+ | |- | ||
+ | ||m ||Any valid memory address | ||
+ | |- | ||
+ | ||N ||Not available ||Constant in the range of 0 .. 31 e.g. LSL R0, R1, #operand | ||
+ | |- | ||
+ | ||O ||Not available ||Constant that is a multiple of 4 in the range of -508 .. 508 e.g. ADD SP, #operand | ||
+ | |- | ||
+ | ||r ||General register r0 .. r15 e.g. SUB operand1, operand2, operand3 ||Not available | ||
+ | |- | ||
+ | ||w ||Vector floating point registers s0 .. s31 ||Not available | ||
+ | |- | ||
+ | ||X ||Any operand || | ||
+ | |} | ||
+ | |||
+ | |||
+ | Constraint characters may be prepended by a single constraint modifier. Constraints without a modifier specify read-only operands. Modifiers are: | ||
+ | {| class="wikitable" style="width:75%" | ||
+ | ! Modifier !! Specifies | ||
+ | |- | ||
+ | ||= ||Write-only operand, usually used for all output operands | ||
+ | |- | ||
+ | ||+ ||Read-write operand, must be listed as an output operand | ||
+ | |- | ||
+ | ||& ||A register that should be used for output only | ||
+ | |} | ||
+ | |||
+ | Examples: | ||
+ | * y=(y<<1); | ||
+ | <source lang="c"> | ||
+ | asm("mov %[value], %[value], ror #1" : [value] "+r" (y)); | ||
+ | </source> | ||
+ | use '+' for read-write able. Or, | ||
+ | <source lang="c"> | ||
+ | asm("mov %0, %0, ror #1" : "=r" (value) : "0" (value)); | ||
+ | </source> | ||
+ | Constraint "0" input reg = output reg | ||
+ | |||
+ | * rdv = table[0]; table[4]=wdr; | ||
+ | <source lang="c"> | ||
+ | asm volatile("ldr %0, [%1]" "\n\t" | ||
+ | "str %2, [%1, #4]" "\n\t" | ||
+ | : "=&r" (rdv) /* & rdv 只能写 不可共用 | ||
+ | : "r" (&table), "r" (wdv) | ||
+ | : "memory"); | ||
+ | </source> | ||
Referernce: http://www.ethernut.de/en/documents/arm-inline-asm.html | Referernce: http://www.ethernut.de/en/documents/arm-inline-asm.html |
2019年11月8日 (五) 14:03的最后版本
asm(code : output operand list : input operand list : clobber list);
example: Rotating bits example
int x;
int y;
y= (x>>1);
asm("mov %[result], %[value], ror #1" : [result] "=r" (y) : [value] "r" (x));
register value (r1) = x
register result (r2) = y
result = (value >> 1)
example: sets the current program status register of the ARM CPU.
asm("msr cpsr,%[ps]" : : [ps]"r"(status));
int status;
ps (r2) = status
cpsr = ps
For ARM processors, GCC 4 provides the following constraints.
Constraint | Usage in ARM state | Usage in Thumb state |
---|---|---|
f | Floating point registers f0 .. f7 | Not available |
h | Not available | Registers r8..r15 |
G | Immediate floating point constant | Not available |
H | Same a G, but negated | Not available |
I | Immediate value in data processing instructions e.g. ORR R0, R0, #operand | Constant in the range 0 .. 255 e.g. SWI operand |
J | Indexing constants -4095 .. 4095 e.g. LDR R1, [PC, #operand] | Constant in the range -255 .. -1 e.g. SUB R0, R0, #operand |
K | Same as I, but inverted | Same as I, but shifted |
L | Same as I, but negated | Constant in the range -7 .. 7 e.g. SUB R0, R1, #operand |
l | Same as r | Registers r0..r7 e.g. PUSH operand |
M | Constant in the range of 0 .. 32 or a power of 2 e.g. MOV R2, R1, ROR #operand | Constant that is a multiple of 4 in the range of 0 .. 1020 e.g. ADD R0, SP, #operand |
m | Any valid memory address | |
N | Not available | Constant in the range of 0 .. 31 e.g. LSL R0, R1, #operand |
O | Not available | Constant that is a multiple of 4 in the range of -508 .. 508 e.g. ADD SP, #operand |
r | General register r0 .. r15 e.g. SUB operand1, operand2, operand3 | Not available |
w | Vector floating point registers s0 .. s31 | Not available |
X | Any operand |
Constraint characters may be prepended by a single constraint modifier. Constraints without a modifier specify read-only operands. Modifiers are:
Modifier | Specifies |
---|---|
= | Write-only operand, usually used for all output operands |
+ | Read-write operand, must be listed as an output operand |
& | A register that should be used for output only |
Examples:
- y=(y<<1);
asm("mov %[value], %[value], ror #1" : [value] "+r" (y));
use '+' for read-write able. Or,
asm("mov %0, %0, ror #1" : "=r" (value) : "0" (value));
Constraint "0" input reg = output reg
- rdv = table[0]; table[4]=wdr;
asm volatile("ldr %0, [%1]" "\n\t" "str %2, [%1, #4]" "\n\t" : "=&r" (rdv) /* & rdv 只能写 不可共用 : "r" (&table), "r" (wdv) : "memory");
Referernce: http://www.ethernut.de/en/documents/arm-inline-asm.html