`
阿尔萨斯
  • 浏览: 4169242 次
社区版块
存档分类
最新评论

在BlackBerry PlayBook NDK 开发中嵌入ARM汇编语句

 
阅读更多

在BlackBerry PlayBook NDK开发中使用的是c和c++,都是编译后执行。在特殊情况下如果有需要使用汇编的话,也可以在使用c或者是c++的过程中嵌入汇编语句。

因为PlayBook使用的是ARM的CPU所以使用的汇编也就是ARM的汇编了。

之前在学习BeagleBoard上的QNX编程时也做过类似的实验,在c程序中嵌入使用ARM汇编语句。总结出来的结果是将ARM汇编独立到一个.S文件中会比较方便,更多的细节请参考之前的博文。

为了测试ARM汇编,在测试过程中就不能使用模拟器了,因为PlayBook 模拟器其实使用的是X86架构,不是ARM架构。

启动PlayBook NDK 开发环境,连接好PlayBook真机,就可以开始测试了。

在PlayBook NDK中新建一个BlackBerry Tablet OS c/c++项目,语言选择c,类型选择“Empty Application”,就是一个空的c项目。

然后在src目录中创建一个main.c源文件,将以下代码拷贝到main.c文件中:

#include <stdlib.h>
#include <stdio.h>

extern void damonfunction(int data);

long t;

void printResult(){
 printf ("t is: %d now \n",t);
 }

int main(int argc, char *argv[]) {

 t=10;
 printResult();
 damonfunction(&t);

 printResult();

 return EXIT_SUCCESS;
}


然后在src目录下创建一个汇编文件,以.S为后缀,文件名没有要求,我使用的是MyASM.S

然后将以下代码拷贝到MyASM.S文件中:

.section .text
.globl damonfunction
damonfunction:
@现场保存
mov ip,sp
sub sp,sp, #12

str lr, [sp]
str ip, [sp, #4]
str fp, [sp, #8]
sub fp, ip, #4
    @保存r0到栈中
    sub sp,sp,#4
    str r0,[sp]
    @恢复r0,并对r0地址指向的空间做赋值操作
    ldr r0,[fp,#-12]
    mov r1,#0x01e
    str r1,[r0]
         @调用printResult打印变量t
         bl printResult
    @再次恢复r0,并对r0地址指向的空间做赋值操作
    ldr r0,[fp,#-12]
    mov r1,#0x0020
    str r1,[r0]
@现场恢复
ldr lr, [fp, #-8]
ldr ip, [fp, #-4]
ldr fp, [fp,#0]
mov sp, ip
mov pc , lr


完成之后就可以编译测试应用了,该应用是一个控制台应用,启动后马上关闭,控制台会输出以下内容:

t is: 10 now
t is: 30 now
t is: 32 now

测试成功后回过头看看代码的细节,理解其中的关键部分才能在以后的现实编程中可以在c代码中灵活调用ARM汇编。

首先看看main.c,首先是有关damonfunction的定义很重要,表明方法damonfunction是一个需要从外部链接进来的方法,该方法有一个参数

extern void damonfunction(int data);

对应的,在MyASM.S中,就有对damonfunction这个标签的定义:

.globl damonfunction

damonfunction:

这就意味着在main.c的main函数中通过damonfunction(&t);调用damonfunction时就会调用MyASM.S中从damonfunction这个标签开始的程序。

在damonfunction开始执行和执行完成后会根据APCS(ARM过程调用标准)的要求保护现场,将寄存器中的内容保存起来。有关APCS,大家可以参考相关文章或者我的博文

《理解APCS-- ARM过程调用标准 》

http://blog.csdn.net/keyboardota/article/details/6799054

此外,调用damonfunction时,将全局变量t的地址传给了方法damonfunction,根据APCS,方法的第一个参数会被保存在r0寄存器中,所以在MyASM.S代码完成APCS相关的现场保护工作后,就将r0压入栈中,供后面使用,代码如下:

sub sp,sp,#4
str r0,[sp]


这里不直接使用r0进行后续计算的原因是期间会调用其它方法,r0有可能被破坏,保险的方法是将r0压入栈中,需要使用变量t的地址时从栈中取出来用。取出来变量t地址的代码如下:

ldr r0,[fp,#-12]


为了测试汇编方法是否执行,在damonfunction中对变量t做了一个赋值动作,将0x01e给了变量t,这是变量t就等于0x01e了,就是十进制的30,代码如下:

mov r1,#0x01e
str r1,[r0]


执行了赋值动作后,通过bl,就是带链接的跳转,调用方法printResult,这个方法是在main.c中定义的,结果是将变量t输出到控制台。调用printResult的汇编代码如下:

bl printResult


执行完以后再次对变量t赋值,将0x020,就是数字32赋予了变量t,代码如下:

 ldr r0,[fp,#-12]
 mov r1,#0x0020
 str r1,[r0]


最后是现场恢复,然后通过mov pc , lr返回。

通过以上的样例可以了解PlayBook NDK编程过程中如何嵌入ARM汇编程序,虽然在目前的情况下,一般编程人员都不会使用汇编进行编程,不过对于一些特殊情况,嵌入一段汇编程序会有特殊的效果。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics