先上完整的示例 代码 :
1、calc.S
AREA CALC, CODE, READONLY
EXPORT asm_add
;定义了一个叫 asm_add 的子程序,我们在C语言里会传递两个参数。参数占用了R0, R1寄存器。本程序里为3 和2
asm_add PROC
ADD r3, r0, #0x01 ;r3 = r0 + 1
MOV R2, #0x7 ;r2 = 0x7
RSB R3, R2, R1 ;r3 = r1 - r2 ,也就是 2 - 7 = -5
MOV R0, R3 ;r0 = r3
MOV PC, LR ;LR也就是R14,保存子程序返回地址。意思程序将跳转到程序返回地址指向
;BX lr ;执行返回的另一种方法。这里注释了
ENDP ;子程序结束
END ;程序结束
2、main.c
#include
extern int asm_add(int, int);
int main(int argc, char* argv[]){
int a = 3;
int b = 2;
int result = asm_add(a, b);
printf("hello, arm7 ! result=%d", result);
return 0;
}
程序打印结果:
hello, arm7 ! result=-5
接下来,详解各个知识点。
---------------------------------------------------------------------------
IMPORT ,定义表示这是一个外部变量的标号,不是在本程序定义的
EXPORT ,表示本程序里面用到的变量提供给其他模块调用的。
以上两个在汇编和C语言混合编程的时候用到
ENDP 表示PROC所定义的过程结束. (end procedure)
ENDS 表示SEGMENT定义的段结束. (end segment)
END 程序结束.
B、BL、BX、BLX 和 BXJ
跳转、带链接跳转、跳转并切换指令集、带链接跳转并切换指令集、跳转并转换到 Jazelle 状态。
状态寄存器传送至通用寄存器类指令
功能:将状态寄存器的内容传送至通用寄存器。
例: MRS R0,CRSR ;将CPSR中的内容传送至R0
相反的: MSR CPSR_c,R0 ;将R0中的内容传送至CPSR
proc是定义子程序的伪指令,它和endp 分别表示子程序定义的开始和结束两者必须成对出现。
NEAR属性(段内近调用): 调用程序和子程序在同一代码段中,只能被相同代码段的其他程序调用;
FAR属性(段间远调用): 调用程序和子程序不在同一代码段中,可以被相同或不同代码段的程序调用.
ret指令的内部操作是:栈顶字单元出栈,其值赋给IP寄存器。即实现了一个程序的转移,将栈顶字单元保存的偏移地址作为下一条指令的偏移地址。(ARM7 似乎没有这个)
AREA 命令指示汇编程序汇编一个新的代码段或数据段。段是独立的、指定的、不可见的代码或数据块,它
们由链接程序处理。
更多详细说明:https://blog.csdn.net/canjiangsu/article/details/6161971?utm_source=blogxgwz0
-------------------------------寄存器Rn详解-------------------------------------------
R0—R7,通用寄存器,共8个。
R8—R12,除快中断有自己寄存器(Rx_fiq),其他模式共用,共10个。
R13,栈指针寄存器(SP)。用户、系统共用外,其他模式有独立寄存器,共6个。在 ARM 指令集当中,没有以特殊方式使用 R13 的指令或其它功能,只是习惯上都这样使用。但是在 Thumb 指令集中存在使用 R13 的指令。
R14,连接寄存器(BL)。当程序跳转、异常模式时,用于保存当前PC值。同上,共6个。在结构上有两个特殊功能:
1,在每种模式下,模式自身的 R14 版本用于保存子程序返回地址;
2,当发生异常时,将 R14 对应的异常模式版本设置为异常返回地址(有些异常有一个小的固定偏移量)。
R15,程序计数寄存器(PC),所有模式共用,1个。它指向正在取指的地址。可以认为它是一个通用寄存器,但是对于它的使用有许多与指令相关的限制或特殊情况。如果 R15 使用的方式超出了这些限制,那么结果将是不可预测的
CPSR,程序状态寄存器,同上,1个。
SPSR,程序状态保存寄存器,用户、系统模式没有。其他模式各自独立。进入异常模式时,用于保存用户、系统模式的CPSR。共5个。 寄存器 CPSR 为程序状态寄存器,在异常模式中,另外一个寄存器“程序状态保存寄存器( SPSR)”可以被访问。每种异常都有自己的 SPSR,在因为异常事件而进入异常时它保存 CPSR 的当前值,异常退出时可通过它恢复 CPSR。
以上为ARM7内核中的37个寄存器。
CPSR位分布
-----------------------------------------------------------------------------------
一、CPSR概述
ARM处理器共有37个寄存器。这37个寄存器按其在用户编程中的功能划分,可分为2类寄存器,即31个通用寄存器和6个状态寄存器。这6个状态寄存器在ARM公司文件中其名称分别为:CPSR、SPSR_svc、SPSR_abt、SPSR_und、SPSR_irq和SPSR_fig。这12的作用分别如图1所示:
所有处理器模式下都可访问当前程序状态寄存器CPSR。CPSR中包含条件码标志、中断禁止位、当前处理器模式以及其他状态和控制信息。在每种异常模式下都有一个对用的程序状态寄存器SPSR。当异常出现时,SPSR用于保存CPSR的状态,以便异常返回后恢复异常发生时的工作状态。
(1)条件码标志
N、Z、C、V,最高4位称为条件码标志。ARM的大多数指令可以条件执行的,即通过检测这些条件码标志来决定程序指令如何执行。
各个条件码的含义如下:
N:在结果是有符号的二进制补码情况下,如果结果为负数,则N=1;如果结果为非负数,则N=0。
Z:如果结果为0,则Z=1;如果结果为非零,则Z=0。
C:其设置分一下几种情况:
对于加法指令(包含比较指令CMN),如果产生进位,则C=1;否则C=0。
对于减法指令(包括比较指令CMP),如果产生借位,则C=0;否则C=1。
对于有移位操作的非法指令,C为移位操作中最后移出位的值。
对于其他指令,C通常不变。
V:对于加减法指令,在操作数和结果是有符号的整数时,如果发生溢出,则V=1;如果无溢出发生,则V=0;对于其他指令,V通常不发生变化。
(2)控制位的作用在图1中可以看出,在这里就不阐述了。
二:CPSR与CPSR_c的区别
CPSR有4个8位区域:标志域(F)、状态域(S)、扩展域(X)、控制域(C)
MSR - Load specified fields of the CPSR or SPSR with an immediate constant, or from the contents of a general-purpose register.
Syntax:
MSR{cond}
c control field mask byte (PSR[7:0]) x extension field mask byte (PSR[15:8]) s status field mask byte (PSR[23:16) f flags field mask byte (PSR[31:24]). immed_8r is an expression evaluating to a numeric constant. The constant must correspond to an 8-bit pattern rotated by an even number of bits within a 32-bit word. Rm is the source register.
C 控制域屏蔽字节(psr[7:0])
X 扩展域屏蔽字节(psr[15:8])
S 状态域屏蔽字节(psr[23:16])
F 标志域屏蔽字节(psr[31:24])
常用于MRS或MSR指令,用于psr中的值转移到寄存器或把寄存器的内容加载到psr中.
如:
MSR CPSR_c,#0xd3
此部分,转自:https://blog.csdn.net/david_luyang/article/details/6276533
-------------------------------思考题目-------------------------------------------
请问 ADD R0, PC, 0x04 中 R0的值是多少?
https://wenku.baidu.com/view/3346747502020740be1e9bdd.html