EDA365电子论坛网

标题: 使用ARM汇编伪指令编程:分别将两个无符号数放在寄存器R0和R1中,求其中较大的那个数... [打印本页]

作者: twel2e    时间: 2022-3-29 14:17
标题: 使用ARM汇编伪指令编程:分别将两个无符号数放在寄存器R0和R1中,求其中较大的那个数...
使用ARM汇编伪指令编程:分别将两个无符号数放在寄存器R0和R1中,求其中较大的那个数的阶乘
7 B; X  `3 A  v" ]4 Y1 S
作者: rergr    时间: 2022-3-29 15:29
本帖最后由 rergr 于 2022-3-29 15:36 编辑 8 k2 O2 Y0 e; w

+ V' j( D  q+ T  w5 u5 Y1、ADR(小范围的地址读取伪指令)* R4 q' R/ w! ~% x$ h
该指令将基于PC的地址值或基于寄存器的地址值读取到寄存器中。, }6 I4 ~. L6 c& K7 X8 z
语法格式8 C  J& k% a% o. u7 _/ j( t3 w
ADR{cond} register, expr
$ o% q) X) P+ S8 K" g+ I  i$ ~其中,cond为可选的指令执行的条件
& f! B  T* ^+ J7 h% Bregister为目标寄存器
* w2 i7 z$ O$ }) V0 Pexpr为基于PC或者基于寄存器的地址表达式,其取值范围如下:
' ?. \7 k- w3 N6 L当地址值不是字对齐时,其取值范围为-255~255.
( v( z) F6 s6 D当地址值是字对齐时,其取值范围为-1020~1020
1 t8 g, p( u* X- L) c3 d当地址值是16字节对齐时,其取值范围将更大
3 ]9 ]2 D  V! l在汇编编译器处理源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能。. A6 X! d3 m# h  M2 W( h9 \- W
因为ADR伪指令中的地址是基于PC或者基于寄存器的,所以ADR读取到的地址为位置无关的地址。当ADR伪指令中的地址是基于PC时,该地址与ADR伪指令必须在同一个代码段中。6 D( b- m/ ?0 C$ n$ e9 s" Z
示例, v/ S, c2 i; C8 O6 o& [
start MOV r0,#10 ;因为PC值为当前指令地址值加8字节
' c0 a* ]8 Q7 f/ S: r! rADR r4, start ;本ADR伪指令将被编译器替换成SUB r4,pc,#0xc
7 q6 b4 U0 M. K! v9 Z/ O/ q. B* P2、 ADRL(中等范围的地址读取伪指令)& C9 J, |+ z' e' [9 I* s0 y  \
该指令将基于PC或基于寄存器的地址值读取到寄存器中。ADRL伪指令比ADR伪指令可以读取更大范围的地址。ADRL伪指令在汇编时被编译器替换成两条指令,即使一条指令可以完成该伪指令的功能。
- ]. R- E9 w4 s% Y( J, M语法格式3 A3 ]' U+ H8 Y% j3 M, q2 J1 A
ADRL{cond} register,expr
3 x& v  o8 H; }- b( q2 {8 n示例1 W+ v$ X! C! {& n" D1 d
start MOV r0,#10 ;因为PC值为当前指令地址值加8字节5 o. @5 o' u# q5 A5 p
ADRL r4,start+60000 ;本ADRL伪指令将被编译器替换成下面两条指令" P4 M& A* l3 O2 ?* T2 b
ADD r4,pc,#0xe800' c# ^$ R0 l, w* [& i
ADD r4,r4,#0x254+ ?) k/ |9 d! F& X# G6 y7 O5 m$ Y
3、LDR(大范围的地址读取伪指令)
) k3 h- W8 s! E* C, FLDR伪指令将一个32位的常数或者一个地址值读取到寄存器中7 j6 t( B3 o' v0 p$ U
语法格式& ~$ O4 t5 u3 `: m- D  D
LDR{cond} register, =[expr|label-expr]* q' Z) F7 D( l% Y
其中,expr为32位的常量。编译器将根据expr的取值情况,如下处理LDR伪指令:' _& x" J% g$ f) y2 V+ d3 z
当expr表示的地址值没有超过MOV或MVN指令中地址的取值范围时,编译器用合适的MOV或MVN指令代替该LDR伪指令
/ x; M2 v: j/ H0 P5 M/ W* m% i' e当expr表示的地址值超过了MOV或者MVN指令中地址的取值范围时,编译器将该常数放在数据缓冲区中,同时用一条基于PC的LDR指令读取该常数。
3 ?; E3 D+ |) B/ Ilabel-expr为基于PC的地址表达式或者是外部表达式。当label-expr为基于PC的地址表达式时,编译器将label-expr表示的数值放在数据缓冲区(literal pool)中,然后将该LDR伪指令处理成一条基于PC到该数据缓冲区单元的LDR指令,从而将该地址值读取到寄存器中。这时,要求该数据缓冲区单元到PC的距离小于4KB。当label-expr为外部表达式,或者非当前段的表达式时,汇编编译器将在目标文件中插入一个地址重定位伪操作,这样连接器将在连接时生成该地址。9 [9 A0 \3 J& E: G& O- a* w  n/ H
LDR伪指令主要有以下两种用途:& [5 g, K+ ]' f- H9 A) w- N
当需要读取到寄存器中的数据超过了MOV及MVN指令可以操作的范围时,可以使用LDR伪指令将该数据读取到寄存器中。3 A) M( i, }0 s! f. m: r( y* h
将一个基于PC的地址值或者外部的地址值读取到寄存器中。由于这种地址值是在连接时确定的,所以这种代码不是位置无关的。同时LDR伪指令的PC值到数据缓冲区中的目标数据所在的地址的偏移量要小于4KB。1 R1 S8 r* s; G+ F( u" T
示例. r+ ]: _) y1 H
将0xff0读取到R1中/ T# x; Z* `8 H
LDR R1,=0xFF0& L8 @1 u- B- e, ]& o( v
汇编后将得到:. y( _6 l% y; z& \0 W( ?
MOV R1,0xFF0, ?" F, ]3 s" X
将0xfff读取到R1中, |  W$ l% @1 `/ p* B0 H) P9 ]( g% h
LDR R1,=0xFFF
4 u: w/ L, @% j7 ]+ i汇编后将得到:" l. j+ F. U8 g' s0 l1 o
LDR R1,[PC,OFFSET_TO_LPOOL]
% A7 g! J9 j+ G: Q, t) L( ~: y) C
/ }7 n, b( s& ]1 M5 d8 A6 O. r! hLPOOL DCD 0xFFF
* u/ f& g6 K, @将外部地址ADDR1读取到R1中, ?. k; R, I' N( Z
LDR R1,=ADDR1
7 o6 V3 `- i$ z7 i汇编后将得到:
( I( e/ G5 }# OLDR R1,[PC,OFFSET_TO_LPOOL]4 w& Y. z9 w+ D! {' |: r+ {4 S. O

6 E2 {* \$ V1 z* u5 ]LPOOL DCD ADDR1
8 q+ ?/ F: _9 D4、NOP空操作伪指令' ], Z5 |2 U6 |6 l$ h
在汇编时将被替换成ARM中的空操作,如MOV R0,R0  L8 {+ C# ?( M' a6 f
NOP伪指令不影响CPSR中的条件标志位
作者: opipo    时间: 2022-3-29 15:44
ARM中伪指令不是真正的ARM指令或者Thumb指令,这些伪指令在汇编编译时对源程序进行汇编处理时被替换成对应的ARM或Thumb指令(序列)。ARM伪指令包括ADR、ADRL、LDR和NOP等。! C4 y, }) d6 b

作者: land    时间: 2022-3-29 15:51
看一下大佬是怎么说的
) f0 V7 l- C9 n1 Q




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2