|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
9 a: v$ o8 ?5 l% |第六章 ATPCS介绍
6 r+ G# P k% ~6 x
1 ?( q6 L6 U W8 y: ?在汇编编译器中使用-apcs选项。
8 u, d4 C8 g2 j+ G) G' c" X+ C& m" T
7 _8 R8 q( Q+ H6.1.2寄存器使用规则
4 q& g3 g( r0 c( j$ V$ n7 O& k6 G1 r. `9 F7 Q
子程序使用R0~R3来传递参数。用R4~R11来保存局部变量,thumb使用R4~R7。R12记作IP,调用scratch寄存器。R13记作SP,用作数据堆栈指针。R14记作LR,用作保存子程序的返回地址。R15记作PC,是程序计数器。
( u# ~: Z$ t- s- I! M/ B2 G' q! i K% z" d5 H3 q7 M
6.1.3数据栈使用规则
, q7 n; }0 f) ]( \; P7 L$ A8 R- h1 B% c& }* q
有四种堆栈方向:4 G7 v1 I* u) U) {' b& V% m
( M# g; V! N" y( ]4 B
FD、FA、ED、EA
6 u H* n E5 L9 h2 ^! I+ ^" T- d7 T* E; }6 O
ATPCS规定使用FD$ e- N" k7 w/ q% c: [) T1 D; t% N
7 m% M2 f9 O6 w0 K4 T- t2 |, z3 h
6.1.4参数传递规则
/ @$ z0 N& \9 }' T5 n. |& R7 F8 I
1、参数可变:参数不超过4,使用R0~R3,超过则将多的参数送到数据栈中保存
9 W- i- Q+ |: F3 M2 P6 B' v; A1 J; W# j2 N9 n- `$ n
2、参数固定:第一个参数,通过R0~R3,其他参数使用数据栈。; L6 f g# i: [$ g* l) F3 {
& @+ m; @; y D4 |+ \0 q
3、结果返回:结果为32位整数,使用R0;结果为64位,使用R0和R1;结果为浮点,使用f0、d0或者s0;
0 w6 W. U. S. t5 e8 |+ O& d9 ?- `4 ?/ d8 O6 v8 L
第七章 ARM和Thumb混合编程
- V9 b" y& V! f7 s# A7 A
' j& a& R& z) e状态切换指令:
/ j o. g' Q: r/ A1 b y5 Y9 g! N) k: m4 D
BLX 、BX 目标地址' |' x/ J. K, R1 }
0 X* {* D F6 b: t( jLDR、LDM及POP 向PC寄存器赋值% W' C R% V+ \( I- F+ }
1 U" Z) @" D2 }/ [ AREA AddReg ,CODE ,READONLY
, ?1 s- I5 e; x4 T) H1 j
! [# |! G# T- e, ?7 J ENTRY; c5 j$ d8 l; F: v% U* L1 L/ R
- q3 o P! a0 `! e/ `- z+ e) \
main
E" N! g0 D! P
& k3 t8 d3 Z2 t( Y1 A ADR R0,ThumbProg+1 ;存储单元的地址肯定是偶数,也就是最低位肯定是0,但ARM与thumb之间的切换是
3 }, i( v D1 z. B1 ?! J8 n; A; u8 Q. S: @/ d5 e- z( J
;通过Rn的最低位来判断的,1为thumb,0为ARM
6 t: u. G* b0 E) @0 m' \4 F
1 ~% s) @: ~5 k0 _' M BX R0 ;跳转到ThumbPro,并且程序切换到Thumb状态/ k" _6 [ c. `( x: D
: x" k e) i+ t4 I0 P; ^% e
CODE16
, T u" ^6 p: w( V- k# D
& a E& E7 L$ cThumbProg3 m. K: j$ ~5 L8 w$ d/ L6 @- W
1 M3 ]4 j/ ^ J" T" l. f' s
MOV R2,#2
: X" Z# b0 g3 l
7 b- D' `7 K: s2 t: q w MOV R3,#3
! Z. p# o* X0 i+ S+ j' l. F. O( w: u6 m1 W0 x
ADD R2,R2,R3* W6 U$ w1 a y0 ]) k
; h% n/ _4 y0 n0 x0 R* \
ADR R0,ARMProg
- v1 b6 ]3 N" N- k& O+ e. H
5 m* K3 J$ I/ c9 p$ E3 G s+ @ BX R0 ;跳转到ARMProg,并且切换到ARM状态
! U7 o4 h* e# v; J! Y. a* v
: j3 j! m" d' } CODE32) u+ h; P' F+ V6 \
, x! y3 X( H0 X; R6 n* G; UARMProg
% t. L8 M( h; D7 x8 V5 @/ x! g2 ~& q- N
MOV R4,#4
" S1 M/ ^2 }, |% s5 i9 {, h P8 \0 o, ^
MOV R5,#5( y; q; u6 ?" S* S* _+ \0 n+ [
7 r; q) P/ @& u, q ADD R4,R4,R5
$ i8 }8 k. i4 \; l9 k2 I5 |: Y+ S! K8 P" ?
stop7 {& a% H3 u2 T1 `8 S# z
/ s2 ^6 t% Z b3 s% U MOV R0,#0X18, [7 d4 K, C# A/ s; O
+ e1 M$ a" J& ~' W# S! O3 s
LDR R1,=0X20026
1 o: c/ T+ `( Z4 J' Z3 X* |: [3 G) ^1 g
SWI 0X123456
: ^- @" i0 ?9 k5 ]# e' z) N% a3 {: Z
4 h" q. ^8 Z2 ?: W. W- g END
7 l3 J9 t% a9 G" E/ F# ~$ H4 B
$ C+ p/ f( ~+ b0 n0 b( U//C程序调用汇编程序+ |7 l5 x7 G" P& `5 ?; R
5 J+ c) X k) D- E#include <stdio.h>, G I; u* U" n1 C" z/ H, |# t
/ z+ X8 m* m4 g+ H1 n0 o. X% V
extern void strcopy(char *d,const char *s) ; //使用关键字extern声明外部函数,即调用的汇编程序
, `" V# s+ Y% H2 b7 B$ ^& |( v
6 ^) S* E* I( ^, fint main(void): f2 @- ~0 m; @, p* @
4 \7 {8 H$ A6 f# q3 Y, o5 u6 l
{, V+ {+ i( P2 n: Z$ [- E
const char *srcstr="Source string";, g0 u8 }( U h5 N
1 L2 m( b! _, I% C' ~8 w5 `: n& S- S; q char dststr[]="Destination string";! x* u+ A5 A; C* v7 R4 e
1 K8 q/ f* y: |; c8 s" R
printf("Before copying :/n");
' U8 v+ V' C/ H- @: B' @" a2 Y* r% U8 S0 y
printf("%s/n %s/n",srcstr,dststr);
' q- k0 m4 ]& Y: J5 u5 j0 _9 a/ k1 i% O
strcopy(dststr,srcstr); $ R+ P" G( X0 L! n9 X9 C. k
% _3 k" r% y8 a( M7 V
printf("After copying :/n"); F9 W v" p0 l9 y
2 F# g# w3 e/ ]
printf("%s/n %s/n",srcstr,dststr);
, s; w. v# f( ?3 E: S# y, F s* I( P4 P' e% t* b
return 0;
5 t+ a4 ?) m4 X& w8 h# m
( X5 V$ G+ y: T7 A( B9 G5 Z}# g2 U, f: A7 E0 Q3 s( V" R+ r
7 K9 F7 j% M& Q( ]. j: \- i
;汇编程序
' x1 g; t8 x! ? \
; A9 y3 d+ u t" m \: M* o AREA STRCOPY ,CODE,READONLY
) B, U' a5 i' Q6 ?1 `. i: X! E3 G" F# U3 D: J- b' l
EXPORT strcopy //使用EXPORT伪操作声明汇编程序. e$ ]/ ?4 d4 `/ \: R6 b% F
0 n, b" R+ _4 D4 T( p. O
strcopy* k' w; W9 q; b* n. D
8 J% y4 y. \ }0 R+ B- f4 \: w4 z) c LDRB R2,[R1],#1 //寄存器R1中存放第srcstr地址
& b7 U2 q+ ?6 _* o9 }) T3 q: o- {* W* d( `' `6 t! y c
STRB R2,[R0],#1- C z3 k( C! W) k( M0 Q- |3 G$ t" q
1 I& [8 y8 Z7 S+ ]0 M) H+ n
CMP R2,#0
_0 {& A8 b$ j. E8 _& o
# w" k* c# J2 y+ Q. [ BNE strcopy
- T; c5 I. Y6 x6 d2 u
% b: D+ h% X) D, z MOV PC,LR
7 w+ _* ?, y) ^% |, B% E4 \
6 H9 i) b! k; U- @2 Z" u0 x END
4 t# d0 A1 t3 B: g; Z7 u
; J. i" T2 A$ J# `9 G# O;汇编程序调用C程序5 E9 f/ m9 m5 }" ^/ B- T E" n
0 k( n6 ^6 |/ d9 I
int sum(int a,int b,int c,int d, int e)
5 ] O5 S0 [6 _* D0 K9 Y+ c/ f5 }' m5 ]% M. Q0 ]" f
{" M6 g8 v9 X# B: W. E: p) ~" P
return a+b+c+d+e;8 ^ v" ^* g7 d* B$ r% d
: c" Q Y; U S& N
}# [- {7 n6 A0 W6 [+ m
/ G% |% x; G# a) X
EXPORT CALLSUM
* \9 b* R7 a& e5 H7 o3 f X+ v* T. e8 _
6 M' W$ R% h* ]" [1 o; p AREA F ,CODE ,READONLY
! ]5 x3 e/ X& a- A( ~
# P: H. v' E( w2 T: d IMPORT sum ;使用IMPORT 声明C程序sum()
! q2 o3 i: I9 z7 K8 a! N8 c: r9 I* e( s) b9 V' y
CALLSUM. ?; v8 R# ~1 F
, b- h4 S% _% _
STR LR,SP! ;保存返回地址8 }+ r5 W1 x( a* O! g& M
% q+ d6 E& C7 g# Q% ?2 D
ADD R1, R0,R0 ;假设进入程序时R0=I,设R1=2I; V4 u# P& D$ V- a' E
4 s# r* D% y, |& n/ V! G: h
ADD R2,R1,R0. A+ o* H3 l) V1 i( j4 h8 j4 [: c
& F4 \# i5 l! a A: a* X+ A; [% A! s
ADD R3,R1,R2
$ i6 h2 C) y6 x" z7 I/ _5 t" C+ }% u: n; @/ y
STR R3,[SP,#-4] ! ;第五个参数通过数据栈传递
+ j, N9 Z6 ]( ? i4 C# f, l6 Q0 z9 ^: w5 I& y# D
ADD R3,R1,R11 b1 {7 X. G' Q+ b3 T
. ~3 q. e8 _0 K2 X
BL sum2 c' m2 w* K" N7 v2 V
0 R, C$ `2 [- _6 I, c9 E ADD SP,SP,#4 ;调整数据栈指针,准备返回
' ^. p' L* y: d0 S; \3 S( `# _7 M/ U$ V- }: C% ~0 M6 x$ N* y0 |
LDR PC,[SP],#4 ;返回
% T* ~+ j/ k" \9 D+ N( L7 R8 c' q' \- G5 L U+ x$ K, x2 k
END |
|