|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
5 z: P2 h9 s8 T, M- H第六章 ATPCS介绍* d- m1 L; |1 z/ h( r, P
, u: G" l& W, |# e4 a
在汇编编译器中使用-apcs选项。
/ ]$ c G7 b( A, L# W. a- n W1 L* S' k( |6 P9 `" D
6.1.2寄存器使用规则' D6 K5 }7 k! l
/ E$ j( v* z. {1 {. \& I子程序使用R0~R3来传递参数。用R4~R11来保存局部变量,thumb使用R4~R7。R12记作IP,调用scratch寄存器。R13记作SP,用作数据堆栈指针。R14记作LR,用作保存子程序的返回地址。R15记作PC,是程序计数器。3 _' Z, A0 q! K' W# V4 e6 b M2 C
6 J p, Z9 W P6 t6.1.3数据栈使用规则3 V% q/ \1 |& G1 Y3 _$ R( S
3 K' G5 ?5 ?* K有四种堆栈方向:
5 Z. @, @* l& {9 ~- q
/ R0 U Y9 h& X# I/ _- eFD、FA、ED、EA
( c9 y5 \8 J/ Z% i; `
: U* U" {8 f8 U% @( q# zATPCS规定使用FD
3 M" w2 n- G! r4 _" d' F& l1 \, r- o5 \- ^( l4 F9 T3 q. l+ E
6.1.4参数传递规则
G" o2 L' D$ V" j: K3 w9 t) _& M6 b' n& B* C$ ?( p# Y, S6 I
1、参数可变:参数不超过4,使用R0~R3,超过则将多的参数送到数据栈中保存
. O, C! E: ^/ n" o$ S- N
/ ?2 `7 }1 n7 K, v( X' X7 n/ l2、参数固定:第一个参数,通过R0~R3,其他参数使用数据栈。4 v" d; N7 E/ G |7 y
& z% n! F# @5 u3、结果返回:结果为32位整数,使用R0;结果为64位,使用R0和R1;结果为浮点,使用f0、d0或者s0;" q. P; w* U" T& f/ j7 ?
' U: X8 c, p. m9 i
第七章 ARM和Thumb混合编程9 S7 @# @" A" D& c4 H% {
% `- U- E/ u7 Q7 v0 F4 I6 A状态切换指令:
* t4 U% T- g; x" B! D. f2 ~) F3 P
& s5 v7 p1 ^4 [6 _- l. |BLX 、BX 目标地址1 K) |- v9 R8 }$ f& Q% Y+ b
! T% i' O; w0 {. F, [) }! P
LDR、LDM及POP 向PC寄存器赋值- S, T* z7 t- K d0 {
0 f3 [: }3 {9 U* f. T8 o AREA AddReg ,CODE ,READONLY
+ g) C7 B5 p F, p! r: D( N
+ n* Z2 U( s4 F" ^9 S! ~6 U/ J c9 A ENTRY4 l- f9 z. t. F4 I
1 E3 I, F8 ?6 f Xmain
: P# ~2 R% I7 h' I
- h1 t! J* l8 b; X4 `" b- E ADR R0,ThumbProg+1 ;存储单元的地址肯定是偶数,也就是最低位肯定是0,但ARM与thumb之间的切换是, l% Q8 K4 a/ [/ l( c( Z- i
% `; ^ `1 J% X1 x) _
;通过Rn的最低位来判断的,1为thumb,0为ARM
D- h& u8 r' N, X; J3 r
) w1 M5 t0 R' W! i1 U9 Y$ w+ h BX R0 ;跳转到ThumbPro,并且程序切换到Thumb状态7 _& B$ E4 q5 d" D% Z( S# B( d' `
8 y& a4 ?, E$ L. i6 \
CODE162 F; B1 u0 c: X% n& l
! N/ _# t! D% }4 vThumbProg, {8 z1 b) D" i& ~* g( ~/ }1 p
0 k) m1 v6 S3 ]% T( @
MOV R2,#2
+ @* Z3 J" H. s. n& {4 P2 T2 Y) V6 T% }! w$ A- f2 Q3 c
MOV R3,#3
3 I$ |3 s5 n: `, I' M$ J2 W K$ y' p2 H# [7 M5 V# ~
ADD R2,R2,R3
3 K+ S$ C8 C$ \2 L- u/ T \4 Y; X, Q, n h6 Q
ADR R0,ARMProg. X7 W2 J# y7 W1 H
& }# V6 U u7 u
BX R0 ;跳转到ARMProg,并且切换到ARM状态8 U5 @$ Z' v5 L7 l9 i" Y6 z4 r
) E y. s1 _2 e x7 G7 [ CODE32
* R t0 a$ _1 A e) A$ @' _; |0 Q
ARMProg, w( m2 \& z4 `
. {3 k8 ?- p- @: M% K+ k
MOV R4,#40 O5 c o2 e7 ]( n( T. ]( ^- P" H
2 z2 l8 \+ e* m! D: X* L( J MOV R5,#5
/ k! G( }( t1 C M+ H$ K; A
+ Y$ s0 c8 u7 H( b7 t, t ADD R4,R4,R56 n7 ]5 x- L; }+ t$ @% v
! P* R5 X/ I2 e4 Wstop
J! r4 w; j( }4 q% S/ e1 J% O
% c$ i. D' {6 v8 e+ P; L8 E MOV R0,#0X18
+ O9 g$ M! Z8 a: ~# }
& T. N! g1 L- w ~& q* V" y! c; A LDR R1,=0X20026
! m% W. w1 W j" S% A+ C! V8 Y
* g+ k: h* \8 _. w6 h( ?; _6 @ SWI 0X123456
: V+ E' [9 D! C* K
; C! F, l4 y2 ?) A( D) A END
. X- k# h$ `2 A/ w: S2 e% }# A4 j8 N( a3 K0 p. V4 R" |7 r$ e
//C程序调用汇编程序, A3 R- Y% Z# [& x* w _- L1 h
( P, `8 a {. I#include <stdio.h>
% L2 F8 s3 d/ H( J6 `0 }, ^2 u
) e( A( s# V* |8 @4 ]" Y( Uextern void strcopy(char *d,const char *s) ; //使用关键字extern声明外部函数,即调用的汇编程序
7 [# [5 C$ G3 ^: H
+ |' ?6 u( Z. `( }9 Uint main(void) @# ]' W: [' p9 M1 o' e
. O% X3 y8 ~9 `; d) k; X9 A& g4 _
{$ p, h7 t$ j$ f& F3 @) L6 q
const char *srcstr="Source string";* R1 L4 l: i0 w! k: B
$ i9 m, @6 R8 B% {! z O
char dststr[]="Destination string";9 n4 ?* V. E* o/ \3 j9 f
: `: ]+ P) j+ o- { printf("Before copying :/n");
; e( h2 c$ I+ A+ h/ w$ A0 a
; N/ B5 g: X4 A) K( Z7 v0 p* ] printf("%s/n %s/n",srcstr,dststr);
3 e5 W5 n& c' [% w0 x5 X& E- C" I c8 S6 t* k" s) k2 ~/ t
strcopy(dststr,srcstr);
+ O |# ~3 Y# v: c* X P% f k6 r3 S" `
printf("After copying :/n");" x0 w# a) E! K- i
! }) u" h$ `7 \- M
printf("%s/n %s/n",srcstr,dststr);
( D1 q9 T& J$ {- e0 |* c6 k# s9 t! u: T6 F l$ {
return 0;2 }' L3 i1 x* o* `
- L8 M3 |/ Y5 \. A9 G
}
! N/ {2 D% z3 w1 ~4 W0 z
2 ]$ ^7 ^6 N; V% X3 D- o! A;汇编程序
( \8 w- s1 ]1 H V3 I
0 A- G, k1 E/ _- _. t, ^7 ] AREA STRCOPY ,CODE,READONLY
2 V0 m# c9 m( e
0 A) b- f3 @4 W8 b( ?- T( z$ ^ EXPORT strcopy //使用EXPORT伪操作声明汇编程序! p# o5 P; N+ b6 y1 [* m) W+ p3 G
% n% y5 X0 d& \- U I0 ^4 k1 y
strcopy
* r0 T6 ^5 y+ y
: o, Q( _& Q( Z: R6 E4 R LDRB R2,[R1],#1 //寄存器R1中存放第srcstr地址8 ~" q1 ^ v, K& y
1 X- e* [+ x" U. @3 R7 p1 m STRB R2,[R0],#1' d3 u8 d3 I" F( x6 P$ g) `, P8 U+ h
1 P9 Y5 ]% F$ m$ C- B# l CMP R2,#0
9 C8 h6 B+ H* r9 p* @; L6 f. m
2 g8 W! F2 }& G4 I# _ BNE strcopy
3 H% v+ k, m O( Z" y! v! P/ G* a" }4 s% |+ e4 ^5 U/ q
MOV PC,LR: @% J3 V0 S; I. @7 [2 Y
: w9 q) \; I( Q6 x8 A END
4 g4 v# V: ?' ~ b: C
# q- [/ Z. C6 c7 H;汇编程序调用C程序* y; d+ c. I _8 j; f
+ c" D/ I) P( n0 Nint sum(int a,int b,int c,int d, int e)3 o5 I; j2 H( ]/ V% B/ l( X! k
' `/ x% b& S! y6 `9 e9 I{
' [3 F$ W0 Y- g7 i return a+b+c+d+e;
! x. F7 q# j# m9 U+ D" Q" E" I6 d9 e8 G5 d$ R! O. Y( R3 E* i2 K5 w
}0 g7 B8 A* h" | \! S$ f
" r0 `. L7 v- j EXPORT CALLSUM. C) U! j8 V3 i9 B! x x% T+ |
3 g) n. c; T9 R5 {% i8 }
AREA F ,CODE ,READONLY; ^1 f, M( \5 Z% z5 Z! O7 g- ~3 P1 v
2 a( h* c: E9 J; v IMPORT sum ;使用IMPORT 声明C程序sum()8 z2 Q& R7 ?+ ? p0 X7 D
% u) R+ @: M! R9 a( w' |( U
CALLSUM# N( z5 q% X% I
4 ~6 W! F/ P$ w" g: H" u2 h. N
STR LR,SP! ;保存返回地址
j$ o/ y( J3 n# }# I! G, Z6 _5 b5 j5 j/ F
ADD R1, R0,R0 ;假设进入程序时R0=I,设R1=2I h8 J3 }) s, O/ N
' P N9 w, g+ a3 n; ?; Y ADD R2,R1,R0
% T( ~4 L- Q* Z }& f/ K" P1 @* ]
: Z- b! M- e! J/ f9 R( j& M ADD R3,R1,R23 M) L9 s- P6 t; b
9 a3 @# b. Z, Q5 u' n STR R3,[SP,#-4] ! ;第五个参数通过数据栈传递7 Z& @) x% h" q9 O( p
' E4 |& I' ?/ u ADD R3,R1,R1
8 p6 u+ X, G; w/ U" B# P3 v5 d; i( n n/ Q: K: m
BL sum3 K1 J6 \' j% g( W& E5 A+ W
! g6 ^- B4 L/ i3 J8 ?
ADD SP,SP,#4 ;调整数据栈指针,准备返回
. \& r6 T& |4 N% q. y- l; _1 H- x) h$ M% u% X: G
LDR PC,[SP],#4 ;返回
+ Z: ]% l0 o7 r" U& [+ Y
0 w c- t* ?4 Z/ S8 g( h8 I$ m END |
|