|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
: {% }, s; G" c' E& x; H1 J8 e9 U- i第六章 ATPCS介绍
% z8 [" g0 t5 d$ R. R) w7 ~' l8 }$ i, @& M) {
在汇编编译器中使用-apcs选项。( \0 G) F: j2 l. p7 F3 G. G
- ]. v# U/ @1 L! E) ~0 D6.1.2寄存器使用规则
' X/ w0 D5 G! y9 B0 H5 V8 ?+ g* K% |* y' L6 y! G# o* `, i. [; H
子程序使用R0~R3来传递参数。用R4~R11来保存局部变量,thumb使用R4~R7。R12记作IP,调用scratch寄存器。R13记作SP,用作数据堆栈指针。R14记作LR,用作保存子程序的返回地址。R15记作PC,是程序计数器。
0 K3 I5 m7 Q+ Z0 n6 y p# I( n4 z' e, O6 l1 s3 L+ k k( D1 p
6.1.3数据栈使用规则+ R! S4 m! v! M* S% v' ~
( [2 Q) i5 w! B7 T8 Z* w2 }4 h# `
有四种堆栈方向:
9 W3 R, b/ x7 \! b E* V: @: A4 G" g, w
FD、FA、ED、EA W6 e; r! ?' o3 w
1 H+ L% _9 O! S8 a% i
ATPCS规定使用FD
) T/ D( ]6 X. _% Z6 L$ x, K2 g$ O! a8 w, {% `
6.1.4参数传递规则
/ M- i# J% {+ }* i" i9 h) f; u* O1 y- f. O9 W' N
1、参数可变:参数不超过4,使用R0~R3,超过则将多的参数送到数据栈中保存
$ i/ M5 B$ U8 } o7 k$ b# j3 N' K1 R% F# q8 E& I
2、参数固定:第一个参数,通过R0~R3,其他参数使用数据栈。
" n: A. [6 }: M$ a1 I p+ Z( q$ {+ C. ~
3、结果返回:结果为32位整数,使用R0;结果为64位,使用R0和R1;结果为浮点,使用f0、d0或者s0;
" w# a, U6 M8 Z; b3 R. Q6 G( D' Y% r$ ] ]8 b
第七章 ARM和Thumb混合编程: ^4 p4 `$ |* M! }8 c0 m) r+ o* X
9 ^9 Z5 n) p# g9 ?状态切换指令:
8 F6 C2 p* j2 |$ U
7 ^( U8 M7 M( ^. GBLX 、BX 目标地址$ H7 S# b$ {) z, i/ c, A- Q6 ~
3 g. C; w! q7 G2 p4 J% r$ a; f' YLDR、LDM及POP 向PC寄存器赋值
1 m/ ]; G" t; r( z, a) g/ y9 d. C) p- p" N7 `3 N
AREA AddReg ,CODE ,READONLY6 |0 r4 h Y2 d7 G
5 O# H6 @- }8 a- I/ c+ r ENTRY7 j: x/ l: u/ L/ k5 D2 U( I- ]
* E9 C0 x% Z& K$ w
main
: p7 h( D1 u t+ [# r' j
% u% n- N0 [) z( y O8 {/ V ADR R0,ThumbProg+1 ;存储单元的地址肯定是偶数,也就是最低位肯定是0,但ARM与thumb之间的切换是% M3 y# |5 _! P
U5 \. F3 T& Y/ I
;通过Rn的最低位来判断的,1为thumb,0为ARM
: V) `& h" B$ [ X5 |4 ]' |
. b# L, s: H7 ~0 ~- G BX R0 ;跳转到ThumbPro,并且程序切换到Thumb状态
; g1 f( }0 A7 F) a9 u6 ~! x1 a5 P. M' O
CODE16
; b# |- m) u5 R0 T/ N9 }7 C1 O& ]( Z o2 @# O& W4 R' O
ThumbProg
# t; M: G, r) Z
2 H* V$ N( `4 ?* F MOV R2,#26 X1 i( f' ?5 d1 F
% W) L4 T7 j3 h* X) ^8 w' L1 k MOV R3,#3
# I1 K5 a' \& v# C; s% k1 ]. H: I4 g2 |# w" g# Q& Y
ADD R2,R2,R3' s4 r2 ?- r4 B
" c4 k" `0 { ~6 v3 ]9 b
ADR R0,ARMProg
6 w" J( Y0 @& r3 c& f: P/ X% e" L, I( Y5 z! h5 V, C+ k
BX R0 ;跳转到ARMProg,并且切换到ARM状态
4 \1 c$ {+ }5 t7 W0 _- c/ ^ d# q& A5 G9 t" F
CODE32
! u4 K, k% `& R- y/ o/ {$ |- J7 ?9 K! y8 L# D+ r. W- R# X
ARMProg
* a# K/ [+ y, I! O0 t& x5 K
1 i0 I0 \5 }4 S- K; f MOV R4,#4
9 \2 H J6 C r7 N( f) `( r7 I& I' b* y/ R! i6 b5 _: z9 r, v
MOV R5,#5
6 f8 @0 _9 a0 C5 f' u/ `6 ~$ h
% G4 d1 p8 s0 Y }% S ADD R4,R4,R5
6 B5 y- d, h: F7 _* s+ Z0 g7 v8 @, J
stop" C) l3 S7 N7 V+ E8 B9 p
p- t6 ]" r8 s) X MOV R0,#0X18
" m5 c* {2 ? r: U/ q, @" _$ Z' P
; I+ M. c' H2 N1 C2 ? LDR R1,=0X20026
7 o' W- l7 x. X; }' i! a
9 Y! b" Y. p/ ^! S6 Y6 _/ v, F SWI 0X123456) b3 ]. ?0 c) Y" E
! J% A0 ~' ~- S+ ^! r w END/ k2 A+ Q. K% q* z
) W! u. `/ m" ^8 V8 b! P( z/ d* S//C程序调用汇编程序6 V7 P' p7 [8 u7 L" c3 @2 K6 p
" p2 K% C, b" C/ d* M% @+ H' i
#include <stdio.h>
* b0 H) `1 \ w8 G7 B5 {9 v! {5 C/ I- i9 N3 O: f2 Z
extern void strcopy(char *d,const char *s) ; //使用关键字extern声明外部函数,即调用的汇编程序
5 x0 `. p, u* m; j0 j+ v$ T
2 O% z" a' J. N6 Q$ u6 @1 Nint main(void)
3 G, |7 I7 I+ H7 z0 t' A) ]) i) C
. \* A6 T9 U4 A' l{. P# W0 k% C; v9 ]' r
const char *srcstr="Source string"; ?+ {" r) H0 |* y* ^3 O. E8 h
# n7 g* }) E1 i0 t6 d6 Z( d+ T2 p char dststr[]="Destination string";, @. o0 c4 l5 W, _$ L8 i
, k5 E( w" Y0 r9 Y" x! Z, ^9 ?
printf("Before copying :/n");
' H2 I8 E9 ]5 O- g$ W( \6 A0 g1 T. B5 i4 t9 l
printf("%s/n %s/n",srcstr,dststr);
. I% \: `7 e o: V6 L+ o
- U9 b O0 C- J K( G0 E% |. O ? strcopy(dststr,srcstr); 4 w4 j3 L4 N" A3 ^
9 G6 [1 O) b8 j5 F6 S, c, C
printf("After copying :/n");
b4 {8 Z% W9 A, \5 R' q
f$ r) }/ R5 X5 g" p! } printf("%s/n %s/n",srcstr,dststr); V% T" W# R O, ]
& ]/ i- @7 q5 D+ e; }2 g9 _2 z: ?
return 0;# P& b' Y( u0 u2 Q
1 ~4 |, m _3 C, v% S
}. i5 t2 p1 R, N( }' e# Q& ~% L; D
- q1 t' _& m2 ]3 V* W5 K1 o;汇编程序
) R: r4 E* o% o% L: z
7 {; ~! ]8 U u6 A AREA STRCOPY ,CODE,READONLY! H, L. i4 e7 U/ x! @( t! k
3 _. F7 i# \1 V' f1 P/ `; u EXPORT strcopy //使用EXPORT伪操作声明汇编程序+ O8 D& s- t. }% V, v/ c& ]
. d8 p2 u$ c+ B5 d7 D& d1 E- nstrcopy
! F; y7 g7 t+ q& X/ v1 U. O4 j; M% u; x& P* E4 b8 R4 n9 g
LDRB R2,[R1],#1 //寄存器R1中存放第srcstr地址# U8 F L. Y' |5 b
6 ?& ~& W5 x, T; b- C8 q STRB R2,[R0],#15 X# u( w; [6 J* X* R
7 o. ~& }) {+ O: y: ]2 Z
CMP R2,#0' E/ ?' ?( H( W/ l0 w/ ~9 {: Q
, c5 _; N; ~( @/ I; S BNE strcopy
, M- k/ k1 l% b2 f- U+ V' E6 Z4 A+ s: \6 g7 U
MOV PC,LR, m: I6 O7 \$ _
) f. [9 k" G4 N6 D4 q
END
$ _# {8 `3 X8 |8 g
- L# x; y/ D& B/ Q/ o6 k;汇编程序调用C程序
5 r. [' y" {7 _" m
" K+ O3 C. I+ y( }int sum(int a,int b,int c,int d, int e)
2 A; k/ s; j6 d D
+ t. X( D6 s7 D& E/ X& T+ y{
+ E0 ]* \% t# F$ z& u return a+b+c+d+e;. E0 ]) R; d" M' w
, C: s( u/ t3 {1 {" ?! P}1 I* v3 t1 G" W' E* ?3 x0 N- G
1 P& }* f* E4 e' b9 k/ l
EXPORT CALLSUM- i5 P4 F/ I3 B* Q: ]
* H1 A6 x9 s/ {' J AREA F ,CODE ,READONLY
; G: L/ E2 @; S# i) N
! }* a* f# Z, o+ d5 p0 Y IMPORT sum ;使用IMPORT 声明C程序sum()
( u0 b/ _/ M5 D5 b# L) |9 K! ^; Q" M \. J2 H! k0 V, x
CALLSUM+ ?8 C: i8 r B3 I$ A$ \" l
, j4 V$ b! [ K/ C4 `3 A STR LR,SP! ;保存返回地址
" K; {. c" P4 U& g5 W" n" [7 p/ v4 d+ z2 z6 M U+ F0 L1 K
ADD R1, R0,R0 ;假设进入程序时R0=I,设R1=2I
* w8 E4 n! a+ ?* I6 O' ^ f; A& E6 E) a0 @( ]* \& d
ADD R2,R1,R03 `& z( s, ^" f1 c
8 ]2 ?7 o1 t; X1 t: w% ^
ADD R3,R1,R2% Q1 Z( U8 \' ~8 p# S
) p7 [' X% B9 O' e- K } STR R3,[SP,#-4] ! ;第五个参数通过数据栈传递. Q q0 }. R( M9 y/ m' z1 ~
& A* `8 M# k; k: Y9 a8 H ADD R3,R1,R1# O8 m) B/ D' i' t9 b5 x9 E
8 M( D$ x% i( J( T: ` BL sum1 T; k3 ~6 p( [7 Z
) |$ H" R' Q# D7 i; i# g% d
ADD SP,SP,#4 ;调整数据栈指针,准备返回
* v# E+ Q5 `1 [: E3 l" B. m9 D# d
LDR PC,[SP],#4 ;返回
. [$ F/ k( F9 b6 x \& f: s
5 t6 N e: \8 t! }4 y# @ D, j2 i3 n END |
|