ARM ASM

ARM ASM

ARM寄存器集

在这里插入图片描述
列出了ARM的16个程序员可见寄存器(r0~r15)以及它的状态寄存器。
ARM共有14个通用寄存器r0~r13。寄存器r13被保留用作栈指针,r14存放子程
序返回地址,r15为程序计数器。

由于r15能够被程序员访问,因此能够执行可以计算的分支(如高级语言case语
句中所用的操作类型)。ARM的16个寄存器需要4位地址,相对于32个寄存器
(5位地址)的RISC处理器来说,每条指令可以节约3位。这种方法使得ARM的
指令比一些RISC处理器丰富得多。

寄存器r13被保留用作栈指针。与特殊功能寄存器r14和r15不同,它们的附加功
能由ARM硬件实现,仅当程序员需要r13作为栈指针时它才会成为栈指针。

ARM的当前处理器状态寄存器CPSR包括Z(零)、N(负)、C(进位)和V(溢
出)等标志位,类似于其他处理器中的条件码或状态寄存器。CPSR的低8位包
含系统信息

ARM指令集

指令集分类方法:数据移动、算数运算、逻辑运算、移位、程序控制

ARM 寄存器-寄存器体系结构的指令集

更新ARM条件码

与绝大多数CISC体系结构不同,ARM不会在算数和逻辑运算后自动更新状态标志。ARM提供按需更新模式,仅仅在当前指令借记符带有后缀s时候才会自动更新条件码。
如,指令ADD r1,r2,r3进行加法操作,不更新状态标志,而指令ADDS r1,r2,r3则
会更新状态标志。

  • SUBS r1,r1,#1 ; r1减1并设置状态位
  • ADD r2,r2,#4 ; 计数器递增,不更新状态位
  • MUL r5,r3,r4 ; r3与r4相乘,不更新状态位
  • BEQ Error ; 如r1为0则跳转去处理问题

ARM汇编语言

Test_5
ADD r0,r1,r2 ; 计算TotalTime =Time +NewTime
SUBS r7,#1 ; 循环计数器递减
BEQ Test_5 ; 为0则跳转到Test_5处

例2
计算数字1~10的立方和,可以使用乘累加指令实现

	MOV	r0,#0		; r0 = 0
	MOV	r1,#10		; FOR i = 1 to 10(向下计数)
Next	MUL	r2,r1,r1	; 	计算平方
	MLA	r0,r2,r1,r0	; 	计算立方并累加
	SUBS	r1,r1,#1	; 	计数器递减(设置标志位)
	BNE	Next		; END FOR(计数值不为零时跳转)

汇编程序由两部分组成:计算机可执行指令和告诉汇编器运行环境有关信息的
汇编伪指令。汇编伪指令告诉汇编器代码在存储器中的位置,为变量分配存储
空间,以及设置程序运行时所需的初始数据。

ARM程序结构

下述代码描述了一个简单的程序结构,计算整数1~10立方和的程序,加阴影的
文字表示汇编伪指令而不是可执行的ARM代码:
在这里插入图片描述

汇编伪指令AREA定义代码段
段的名字为ARMTest,属性为CODE和READONLY
汇编伪指令ENTRY告诉汇编器在哪里找到要执行的第一条指令
伪指令END是强制的,告诉汇编器已经到达程序末尾

伪指令

伪指令是程序员可用的指令,但不是处理器ISA的一部分,伪指令是一种速记形式,程序员可用用它简单的表示一个动作,并使汇编器生成合适的代码。

CISC处理器能将地址以及16位或32位数据加载到寄存器中。由于ARM是规整的32位指令格式,不能直接实现这样的指令。
如,想把32位十六进制数0x1234567加载到寄存器r0中,不能写成MOV r0,#0x1234567(why?)。ARM汇编器提供了能够简化常量加载的方法。

伪指令ADR

伪指令ADR,把地址加载到目的寄存器中。该指令格式为ADR rdestination label,
label是程序中有效地址标号。尽管我们会在程序中看到ADR,但它并不是一个
真正的指令,因为没有指令能把32位常量加载到ARM寄存器中。ADR是一个可
由程序员使用的伪操作或虚拟指令,之后汇编器将生成完成同样功能的实际机
器代码。

伪指令是一种便捷的形式,汇编器将其转换为实际指令,将程序员从一些事务
性的工作解脱出来。一般来说,ADR能够利用ARM的ADD或SUB指令以及PC相对
寻址方式产生所需要的地址。

下面代码说明ADR的使用方法:
ADR r1,MyArray ; 使r1指向MyArray
LDR r3,[r1] ;
MyArray DCD 0x12345678 ;用指针读出一个元素

编译器会生成将已知值载入寄存器rd中的代码,如
LDR r0, = 0x12345678
把数据1234567816加载到寄存器r0中。汇编器会使用指令MOV或MVN,或使用一条LDR r0,[PC,#offset]指令去访问常数1234567816,该常数被存放在位于存储器中某处的立即数池或常数池。

ARM是如何处理伪指令的,考虑以下代码段(虚拟代码,仅用于说明伪指令用法): AREA ConstPool, CODE, READONLY
ENTRY
LDR r0,=0x12345678 ; 将32位常量加载到r0中
ADR r1,Table ; 将Table的地址加载到r1中
ADR r2,Tabel1 ; 将Table1的地址加载到r2中
LDR r3,=0xAAAAAAAA ; 将32位常量加载到r3中
LDR r4,P3 ; 这条语句的功能是什么?

Table	DCD	0xABCDDCBA		; 虚拟数据
Table1	DCD	0xFFFFFFFF		;
P3	DCD	0x22222222		;

地址 数据/指令 说明
0x00000000 LDR r0, [PC, #0x10] 加载 0x12345678
0x00000004 ADD r1, PC, #0x0C 计算 Table 地址
0x00000008 ADD r2, PC, #0x08 计算 Table1 地址
0x0000000C LDR r3, [PC, #0x0C] 加载 0xAAAAAAAA
0x00000010 LDR r4, [PC, #0x0C] 加载 P3 处的数据
0x00000014 0x12345678 文字池:LDR r0 的常量
0x00000018 0xAAAAAAAA 文字池:LDR r3 的常量
0x0000001C 0xABCDDCBA Table 数据
0x00000020 0xFFFFFFFF Table1 数据
0x00000024 0x22222222 P3 数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值