看arm汇编遇到的几个问题,请各位达人讲解,谢谢!

lessun   2009-2-28 21:22 楼主
1.汇编程序调用C程序
C_add.c

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

ARM_add.s

AREA ARM_add,CODE ,READONLY
EXPORT ARM_add
IMPORT g
ENTRY

STR LR ,[SP,#-4]!  ;保存返回地址
MOV R0,#1
MOV R1,#2
MOV R2,#3
MOV R3,#4
MOV R4,#5    ;设置参数,R4用数据栈传递   ????为什么只有R4,其他的寄存器呢
STR R4,[SP,#-4]!  ;只有R4,入栈了,其他的呢,
BL g     ;??????如何传递的呢,R0,R1,R2...怎么没有显示的调用呢?结果为什么在R0返回呢?
ADD SP,#4  ;调用数据栈指针,准备返回
LDR PC,[SP],#4
END


2.BLX实现状态切换
AREA ...
CODE32
ARM1   ADR RO,thumb1+1  ;????
        BLX RO   
       ...
thumb1 ADD R1,R3,#1
       ....
       BX LR


thumb1是个标号,ADR指令里面他代表一个地址,+1后,为什么不是讲地址加一。。如
0X00003  +1  =0X0004  呢?
而是把语句标号thumb1所在的地址赋值给R0,末位R0【0】置1,要跳转到THUMB指令集
????

3.目标地址由寄存器Rm表示
此时BLX指令相当于执行操作PC=Rm[0]&OXFFFFFFE,T=Rm[0]&1.....>??????为什么是与1,e的二进制码不是1110吗?
应该是Rm[0]&0.。。。结果只能是1.。但是不能实现ARM--->THUMB转换了?为什么是与1呢。。




谢谢各位了!

回复评论 (3)

把ARM的汇编指令多看看
点赞  2009-3-2 08:39
只回答第一个。
第一个问题跟调用约定有关。ARM中约定函数前四个参数在R0-R3中传递,其余的在栈上传递。用寄存器传递参数的好处是效率高,不涉及外部存储,依赖性也小,有些情况下甚至没有栈用;规定只用4个是因为大多数函数参数不超过4个,寄存器是很宝贵的资源。在R0返回结果也是约定的,就像X86约定在EAX返回结果一样。所谓调用约定只是建议你这么用,因为绝大多数人都会遵守,约定好了大家都方便。如果你的代码不打算调用别人的代码,或者没有别人调用你的代码,你用10个寄存器传参数都没问题,完全放在栈里传递也没问题。
点赞  2009-3-2 09:02
引用: 引用楼主 RFbenson 的帖子:
1.汇编程序调用C程序
C_add.c

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

ARM_add.s

AREA ARM_add,CODE ,READONLY
EXPORT ARM_add
IMPORT g
ENTRY

STR LR ,[SP,#-4]!  ;保存返回地址
MOV R0,#1
MOV R1,#2
MOV R2,#3
MOV R3,#4
MOV R4,#5    ;设置参数,R4用数据栈传递  ????为什么只有R4,其他的寄存器呢
STR R4,[SP,#-4]!  ;只有R4…

BL g    ;??????如何传递的呢,R0,R1,R2...怎么没有显示的调用呢?结果为什么在R0返回呢?



这个R0~R3这四个寄存器是ARM汇编,C混合编程默认传递参数的。不用入栈,他们本身是寄存器。
如果程序多于四个参数,程序就要使用栈传递参数。

在程序中有这么个规定:最好不要让函数多于四个参数,我想就是这个原因,因为使用栈传递参数估计速度会慢点。

类似的说明我记得网上有。楼主找找吧。



点赞  2009-3-2 09:03
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复