|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
9 n: z' M3 d% F& K* W
第六章 ATPCS介绍
) [; o- y* }' g
: e s: \2 w* Y在汇编编译器中使用-apcs选项。
2 |5 L* \: H8 z- ^" i, ]' B0 x8 K. O% m0 o4 _4 d
6.1.2寄存器使用规则' c Y' g' v( Z
- U1 E; R2 Y: ]
子程序使用R0~R3来传递参数。用R4~R11来保存局部变量,thumb使用R4~R7。R12记作IP,调用scratch寄存器。R13记作SP,用作数据堆栈指针。R14记作LR,用作保存子程序的返回地址。R15记作PC,是程序计数器。! p: f" y8 W b+ G8 r* _
& Q) K& X( b. w8 w( O( T/ v6.1.3数据栈使用规则( _5 g, A9 v$ X$ |8 ~
|" T8 B( ]$ p6 x有四种堆栈方向:/ H$ i. [- [) x
; C. L# ^# T: L7 ~7 BFD、FA、ED、EA
$ H @9 X/ w( J; K* Y0 P/ T) E5 n8 R3 g7 H% x
ATPCS规定使用FD2 h: O i2 A1 {6 _; A
( S( l7 g. u! F7 D6 v
6.1.4参数传递规则7 R6 t6 M+ v6 D: Q% Y! H# [ l4 g
# p! ~$ w! @. U% `3 L: R" C
1、参数可变:参数不超过4,使用R0~R3,超过则将多的参数送到数据栈中保存
( d! P7 R$ G9 r9 e$ @5 d# d0 E! H
# p" _7 Q1 o8 n g- a: D2、参数固定:第一个参数,通过R0~R3,其他参数使用数据栈。
" H7 T m: ^& b0 \' y
3 ^# k" @0 m8 g* R2 m) m" {( V1 a3、结果返回:结果为32位整数,使用R0;结果为64位,使用R0和R1;结果为浮点,使用f0、d0或者s0;
U6 X- a+ }7 w% W5 J& h* }" y7 s7 C% T4 ~* @! k# B, ?
第七章 ARM和Thumb混合编程
# x! K$ G, |& b7 d. q3 G5 b! L
9 I) @ U5 j- Z: H: w状态切换指令:* ?$ f1 A1 j5 s5 ~5 p& v; }. \/ n
5 V1 Y& S* ]! b. v: P
BLX 、BX 目标地址
) h* w+ x- S6 U# D1 L+ @3 }( M3 }$ c2 w, c# p2 [, L) {9 F4 j5 U
LDR、LDM及POP 向PC寄存器赋值
8 I: n3 `- H/ D ~1 \
$ |4 ]' K" s5 l4 H. q7 m AREA AddReg ,CODE ,READONLY
$ ~& R) o8 @2 Z, J: x+ }. m( o' t1 |3 d) O6 k6 }* i
ENTRY+ h' i8 p5 c8 ?' c
- [: t* R/ p" w% Q% [main
) s/ r& e/ z3 {% l# B: ?1 _' h/ L5 N8 r* D
ADR R0,ThumbProg+1 ;存储单元的地址肯定是偶数,也就是最低位肯定是0,但ARM与thumb之间的切换是
4 d6 K3 h y# `8 V
- d$ ?) L2 L. \1 e/ h ;通过Rn的最低位来判断的,1为thumb,0为ARM) e9 a# Q' @# d8 z
' }) D9 U5 s' G, h9 h# G
BX R0 ;跳转到ThumbPro,并且程序切换到Thumb状态3 x0 c* @4 w% [; }- Y
; }- T4 j7 d1 e- y/ G- K CODE163 c4 P, j. o& g/ k b1 \
. N& e5 C2 G( M# g2 ^: j+ f X1 E
ThumbProg
; s7 M" {2 n% t# y
" ?. e) u+ Z B8 S2 L! n) j MOV R2,#2) ^& O2 r, z0 c, ~
, t+ m% q5 X) c) {4 X' p MOV R3,#3
3 B2 y3 K7 A2 @" C8 k7 C# m7 u1 ~
3 `3 m5 | `2 o4 c7 f! G, C ADD R2,R2,R3
3 J9 m5 @0 k! d7 e
9 Q$ f( d5 _& m0 Y) C ADR R0,ARMProg
c2 d* W2 \1 V* ?* C6 I' C$ J1 ^. H* P3 j# o1 _' E
BX R0 ;跳转到ARMProg,并且切换到ARM状态* j. I4 v, p/ D0 `
0 k& w- t. I; \0 R: v; i
CODE32. Q! ^8 c N1 b! n2 _% E
( X: c# K! _- `ARMProg' {) }0 a8 s5 B/ | R6 Y7 ~- l
7 R& D3 Z1 w# Y7 { MOV R4,#4
! N% q- |! ~" ?2 O
8 Z9 a; Y. _5 N6 c MOV R5,#5
, V0 @7 \$ g# g4 ]* a: Z' {" m8 |! c& y( T# Y8 N# c
ADD R4,R4,R5; Z$ `/ X0 \ y! v" P7 Z
- w. n }& T$ f1 Y* y3 ~" a
stop0 v9 r% L$ ^; ? l3 |+ o
; F9 G" U( m Z8 `
MOV R0,#0X186 M$ M) P: N8 q3 @5 k7 D
5 Z. T# H, W$ L! k6 i# a
LDR R1,=0X20026
+ i- z: F( c# _" T/ X( H/ G O. k, M) |5 X. m# J# m5 ~* c
SWI 0X1234569 |: e* @+ F2 D- J' I5 B: Y9 _( `
6 B, c, ^8 u6 ~" ^6 p6 q9 s& ]0 i- |, g
END) A/ _* v$ i9 N
! v& [( F! v: I# u
//C程序调用汇编程序: {% P" y7 ^. V' c
( O) U/ F3 [, }: ^2 B
#include <stdio.h>
g, G2 O2 [8 Q5 v4 d
5 Z2 \, \5 b# t9 e; e: ?/ }extern void strcopy(char *d,const char *s) ; //使用关键字extern声明外部函数,即调用的汇编程序% R6 c/ e. `: Z+ t
$ V3 k1 s9 ~6 uint main(void)' t! Z& d1 d% O5 ?$ C" c0 |* n
! h: _' t2 p& J1 ]9 a{
* T, Y3 Z% f$ P r; g% [: @1 |' j const char *srcstr="Source string";
_# A. h4 I7 f+ U3 v j& A% K( |9 ^+ J
char dststr[]="Destination string";' y' {6 k' b7 Q. |
7 e) p5 ~; M0 Z. |8 P/ J4 x# ^
printf("Before copying :/n");* ]5 L8 s5 u& k$ ^$ l' K
2 n4 e0 ], h% l; h! e7 G4 w+ ~ printf("%s/n %s/n",srcstr,dststr);1 j8 f, n: P+ [( B0 D
* G: v1 T2 Z) x3 h, _
strcopy(dststr,srcstr);
k( Z! d% r: a+ X
# C" A. u1 u% ?# v, K( G6 e! _0 I0 ^8 M printf("After copying :/n");, k1 y0 \/ A s5 y
+ f% C V; F9 _7 S1 j( a printf("%s/n %s/n",srcstr,dststr);
2 g% H: a1 f/ D& ^# j# }" ]& v9 x C% b3 I. M- l9 }% v: j: }* R
return 0;$ u3 U: P# h a( D% C& o% B
]; D% i; D0 \9 ^" f3 ~* b}# ~/ f- U; L% Q7 M* D* Q( c
l+ q8 |" `8 m; I8 [! y;汇编程序
8 {% z+ M1 v4 b9 s) G( B
# t t& p2 _/ b( {& A; J AREA STRCOPY ,CODE,READONLY- f, c( _4 w$ {) K
0 ~, U- m3 \# z% {: t4 O EXPORT strcopy //使用EXPORT伪操作声明汇编程序
: Q; C/ s$ e. U0 C' @' x
% d$ O( X, F8 ^strcopy
2 H6 Z a1 n$ H. I5 O
6 _/ m8 `7 t2 W& u. i LDRB R2,[R1],#1 //寄存器R1中存放第srcstr地址+ D7 A) ?8 V& {% v) X$ M- s
+ S. {" y H6 A$ \7 k' s9 {5 j
STRB R2,[R0],#1- _/ ~1 b7 H% ]! }, L
. Y' V* h. f6 w* @1 e) h2 s: C) j& _ CMP R2,#0
& {: j2 `# Z& ]) j2 g: C8 T# k* {1 q N
BNE strcopy
/ T& W: q6 t5 G* m$ [" L" u) g1 w8 x! _& R5 a/ l/ [& E
MOV PC,LR
4 X0 W0 t% @2 F3 d
$ m/ U+ X8 ^- T0 T/ q6 p END2 D$ W6 v- F- n
: v! O* q4 y& O8 B, y' y
;汇编程序调用C程序
, P+ C4 E# H- m; Y) V T& O4 F* V2 o# i; @) [: ?: j
int sum(int a,int b,int c,int d, int e)
; G9 D' r+ r8 ^
: I1 L+ e P r6 M; ` y0 f{
: c$ ~* ~: g3 p2 c; R1 ?) t, j+ J return a+b+c+d+e;! | ^# \3 z# [
. z& \. h' z$ C9 g6 i8 m}
% Y9 n; a4 V8 @& M/ Q- ~% d3 Z! q: A& y, K* h* V! N
EXPORT CALLSUM2 k: ~& U: U% }3 k% x: L
1 [' o3 ?8 S K$ z3 M
AREA F ,CODE ,READONLY( u6 q' V% |+ }. U5 `% ^" M
$ A9 e# G) F8 ~% Z4 L) R
IMPORT sum ;使用IMPORT 声明C程序sum(): q" v; a% M3 S$ Y1 n; W7 K
. F0 a, C- g' o1 L V. \CALLSUM& ?& w" }. \3 Z9 {* ?/ M% n
, U k5 x ~' [! e; L, r
STR LR,SP! ;保存返回地址* p9 C) o6 m: I* g: g9 Q% g
' L0 [& |! K# b1 X9 O
ADD R1, R0,R0 ;假设进入程序时R0=I,设R1=2I
" E6 U! g* X% l
* {/ N1 L+ s& r2 z: ]# z ADD R2,R1,R0. l/ s; p8 G" G# D+ Z5 P; k
& B( }6 d. x# k: D+ w; V s
ADD R3,R1,R21 I5 ~# x% s$ t; M2 ?
- Z5 S! I5 b0 w, s3 A STR R3,[SP,#-4] ! ;第五个参数通过数据栈传递
: f' W5 S% H6 S% Y: }4 s; j* E
' U7 u0 T+ T; }/ C ADD R3,R1,R1+ y7 ~" M/ }- p1 U: B5 B
1 U" W* A9 h9 ^- r
BL sum
$ R# f% H. K8 C
* Y7 T# X, Y) l$ H ADD SP,SP,#4 ;调整数据栈指针,准备返回
- N0 s, z+ N0 }. J9 d( d
7 n1 T7 I6 p& f4 }0 q LDR PC,[SP],#4 ;返回
3 b2 g0 } m2 P) |/ l% u( e- K$ G/ T3 d$ ?& L& E, D
END |
|