EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x

, U) b) }+ U8 \" d/ v( \$ ~  T对于ARM体系来说,不同语言撰写的函数之间相互调用(mix calls)遵循的是 ATPCS(ARM-Thumb Procedure Call Standard),ATPCS主要是定义了函数呼叫时参数的传递规则以及如何从函数返回,关于ATPCS的详细内容可以查看ADS1.2 Online Books ——Developer Guide的2.1节。这篇文档要讲的是 汇编代码中对C函数调用时如何进行参数的传递以及如何从C函数正确返回9 O; |6 z8 ?, g- u

" ?# B! P0 k+ [+ p1 d+ w$ U9 {

不同于x86的参数传递规则,ATPCS建议函数的形参不超过4个,如果形参个数少于或等于4,则形参由R0,R1,R2,R3四个寄存器进行传递;若形参个数大于4,大于4的部分必须通过堆栈进行传递。

" e- U7 W" f3 ?3 o; N

9 _/ R1 ]2 \$ Y# D2 b# c& U$ X我们先讨论一下形参个数为4的情况.

/ u6 P5 t. W( Q- E( I实例1:) p2 U- M; [/ k& F

test_asm_args.asm0 \: b" C7 M7 q& }& l1 \2 @5 M. C

//--------------------------------------------------------------------------------( v  u' l& a3 z* e

IMPORT test_c_args ;声明test_c_args函数/ G# A" s& _8 k; C

AREA TEST_ASM, CODE, READONLY

: D& M6 M6 y3 `* t" b        EXPORT test_asm_args% g) p- L! c2 J8 m6 ]

test_asm_args( G+ m% Y, s' B# a% E1 V" }

STR lr, [sp, #-4]! ;保存当前lr# |. [1 x# Y  E* h* i( }

ldr r0,=0x10       ;参数 18 h* ^& r, s* j4 Z2 F2 P

ldr r1,=0x20        ;参数 2% J% I( |) Z- V* x& i

ldr r2,=0x30        ;参数 3* j) R3 H4 `  a. G4 W/ k$ R% y

ldr r3,=0x40       ;参数 4

! @' T: w, i5 ?4 \        bl test_c_args      ;调用C函数- [. P( O& r. [1 f; K( @

LDR pc, [sp], #4  ;将lr装进pc(返回main函数) 8 L/ C" U% g: s

END% ~0 |2 C, L" f" b! O0 Z% n9 P

test_c_args.c

1 a  A5 z" `# U& b) M" M//--------------------------------------------------------------------------------( d1 F  X4 \- S" h) h# R3 ]& o- [5 C

void test_c_args(int a,int b,int c,int d)

' u- j* f+ d* p6 d{& \2 Z- F- B1 u% w

printk("test_c_args:/n");

" `1 R9 K9 M5 V' s1 z, e        printk("%0x %0x %0x %0x/n",a,b,c,d);7 D4 ~4 `3 r- d, j

}4 W! t2 ^2 Q, q' z: y: ]8 A

main.c

9 d& n/ K+ Z! q" P  o//--------------------------------------------------------------------------------

1 h& J: a4 N2 _$ q7 f! [0 eint main()

3 O( `# U% E7 u2 [4 q3 U( V. L{

* `4 O5 |/ f! C5 L2 I3 b     test_asm_args();

6 |) E1 c3 N7 Q9 g     for(;;);" I( g$ W5 O. \0 t

}

" p1 ]; C, L; {3 l0 ^

4 g7 x4 X' O  J程序从main函数开始执行,main调用了test_asm_args,test_asm_args调用了test_c_args,最后从test_asm_args返回main." ^1 {5 `' [0 O8 h' q

代码分别使用了汇编和C定义了两个函数,test_asm_args 和 test_c_args,test_asm_args调用了test_c_args,其参数的传递方式就是向R0~R3分别写入参数值,之后使用bl语句对test_c_args进行调用。其中值得注意的地方是用红色标记的语句,test_asm_args在调用test_c_args之前必须把当前的lr入栈,调用完test_c_args之后再把刚才保存在栈中的lr写回pc,这样才能返回到main函数中。% }6 \( Z$ L# g, ^

8 o" T" f" T7 e* d3 U" x, K; a+ m5 j, L/ c; K/ t; f2 d0 ?

如果test_c_args的参数是8个呢?这种情况test_asm_args应该怎样传递参数呢?' F0 J" v0 F$ a7 n2 S

实例2:

, q; h! b, v+ ktest_asm_args.asm

7 B# `8 B6 K0 j; n4 Q//--------------------------------------------------------------------------------3 d0 C( `9 q' o% T

IMPORT test_c_args ;声明test_c_args函数

! [, @$ A3 B+ X/ W& K" P        AREA TEST_ASM, CODE, READONLY

. K# I/ x# v# r& o( S        EXPORT test_asm_args

- ?/ Q7 ^  r: q+ k5 h7 ptest_asm_args+ C% V% E) W/ D8 K; J8 I

STR lr, [sp, #-4]! ;保存当前lr- J, Y, s. x9 D0 L

ldr r0,=0x1 ;参数 14 D, e/ @$ w' o, Y3 b6 O

ldr r1,=0x2 ;参数 2

0 p4 B9 A) z1 R" d       ldr r2,=0x3 ;参数 3

7 [( l5 `( J- e" j- R; O; g# {       ldr r3,=0x4 ;参数 4

: E5 T; d( l- ?9 T, n5 G6 T, X       ldr r4,=0x8

! p% y% v# l: v       str r4,[sp,#-4]! ;参数 8 入栈. Z% l# H; h) w1 Z, J" r% M; b: K

ldr r4,=0x7~+ K& N2 w1 y1 b# \

str r4,[sp,#-4]! ;参数 7 入栈% G( Q: ^+ y7 [( t1 J0 \1 s1 d; O

ldr r4,=0x6: X" c) A- c: B  M. j) u

str r4,[sp,#-4]! ;参数 6 入栈

& y1 G* g$ u. e) a) x       ldr r4,=0x5* H5 m4 L* N$ c

str r4,[sp,#-4]! ;参数 5 入栈, V* R/ v8 W$ G2 h, [' F- M$ `" ^

bl test_c_args_lots

8 i% t8 `0 Y! z& B9 F4 u0 h' e& Q       ADD sp, sp, #4     ;清除栈中参数 5,本语句执行完后sp指向 参数6 # V0 D" b" d- {5 k1 V

ADD sp, sp, #4     ;清除栈中参数 6,本语句执行完后sp指向 参数75 q. l4 Y0 ^/ v+ }" ~* ^4 P, {' i

ADD sp, sp, #4     ;清除栈中参数 7,本语句执行完后sp指向 参数8

0 `8 U+ |' d2 ?; F1 S- X       ADD sp, sp, #4     ;清除栈中参数 8,本语句执行完后sp指向 lr. _* ?! A8 ^* l

LDR pc, [sp],#4    ;将lr装进pc(返回main函数) % I6 f" K( y( R" h$ J( j

END, e9 |5 @/ r  e! D' }6 b$ Y

test_c_args.c

7 [  x9 D/ J1 p3 w: R) L& ?! S! O8 g& {//--------------------------------------------------------------------------------

3 H: y' V2 C6 j' A" P& ^void test_c_args(int a,int b,int c,int d,int e,int f,int g,int h)

& C" M5 p5 t, k- Z3 a6 L0 ?{0 X; v7 n" }5 M" O

printk("test_c_args_lots:/n");. |( @9 P, v# D. A# ^* k* k

printk("%0x %0x %0x %0x %0x %0x %0x %0x/n",/ L8 d. I  D& Z+ p$ i4 ]

a,b,c,d,e,f,g,h);

" A$ u4 T! _+ f  [( c}! b1 v! [6 F6 K" P. t

main.c! B8 N3 p5 [6 a$ J

//--------------------------------------------------------------------------------

& S# I1 z" F8 Q+ x+ @5 }9 y4 `- \int main()

: D4 U" k4 `/ P7 c! f{

# l! }4 b! r6 S1 r8 _( e- \  H     test_asm_args();

3 ~0 A3 R6 V- d- x' p     for(;;);, B' T, [  p& U* o& {

}' Z3 n: z) u. Y& @

) G4 d9 Z. Z% s% h" H  B

这部分的代码和实例1的代码大部分是相同的,不同的地方是test_c_args的参数个数和test_asm_args的参数传递方式。

5 g& H+ x& z- m在test_asm_args中,参数1~参数4还是通过R0~R3进行传递,而参数5~参数8则是通过把其压入堆栈的方式进行传递,不过要注意这四个入栈参数的入栈顺序,是以参数8->参数7->参数6->参数5的顺序入栈的。

) K, g+ ~7 F, p; @1 A直到调用test_c_args之前,堆栈内容如下:% f9 f3 x% m8 M8 b: ~

sp->+----------+

% W" N6 S5 \* c: p$ Q        |  参数5  |0 V8 H8 r! _) |+ x2 Z- N

+----------+

/ b0 E* ?; U( ?: e        |  参数6  |; p! g  J& O% }, j

+----------+, U3 k# ^& ~2 F: R! {  Z

|  参数7  |$ `1 D+ Q2 j2 n- W: u

+----------+

( m6 i; E1 j* D! Q* `& v        |  参数8  |+ c/ `, [& E# j6 ^

+----------+

& d5 P' Q" F" R  w7 A, \2 @        |     lr      |+ R8 b  T+ _" G

+----------+

- o" S. J; @4 O1 W6 I& O  I/ F- Ntest_c_args执行返回后,则设置sp,对之前入栈的参数进行清除,最后将lr装入pc返回main函数,在执行 LDR pc, [sp],#4 指令之前堆栈内容如下:) g$ w& @3 y$ r- ~

+----------+7 K. S, b& |. k; m$ ?

|  参数5  |

# v+ M' x: m' m$ E2 x8 ]. `       +----------+

, J- D% E* q9 k        |  参数6  |

4 a! a7 x7 w2 `. Y1 t; f: N& @       +----------+0 R! M  Z, Q  d

|  参数7  |

" A  t( \5 J+ ]+ |1 R. @       +----------+- N: M4 H2 \1 n- K( X! C: |" Z1 t

|  参数8  |9 O! S/ I! W: j% n+ \" D. }

sp->+----------+% |! B3 Z) I5 ~: o2 d

|     lr      |* r1 q9 Q- V7 P, H

+----------+

汇编语言调用c语言ads,ADS1.2 在汇编代码中调用C函数相关推荐

  1. python语言format是什么意思_Python代码中str.format()函数有什么功能呢?

    摘要: 下文讲述Python代码中str.format()函数的简介说明,如下所示: str.format()函数功能 用于将字符串格式化,然后输出 str.format()函数语法 通过{} 和:替 ...

  2. c语言代码中调用系统命令行.sh shell脚本,linux shell system传参

    C语言代码中调用命令行: 1. 使用system(" 命令行 ");    --  执行完命令行后,会返回原先C代码的位置,继续执行. 2. 如果命令行中需要传参,使用 sprin ...

  3. c语言调用c 方法,C语言代码中调用C++代码的方法示例

    由于历史原因,以及不同开发人员的技术偏好,C语言和C++语言都有一些独有的非常有价值的项目,因而两种语言的互操作,充分利用前人造的轮子是一件非常有价值的事情. C++代码调用C代码很简单,只要分别在包 ...

  4. Golang cgo:如何在Go代码中调用C语言代码?

    如何在Go代码中调用C语言代码? Go语言是通过自带的一个叫CGO的工具来支持C语言函数调用,同时我们可以用Go语言导出C动态库接口给其它语言使用. 方式一.直接在 Go 代码中写入 C 代码 检查是 ...

  5. C 语言编程 — 结构化程序流的汇编代码与 CPU 指令集

    目录 文章目录 目录 文章目录 为什么要保留汇编语言 顺序程序流 条件程序流 循环程序流 函数调用栈的工作原理 文章目录 <C 语言编程 - GCC 工具链> <C 语言编程 - 程 ...

  6. 调用c++_WebAssembly: 在C代码中调用JS的函数

    0. 前提知识点 导出C中的函数给JS调用:主要是EMSCRIPTEN_KEEPALIVE这个Emscripten环境特有的宏. #include <stdio.h>#ifndef EM_ ...

  7. bcs转10 c语言,小弟刚学习C语言,怎么把下段汇编代码转化为C语言程序,请高手指教!!!单片机89c52...

    已结贴√ 问题点数:20 回复次数:3 小弟刚学习C语言,怎么把下段汇编代码转化为C语言程序,请高手指教!!!单片机89c52 BIT_COUNT     DATA 07FH TIMER0       ...

  8. R语言ggplot2可视化:使用ggfortyify包中的autoplot函数自动可视化时间序列数据(Time Series Plot From a Time Series Object (ts))

    R语言ggplot2可视化:使用ggfortyify包中的autoplot函数自动可视化时间序列数据(Time Series Plot From a Time Series Object (ts)) ...

  9. python把模块装到文件夹中_把模块有关联的放在一个文件夹中 在python2中调用文件夹名会直接失败 在python3中调用会成功,但是调用不能成功的解决方案...

    把模块有关联的放在一个文件夹中 在python2中调用文件夹名会直接失败 在python3中调用会成功,但是调用不能成功 解决办法是: 在该文件夹下加入空文件__init__.py python2会把 ...

最新文章

  1. Go实现简单的K-V存储
  2. (Ajax)axios源码简析(三)——请求与取消请求
  3. 【报告分享】2019-2020广告主KOL营销市场盘点及趋势预测.pdf(附下载链接)
  4. 旷视孙剑团队提出AutoML神经架构搜索新方法:单路径One-Shot,更精确更省时
  5. linux下命令行操作快捷键及技巧
  6. 《我也能做CTO之程序员职业规划》之二:做CTO的苹果定律
  7. Xampp mysql启动
  8. css中background-image与background-color在元素背景中开始结束的位置
  9. 字符串模式匹配sunday算法
  10. uniapp中获取元素页面信息的方法
  11. Qt安卓开发环境搭建
  12. MATLAB 格拉布斯准则代码
  13. 数字通信学习笔记——自相关函数、随机信号
  14. 考研408(操作系统、计算机组成原理、数据结构、计算机网络)
  15. 达梦数据库解决ZYJ环境数据库连接会闪断的问题
  16. 7939.com,7b.com.cn,9505.com,4199.com 清除工具(转)
  17. 哈工大C语言程序设计精髓第十三周
  18. ubuntu下安装git安装及使用
  19. Java应届生大学四年怎么做,可以毕业就进入华为工作,致Java高级工程师的一封信
  20. Cadence CIS 器件管理平台解决方案

热门文章

  1. Java 栈的存储过程
  2. 程序设计基础——c语言篇,C语言程序设计基础篇.ppt
  3. c语言程序设计语言描述,C语言程序设计题目描述(详).txt
  4. R之Excel文件读取与程序包的安装调用
  5. 山东大学 2020级数据库系统 实验八、九
  6. 孕妇能长期在计算机屏幕前工作吗,怀孕了在电脑前工作怎么办
  7. new 结构体指针_Go:我应该用指针替代结构体的副本吗?
  8. python3 robotframework+pycharm框架搭建
  9. Python习题week2
  10. pycharm中windows找不到chrome解决办法