Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1049871
  • 博文数量: 178
  • 博客积分: 10222
  • 博客等级: 上将
  • 技术积分: 2215
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-03 11:27
个人简介

有所追求

文章分类

全部博文(178)

文章存档

2012年(1)

2011年(5)

2010年(3)

2009年(78)

2008年(91)

我的朋友

分类:

2009-03-15 18:52:37

谢谢您的推荐

周一又上班了,按照进度今天应该上电做蜂鸣器的实验,不过出了点小问题,电源丢了,还要买电源,那今天就看看C语言与汇编语言相互调用的文档吧。
在开发板给的光盘上有一个文档ATPCS.pdf说的应该就是这方面内容,还是先看看中文的吧,原来(\)是续行符号呀,今天第一次听说。
在C、C++程序中使用内嵌的汇编指令的注意事项:
1 在汇编指令中(,)用作分隔符。因此如果指令中的C表达式中包含有逗号,则该表达式应该包含在括号内。
2 在指令中谨慎的使用物理寄存器,特别是需要调用函数或程序段的时候。
3 不要使用物理寄存器去引用一个C变量
4 对于在内嵌汇编语言程序中使用到的寄存器,便一起在编译时会自动保存和恢复这些寄存器,用户不用保存和恢复这些寄存器。
我验证一下:
第一个:略
第二个:结果如图所示:

按照原来的设想应该是sum=500+500/5=600;在实际编译中将100给了R0然后相加结果变成了200,这是因为保存500/5的结果的是R0,破坏了R0原有的数据。

 程序改为如图所示:设想的结果出来了,程序先把500放到R1里边去了,这样就不会被500/5的结果打扰。

第三个:很好理解,略
第四个:很好理解,略
从汇编程序中访问C程序变量(有这个必要吗?)
在C程序中声明的全局变量可以被汇编程序通过地址间接访问。1:先用IMPORT声明要用这个全局变量。2:用伪指令读入这个全局变量的地址。3:用相应的指令读取存储全局变量的值

前面所说的ATPCS.pdf我大略的找一下也为以后看着方便
关于ATPCS
什么是ATPCS,什么是PCS?
ATPCS即arm-thumb procedure call standard,PCS即procedure call standard.
PCS规定了应用程序的函数可以如何分开地写,分开地编译,最后将它们连接在一起,所以它实际上定义了一套有关过程(函数)调用者与被调用者之间的协议。PCS规范强制实现如下约定:调用函数如何传参(即压栈方法,以何种方式存放参数),被调用函数如何获取参数,以何种方式传递函数返回值。PCS规范的制订是一系列指标的“tradeoff”(因为很大程度上涉及系统的一些性能),如会涉及生成代码的大小,调试功能的支持,函数调用上下文处理速度以及内存消耗。当然,通过编译器的支持可以让生成的代码有不同的特性,如gcc编译选项可以支持或不支持framepointer来支持深入调试功能或提高程序运行性能。

PCS是体系结构密切相关的,直接涉及编译器如何使用处理器提供的应用寄存器,如编译器使用什么寄存器作为栈指针,利用哪些寄存器作直接传参等。值得注意的是,没有谁规定说ATPCS是必须这样而不是那样的,它是应用相关的,任何一个操作系统和应用可以处于它自身的考虑定义自己的PCS,当然,如果那样,也必须有自己的编译器,而实际上,在一个处理器设计时,都会有某种假设,所以PCS某种程度上应该是一样的。

ATPCS是基于arm指令集和thumb指令集过程调用的规范。


寄存器的使用规则:
寄存器的使用必须满足下面的规则:
1. 子程序间通过寄存器R0 R3来传递参数,这时,寄存器R0R3可以记作A1-A4。被调用的子程序在返回前无需恢复寄存器R0-R3的内容。
2. 在子程序中,使用寄存器R4 R11来保存局部变量.这时,寄存器R4-R11可以记作V1-V8。如果在子程序中使用到了寄存器V1-V8中的某些寄存器,子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值;对于子程序中没有用到的寄存器则不必进行这些操作。在Thumb程序中,通常只能使用寄存器R4-R7来保存局部变量。
3. 寄存器R12用作子程序间scratch寄存器(用于保存SP,在函数返回时使用该寄存器出栈),记作ip。在子程序间的连接代码段中常有这种使用规则。
4. 寄存器R13用作数据栈指针,记作sp。在子程序中寄存器R13不能用作其他用途。寄存器sp在进入子程序时的值和退出子程序时的值必须相等。
5. 寄存器R14称为连接寄存器,记作lr。它用于保存子程序的返回地址。如果在子程序中保存了返回地址,寄存器R14则可以用作其他用途。
6. 寄存器R15是程序计数器,记作pc。它不能用作其他用途。


    ADS编译链接环境定义了统一的函数过程调用标准ATPCS(ARM-Thumb Procedure Call Standard)。

1、概述:

    ATPCS定义{R0–R3}为参数传递和结果返回寄存器;
    若参数超过4个字型(32bit),则使用堆栈进行传递;
    ———内部寄存器的存取速度要远远大于存储器,一般应尽量使参数传递通过寄存器事项,即应尽量控制函数的参数在4个字型以下,使得函数调用尽量快、小、易于优化。
    ———深入理解ATPCS有助于透彻理解C与汇编混合调用时参出传递;
2、ATPCS中定义的寄存器:
    The first four registers r0-r3 are used to pass parameter values into a routine and result values out of a routine, and to hold intermediate values within a routine (but, in general, only between subroutine calls). In ARM-state, register r12—also called IP—can also be used to hold intermediate values between subroutine calls.

    Typically, the registers from r4 to r11 are used to hold the values of a routine’s local variables. They are also labeled v1-v8.

    In all variants of the procedure call standard, registers r12-r15 have special roles. In these roles they are labeled IP, SP, LR and PC (or ip, sp, lr, and pc).

3、子程序调用:

    子程序调用通过可实现如下功能的指令实现:
    LR <-- return address
    PC <-- destination address
    ...
    return address:
    ...
    这在ARM一般可通过一条BL指令达到。ATPCS规定子程序调用前后内核寄存器状态:
    ———因此,利用ADS编译环境(遵循ATPCS标准)编译后的子程序汇编代码一般不会对r4~r11操作,这也是如下两条语句普见于汇编代码中的原因(子程序中仅对r0~r3、r12等进行操作,故也只对这些个寄存器入栈出栈保护):
      STMFD   SP!, {R0-R3, R12, LR}
      …… ……
      LDMFD   SP!, {R0-R3, R12, PC}^
     
4、参数传递:
    头4个参数依次存于R0...R3,大于4个的后续字型参数通过栈传送,见ATPCS中的陈述:
5、返回值:
     一个子程序调用可能没有返回值(void型),也可能有1-4个字型(32bits)值返回(这里仅讨论返回值小于等于四的情况),这些返回值也装载在r0-r3中:
 
阅读(2770) | 评论(1) | 转发(0) |
0

上一篇:ARM异常和中断处理

下一篇:逻辑电平匹配

给主人留下些什么吧!~~

chinaunix网友2009-10-28 16:54:31

图片不能显示哦