一个简单的ARM7汇编程序示例详解

先上完整的示例 代码 :

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详解-------------------------------------------

     ARM7内核寄存器分布

一个简单的ARM7汇编程序示例详解_第1张图片

ARM7TDMI-S内核共37个寄存器。

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位分布

一个简单的ARM7汇编程序示例详解_第2张图片

-----------------------------------------------------------------------------------

详细解读ARM寄存器之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} _, #immed_8r MSR{cond} _, Rm where: cond is an optional condition code. is either CPSR or SPSR. specifies the field or fields to be moved. can be one or more of:

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

 

你可能感兴趣的:(ARM汇编)