|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
0 H6 p o- \1 k2 [第六章 ATPCS介绍
+ O$ I* H# l& y, B9 ]* Y' O6 M* B$ d0 k! k& Y9 x) V$ U
在汇编编译器中使用-apcs选项。
1 l5 F/ C/ G; o! f/ S4 X7 A* k& M. k1 h1 o
6.1.2寄存器使用规则
( g9 q, R# T7 V. ?2 @
9 k8 d G/ g- S- d% I1 D1 a* F子程序使用R0~R3来传递参数。用R4~R11来保存局部变量,thumb使用R4~R7。R12记作IP,调用scratch寄存器。R13记作SP,用作数据堆栈指针。R14记作LR,用作保存子程序的返回地址。R15记作PC,是程序计数器。3 ]; F' X4 k1 h1 [
* y+ k' J; I. n# Z* p. I, a4 |% L
6.1.3数据栈使用规则" ~1 e, {$ M1 F+ a
* T+ W+ T6 S8 M# q) [有四种堆栈方向:
$ V7 \6 Q6 [! c2 i$ H/ i6 Q/ \- ^$ O5 L
FD、FA、ED、EA
3 } a, C8 D- u6 d/ D: V: @7 W* H) Y2 a
ATPCS规定使用FD
: M( s9 C6 c; l0 p
9 @' b) [! s3 ^1 R1 l7 S8 Y u6.1.4参数传递规则- J$ V8 _+ p, V2 f6 n
5 O! h( l; Y) W% n. a) w4 @ o( o" W/ x
1、参数可变:参数不超过4,使用R0~R3,超过则将多的参数送到数据栈中保存9 F* ?9 O/ S' I+ }6 n/ P7 t3 |" ?
+ h, b2 g; F! E1 _5 |& \% C
2、参数固定:第一个参数,通过R0~R3,其他参数使用数据栈。
1 C' B7 M3 z8 R+ p, j v& Z# s- X, n. U5 p. m
3、结果返回:结果为32位整数,使用R0;结果为64位,使用R0和R1;结果为浮点,使用f0、d0或者s0;
4 e9 G2 V, X3 F: x2 G5 O R
) ]" \- L; ~. x+ X第七章 ARM和Thumb混合编程
, j% y+ o3 N y) O' @% |' q. _: v. }! \+ b, G4 I
状态切换指令:; z3 N7 ?6 p; a' `% b% b
7 Y8 ~* c* r0 T
BLX 、BX 目标地址: @! A. D9 q# \( k
2 X, U/ `1 i( X) ^& l( P: g
LDR、LDM及POP 向PC寄存器赋值
: B8 S# r0 x/ S+ t* ~) B' _" O9 E/ S; e" m
AREA AddReg ,CODE ,READONLY8 t) A2 o: |! c
: U1 S( I! J. }* y9 ?# z [ ENTRY
$ T. U! c& l: b) k, l
( I& \9 \0 u: W9 Gmain
1 n1 I1 v# A" e3 E/ H) V+ x0 P+ q6 y; C, h( h
ADR R0,ThumbProg+1 ;存储单元的地址肯定是偶数,也就是最低位肯定是0,但ARM与thumb之间的切换是
5 W$ D, G$ U% E7 D7 ], Z1 W. f3 M0 U" Y7 R: E. A( d
;通过Rn的最低位来判断的,1为thumb,0为ARM
2 d# w! P) U/ G) W: I% E( N( n
" v" B) i" M" a BX R0 ;跳转到ThumbPro,并且程序切换到Thumb状态
2 f, |( l& x* p' x9 G& d! T' g' @4 s W
CODE16
% S" v; X/ Y! k _+ e2 T
( J+ Y7 o9 v! B6 {$ CThumbProg8 h; c( q3 _0 ?5 O6 v5 b$ b3 U
; x9 f7 r4 s2 N# A- K2 \: t MOV R2,#2
7 w/ f3 b) a; }+ O; c9 [2 K# }. x! x5 N
MOV R3,#3
* h( u1 v2 _7 V7 ]/ x- F
8 K) c4 U) o( D6 R& T5 L. }6 K ADD R2,R2,R3
' \7 Y2 x$ B% a8 W& {: {/ R+ X8 ~1 r; q" r2 G) M9 o
ADR R0,ARMProg" m7 S7 n) I1 Z
" X* q- _8 g0 H* |% c% ^7 q
BX R0 ;跳转到ARMProg,并且切换到ARM状态% J% V; p0 H) ]" Q$ A$ P- ^5 U
9 }6 a4 N! g# f
CODE325 y0 F0 b0 J# ]6 Z0 H9 u
/ U( l9 _! z9 m! C7 }; n% eARMProg
8 y# _5 m! u, S4 e7 c, k' K2 g9 C
MOV R4,#4
' n# P H$ y' b" U( J* E) w/ c8 R# ]) C0 l
MOV R5,#5' K) q Q V' o3 T, N4 J4 I. l& T5 w
: Q+ K* c4 ~" J; F# n ADD R4,R4,R5 @, l4 l: O4 `1 i Y+ X
# {4 ~3 C1 g# Hstop
' C; C r5 ? |
( [; ~8 u9 s+ E. Y( m6 r) }3 m MOV R0,#0X182 i3 \5 B+ }( ~1 Y/ B* `
/ ~4 `4 C0 T, A9 }4 V; o
LDR R1,=0X20026( ]1 j( Z/ ~/ v. s# U
9 _$ x, r0 D- @. \3 ^# \" I SWI 0X123456+ x. X+ y7 n% C4 j8 c! a4 q
# M1 a# g! l$ G& H
END
, w" R- ?0 d3 f. y% l" Q
" ?1 B$ b( l5 C7 J! p1 G//C程序调用汇编程序
3 {: r5 \7 I' D1 s! Z/ Y& \; l
" b' h$ D9 Q9 S4 d" j% c( `3 A#include <stdio.h>+ O6 {% f' n$ _1 i% Q
/ b$ K0 z7 M' R# X2 I$ o
extern void strcopy(char *d,const char *s) ; //使用关键字extern声明外部函数,即调用的汇编程序
' E3 W) d. G; E- Y+ f/ A3 F* b/ J X% c1 ~$ R' w
int main(void). o! f% \3 O: `% j# U
" X' p/ F8 s) X# y
{
( H }" H z4 F$ _6 _: B const char *srcstr="Source string";
E. U8 v" c2 @1 L! A5 f* ?1 r* Z* o9 E5 T
char dststr[]="Destination string";
: h7 Z- `! B4 h' N, J9 m, ?
6 i n- s% S! i% {: O9 }# a printf("Before copying :/n");" _% T+ s1 N4 J: G/ h
3 R, r; L9 y. Z& m& x6 P/ P$ @
printf("%s/n %s/n",srcstr,dststr);
i) |! P, \5 K% C& p& C" q4 T; _# h9 P/ ]4 T" c+ E
strcopy(dststr,srcstr); 4 X( B: j% F6 u; k# i% l4 _. b
9 F1 }0 C. @, H/ A. q+ V printf("After copying :/n");& ^& F$ T% I- z i7 }( C
5 ~% {: H7 a" P4 s
printf("%s/n %s/n",srcstr,dststr);8 E6 R8 m2 |) {: I: h
" v) X- A; }4 h+ _) [4 S: Q# ]- [ return 0;# t# i; b! c# j$ v. t3 y
# S b1 {5 e0 a+ t3 Y
}
. I( i m) _ n$ a* G1 p1 l, e
" f6 h" n# ]5 O# M4 ?/ w+ K# O;汇编程序% g& ~7 T& F" I# ]! w! f' o
; z, e6 Q2 H# @7 x AREA STRCOPY ,CODE,READONLY
, }/ P& m1 V# r+ }
# x5 {7 w) \7 a3 j, q8 V EXPORT strcopy //使用EXPORT伪操作声明汇编程序
& B' B0 M/ |0 p
# p+ `9 ~2 u1 I/ Astrcopy
- l2 T# j v# z7 c8 I9 s I
2 n/ w( ?. z* n$ A/ k; h LDRB R2,[R1],#1 //寄存器R1中存放第srcstr地址% u2 m$ f5 ]% t) W
4 V9 I a7 y- J* R8 @: C! Y, p: M: v
STRB R2,[R0],#14 v9 Q9 k# w4 Z* F4 V- e
) L3 D$ Y, s5 J0 u
CMP R2,#0
5 B. K5 `1 y$ n; m z! _2 c
! T0 A2 x$ U# f* ^) d; t# n { BNE strcopy
: F0 A1 o4 k# ]' {+ ]( |8 E; ?
- O% I! v# N) M) F f- Q* g MOV PC,LR
3 n2 N/ F+ _% q/ F2 m) h, j5 l* @. e4 |/ a, c9 J# S1 l+ Q2 c- s7 A$ l$ ^
END
( {) }" {: n3 x- |. Z
3 R% V. v% k& R- \5 t8 ~;汇编程序调用C程序$ o5 P+ E6 {$ v0 b; M7 d
0 c+ o1 b) ]( X8 oint sum(int a,int b,int c,int d, int e)
' n6 l% w3 C3 r# q- ~* t' e' j5 Z U
6 S9 l$ A) i0 D; ^/ q" N{% g* j/ _: \* z- V/ R2 F8 ^
return a+b+c+d+e;. ~- S5 z4 C: s. C1 J+ s8 v9 t
6 v4 x7 Z( o+ j- l+ X, V& S
}
+ g8 c* X/ D" M8 I( S" z0 X% X6 k c: h+ g
EXPORT CALLSUM+ ~- f3 f2 ]; ?( C/ [
& n9 a; _: G% @: }3 I8 p: G" C AREA F ,CODE ,READONLY
: @3 \. S- @$ m% Q) E4 V7 G, l( x
|7 h0 S( O4 [% _- W: _; J IMPORT sum ;使用IMPORT 声明C程序sum()
) b9 Y5 h" K0 N# B4 o b1 {. D. h; W8 \& k) z. z; s4 f4 o1 t
CALLSUM
9 l7 \$ d4 Y1 ^
: ~& }& N0 E2 p+ L' t, C% H STR LR,SP! ;保存返回地址
6 J# z2 \- J. V, A5 ?
" K- C, h9 m/ I/ z ADD R1, R0,R0 ;假设进入程序时R0=I,设R1=2I
( m( a! \. F/ z3 y4 O- D
; ~6 n% f6 R. @! g# N; ` ADD R2,R1,R0" Z8 Y6 E( A k2 \0 `1 @
B# Y+ Q5 a3 G8 K ADD R3,R1,R2
/ _3 _: `0 O4 m/ y, P, c9 R. X5 W9 K7 d! D
STR R3,[SP,#-4] ! ;第五个参数通过数据栈传递
3 \. i; j) [) u* y: A* h/ u4 O0 N
( X9 Q0 I: o. _2 v ADD R3,R1,R1
# e& m* k5 Q+ C% |. n$ M, {% l5 C9 G- m& j9 u: v% \! q# r1 m+ [
BL sum
! q' x4 \9 _% h& s% u1 y# _3 V/ \5 O' {
ADD SP,SP,#4 ;调整数据栈指针,准备返回) K; D9 \; v* R& u2 M7 A
; m, V) k6 E3 r& ]3 y LDR PC,[SP],#4 ;返回
; G. b: Z ~4 {+ j4 n' C0 h) g! B( E0 Q# D* x8 n. U
END |
|