好记性不如铅笔头

ARM, 操作系统

《RealView编译工具开发指南》摘录: C和汇编语言互相调用

CONTENTS

备注:

1 本部分文档摘录自ARM网站【 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0203ic/index.html 】,版权归属于ARM。

2 作者只摘录了部分内容,这里主要是C和汇编相互调用,全面详细的内容清参考ARM网址。

4.2. 在汇编代码中访问 C 全局变量

全局变量只能通过地址间接访问。 要访问全局变量,请使用 IMPORT 指令执行导入,然后将地址加载到寄存器中。 根据变量的类型,可以使用加载和存储指令来访问全局变量。
例如,对于 unsigned 变量:
    LDRB/STRB 用于 char
    LDRH/STRH 用于 short
    LDR/STR 用于 int
对于 signed 变量,请使用等效的有符号指令,如 LDRSB 和 LDRSH。
使用 LDM 和 STM 指令可以将少于 8 个字的小型结构作为整体进行访问。 可以使用适当类型的加载和存储指令来访问结构的单个成员。 为了访问成员,必须知道该成员从结构起始地址算起的偏移量。
Example 4.1 将整型全局变量 globvar 的地址加载到 R1,将该地址中包含的值加载到 R0,将它与 2 相加,然后将新值存回 globvar 中。

Example 4.1. 访问全局变量

    PRESERVE8
    AREA     globals,CODE,READONLY
    EXPORT    asmsubroutine
    IMPORT    globvar
asmsubroutine
    LDR  R1, =globvar   ; read address of globvar into R1
    LDR  R0, [R1]       ; load value of globvar
    ADD  R0, R0, #2
    STR  R0, [R1]       ; store new value into globvar
    BX   lr
    END

 4.4. C、C++ 和 ARM 汇编语言交叉调用

本节提供一些示例,帮助您在 C++ 中调用 C 和汇编语言代码,以及在 C 和汇编语言中调用 C++ 代码, 还介绍调用约定和数据类型。
只要遵循 ARM 体系结构的过程调用标准 (AAPCS),就可以混合调用 C、C++ 和汇编语言例程。 有关详细信息,请参阅 install_directory\Documentation\Specifications\… 中的 AAPCS 规范 aapcs.pdf。

4.4.3. 语言交叉调用的示例

在 C 中调用汇编语言

Example 4.4 和Example 4.5 介绍的 C 程序调用了汇编语言子例程,将一个字符串复制到另一个字符串之前。

Example 4.4. 在 C 中调用汇编语言

#include <stdio.h>
extern void strcopy(char *d, const char *s);
int main()
{   const char *srcstr = "First string - source ";
    char dststr[] = "Second string - destination ";
/* dststr is an array since we’re going to change it */
    printf("Before copying:\n");
    printf("  %s\n  %s\n",srcstr,dststr);
    strcopy(dststr,srcstr);
    printf("After copying:\n");
    printf("  %s\n  %s\n",srcstr,dststr);
    return (0);
}

Example 4.5. 汇编语言字符串复制子例程

    PRESERVE8
    AREA    SCopy, CODE, READONLY
    EXPORT strcopy
strcopy               ; R0 points to destination string.
                      ; R1 points to source string.
    LDRB R2, [R1],#1  ; Load byte and update address.
    STRB R2, [R0],#1  ; Store byte and update address.
    CMP  R2, #0       ; Check for null terminator.
    BNE  strcopy      ; Keep going if not.
    BX   lr           ; Return.
    END

Example 4.4 位于示例目录 …\asm 中,文件名为 strtest.c 和 scopy.s。
请按以下步骤在命令行生成该示例:
    键入 armasm –debug scopy.s 编译汇编语言源代码。
    键入 armcc -c –debug strtest.c 编译 C 源代码。
    键入 armlink strtest.o scopy.o -o strtest 链接对象代码。
    通过对相应调试目标使用兼容调试器来运行映像。

在汇编语言中调用 C

Example 4.6 和Example 4.7 演示如何在汇编语言中调用 C。
Example 4.6. 定义 C 函数

int g(int a, int b, int c, int d, int e) 
{
    return a + b + c + d + e;
}

Example 4.7. 汇编语言调用

    ; int f(int i) { return g(i, 2*i, 3*i, 4*i, 5*i); }
    PRESERVE8
    EXPORT f
    AREA f, CODE, READONLY
    IMPORT g           ; i is in R0
    STR lr, [sp, #-4]! ; preserve lr
    ADD R1, R0, R0     ; compute 2*i (2nd param)
    ADD R2, R1, R0     ; compute 3*i (3rd param)
    ADD R3, R1, R2     ; compute 5*i
    STR R3, [sp, #-4]! ; 5th param on stack
    ADD R3, R1, R1     ; compute 4*i (4th param)
    BL g               ; branch to C function
    ADD sp, sp, #4     ; remove 5th param
    LDR pc, [sp], #4   ; return
    END

 

发表评论

8 + 6 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据