ARM汇编程序设计学习笔记(一)

ARM汇编程序设计学习笔记(一)

为了学习android系统,发现需要学习linux驱动,发现学习linux驱动,需要先知道处理器的各种架构,为了学习此种知识,发现网上有很多mini2440相关的知识,因此,将其作为蓝本,认真学习。直到linux驱动的学习完成。

这是linux驱动学习的第一部分,arm的汇编程序。

本文档的大部分资料翻译于《S3C2440A 32-BIT CMOS MICROCONTROLLER USER’S MANUAL》

一.编程模型

处理器工作状态

从程序员的角度来看,ARM920T(s3c2440的内核)有如下两种状态:

  1. ARM状态,执行32位,字对齐的指令
  2. THUMB状态,执行16位,半字对齐的THUMB指令。

注意:这两种状态的切换,不会影响处理器的模式和寄存器状态

1.1 切换状态

进入THUMB状态

将操作数寄存器的第0位,设为1,然后执行BX指令,就可以切换为THUMB状态。

例如:

BX Rm;如果Rm的第0位,是1,则跳转到Rm所在的地址,并且设置处理器在thumb模式下

如果在THUMB状态下,进入了异常,从异常中退出,依然是THUMB状态

进入ARM状态

可以通过下面的方法,进入arm状态:

  1. 将操作数寄存器的第0位,清零,然后执行BX指令
BX Rm;如果Rm的第0位,是0,则跳转到Rm所在的地址,并且设置处理器为arm模式下
  1. 处理器发生异常时,PC被放置在异常模式下的连接寄存器中,然后从异常向量地址开始执行

1.2 内存格式

ARM920T 将内存视为一个线性的字节序列。字节地址从0开始。0到3字节保存第一个字。4到7字节保存第二个字,依次类推。这些字支持小端和大端格式。

1.3 指令长度

指令长度为32位长(arm模式)和16位长(thumb模式)

1.4 数据类型

ARM920T 支持字节(8位)、半字(16位)、字(32位)数据类型。字必须4字节对齐。半字必须两字节对齐。

1.5 运行模式

ARM920T 支持7种运行模式:

  1. User(usr):最普通的arm执行状态
  2. FIQ(fiq):被用来进行数据传输,和信道处理
  3. IRQ(irq):通用的中断处理
  4. Supervisor(svc):为操作系统设计的保护模式
  5. Abort mode(abt):数据和指令预取发生问题时,进入
  6. System(sys):为操作系统设计的特权用户模式
  7. Undefined(und):当一个未定义的指令执行时,进入此模式

模式的改变可以通过软件控制,也可以通过外部的中断,或者异常。大多数的应用程序将运行在用户模式下。

特殊模式(非用户模式)仅仅在服务中断或者异常,或者访问受保护的资源时才会进入。

1.6 寄存器

ARM920T 总共有37个寄存器。其中,31个通用的32位寄存器和6个状态寄存器。这37个寄存器,对于程序来说,不能同时可见。

处理器状态和运行模式,决定了那些寄存器对于程序员来说可见。

1.7 arm状态下的寄存器集

在arm状态下,程序员只能看到16个通用寄存器和1个或者2个状态寄存器。在特殊模式(非用户模式),相应的寄存器组被切换。图2-3展示了在每种模式下那些寄存器可见。这些寄存器组使用一个阴影三角形标记:

在这里插入图片描述

arm状态下的寄存器组包含16个可直接访问的寄存器:R0-R15.除了R15寄存器以外,其他的寄存器都是通用寄存器。可以用来存储数据或者地址。

除此之外,还有第十七个寄存器用来存储状态信息。

寄存器描述
寄存器14该寄存器作为子程序的链接寄存器。当分支指令(Branch)和连接指令(BL)执行时,这个寄存器保存R15的值.其他时候,可以被作为通用寄存器来使用。对应的寄存器有:R14_svc,R14_irq,R14_fiq,R14_abt,R14_und,他们都在对应的模式下保存R15的值
寄存器15这个寄存器为程序计数器(PC)。在arm模式下,bits[1:0]是0,bits[31-2]保存PC。在thumb模式下,bit[0]为0,bits[31:1]保存PC
寄存器16这个寄存器是CPSR(当前程序状态寄存器)。它保存代码的各种flag和一些模式位

FIQ模式有7个寄存器,被映射为R8-R14(R8_fiq-R14_fiq).在arm模式下有许多FIQ处理程序不需要保存的寄存器。

而USer,IRQ,SuperVisor,Abort和Undefined模式,都有R13和R14,并且允许他们有自己的堆栈指针和链接寄存器

ARM和THUMB之间的寄存器关系

如下:

  1. THUMB模式下R0-R7 ,ARM模式下R0-R7 完全相同
  2. THUMB模式下CPSR和SPSRs,ARM模式下CPSR和SPSRs是完全相同的
  3. THUMB模式下SP映射为ARM的R13
  4. THUMB模式下LR映射为ARM下的R14
  5. THUMB模式下PC映射为ARM的R15

在这里插入图片描述

在thumb模式下访问高寄存器组(Hi-registers)

在THUMB模式下,寄存器组R8-R15(被称为Hi-registers)不是标准寄存器组中的一部分。因此,汇编程序对他的访问是受限制的。但是他们可以用来作为临时的存放地。

可以使用mov指令,将R0-R7里面的值放置到高寄存器中。也可以将高寄存器中的值放到低寄存器中(R0-R7)

也可以使用CMP指令,将高寄存器和低寄存器进行比较

也可以使用ADD指令,将高寄存器中的值加到低寄存器中

1.8 程序状态寄存器

ARM920T 包含一个当前程序状态寄存器(CPSR),以及5个已经保存了的程序状态寄存器(SPSR)。这些寄存器的功能有:

  1. 保存执行单元(ALU)最近的信息
  2. 打开或者关闭中断
  3. 处理器运行模式
313029282726252423222120191817161514131211109876543210
NZCV--------------------IFTM4M3M2M1M0

条件码标识

N,Z,C,V是条件码的标志位。这些将会被算术和逻辑运算改变,然后再根据这些位来决定指令是否执行。

在arm状态下,所有的指令可以被条件的执行。

在thumb状态下,只有分支指令才可以按照条件执行

控制位

最低下的8位被称为控制位。当一个异常发生时,他们会被改变。如果处理器在特权模式下,那么他们也可以被软件手动改变。

描述
T当为1时,处理器运行在THUMB模式下,否则运行在ARM模式下。他将影响TBIT外部信号
中断禁止位I和F是中断禁止位。为1,则相应的禁止IRQ和FIQ
模式位M4,M3,M2,M1,M0是模式位,如下表,只有下表出现的模式才是正确的模式,一旦程序设置了错误的模式,则会产生复位异常
保留位剩下的位为保留位。
M[4:0]模式thumb模式下的寄存器arm模式下的寄存器
10000UserR7…R0,LR,SP,PC,CPSRR14…R0,PC,CPSR
10001FIQR7…R0,LR_fiq,SP_fiq,PC,CPSR,SPSR_fiqR7…R0,R14_fiq…R8_fiq,PC,CPSR,SPSR_fiq
10010IRQR7…R0,LR_irq,SP_irq,PC,CPSR,SPSR_irqR12…R0,R14_irq,R13_irq,PC,CPSR,SPSR_iraq
10011SupervisorR7…R0,LR_svc,SP_svc,PC,CPSR,SPSR_svcR12…R0,R14_svc,R13_svc,PC,CPSR,SPSR_svc
10111AbortR7…R0,LR_abt,SP_abt,PC,CPSR,SPSR_abtR12…R0,R14_abt,R13_abt,PC,CPSR,SPSR_abt
11011UndefinedR7…R0,LR_und,SP_und,PC,CPSR,SPSR_undP12…R0,R14_und,R13_und,PC,CPSR
11111SystemR7…R0,LR,SP,PC,CPSRR14…R0,PC,CPSR

1.9 异常

例如响应外设电路的中断,此时反生异常。在异常处理前,当前处理器的状态必须保存下来,目的是,当异常处理完成之后,可以继续执行

在同一时间,可能同时出现多个异常,此时他们以固定的顺序进行处理,详见下面的异常优先级。

进入异常时的操作

当处理异常时,ARM920T会做如下的操作:

  1. 在链接寄存器中保存下一个指令的地址。如果异常从arm状态进入,则下一个指令的地址被复制到链接寄存器中(即PC+4,或者PC+8,具体依赖于不同的异常,后面有详细说明)如果异常从THUMB状态进入,链接寄存器则保存当前PC的偏移量。这就意味着,异常处理程序,不用管,到底是从哪个状态进入的异常。
  2. 赋值CPSR到对应的SPSR
  3. 修改CPSR对应的模式位
  4. 修改PC为对应的异常向量地址

还可以设置异常禁止位,防止异常嵌套的发生

如果处理器在THUMB状态下,此时发生了异常,当PC指向异常向量的地址时,自动切为ARM状态

离开异常时的操作

异常处理程序完成后:

  1. 将链接寄存器的值,复制到PC中
  2. 复制SPSR到CPSR
  3. 如果允许中断,则清除中断禁止位,

异常入口/出口摘要

下表列出了异常发生时,保存在链接寄存器中的PC的值,以及退出异常处理程序的推荐的指令

返回的指令arm R14_xthumb R14_x
BL;MOV PC,R14PC+4PC+2
SWI;MOVS PC,R14_svcPC+4PC+2
UDEF;MOVS PC,R14_undPC+4PC+2
FIQ;SUBS PC,R14_fiq,#4PC+4PC+4
IRQ;SUBS PC,R14_irq,#4PC+4PC+4
PABT;SUBS PC,R14_abt,#4PC+4PC+4
DABT;SUBS PC,R14_abt,#8PC+8PC+8
RESET;NA--

FIQ

FIQ(快速中断异常)被设计来处理数据传输和信道处理。在arm模式下,保证有最小,且足够的寄存器可用,以达到最优的上下文切换

外部的nFIQ输入为低时,产生FIQ异常。根据ISYNC输入信号的状态,nFIQ的输入可以被处理为同步或异步。当ISYNC为低时,nFIQ和nIRQ被当做异步。同步的周期延迟发生在中断影响处理器流之前。

无论异常是从ARM状态还是thumb状态进入的,FIQ异常可以通过下面的指令退出异常处理流程:

SUBS PC,R14_fiq,#4

FIQ可以通过CPSR的F位来禁止(用户模式下无法操作)。如果F位为0,ARM920T在每条指令结束时检查FIQ同步器输出的低电平。

IRQ

IRQ就是常见的中断,它由nIRQ输入触发。IRQ的优先级比FIQ的优先级低并且当FIQ进入时,IRQ将被禁止。通过设置CPSR寄存器的I位,可以在任何时候在特殊模式下(非用户模式)禁止这个异常

可以执行下面的代码,返回异常:

SUBS PC,R14_irq,#4

Abort

当前内存访问无法完成时,产生一个Abort异常。它也可以由外部的ABORT输入产生。ARM920T在内存访问周期中,检查abort异常

两种abort异常:

  1. 预取址Abort:在指令预取址的时候发生
  2. 数据Abort:数据访问时发生

如果预取址Abort发生,则取到的指令被标记为非法指令,并且直到指令到达管道的头部才发生异常。

如果指令没有被执行,abort也不会产生,比如分支指令

如果数据abort发生,接下来会发生什么,则依赖于指令的类型:

  1. 但数据传输指令(LDR,STR)写会被修改的寄存器。abort异常处理程序必须清楚这一点
  2. 交换指令(swap)中止,就好像它没有被执行一样
  3. 块数据传输指令继续完成(LDM,STM)。如果回写位被置位,则基址寄存器被更新。如果指令要覆盖基址寄存器,则覆盖会被中止,以保证不会覆盖。一旦发生abort异常,所有的寄存器覆盖都会被中止。因此R15就会被保留

abort机制可以实现按需分页的虚拟内存系统。在这个系统中,处理器可以产生任意的地址。当数据地址无效时,内存管理单元(MMU)产生一个abort异常。然后abort异常处理程序找出abort的原因,让请求的数据可用,然后重新执行产生abort异常的指令。

应用程序不需要知道他可用的内存量,他的状态也不会受abort异常的任何影响

退出abort异常的指令为:

SUBS PC,R14_abt,#4;for a prefetch abort
SUBS PC,R14_abt,#8;for a data abort

然后恢复PC和CPSR,并且再次执行产生abort异常的指令

软件中断

软件中断(SWI)被用来进入Supervisor模式。软件中断通过下面的指令返回:

MOV PC,R14_svc

他们恢复PC和CPSR,然后继续执行SWI后面的指令

未定义指令

当arm920T无法处理一个指令时,产生一个未定义指令异常。这种机制可以被用来扩展THUMB和ARM指令的软件仿真。

可以执行下面的指令,退出异常:

MOVS PC,R14_und

恢复CPSR,然后执行产生未定义指令异常的下一条指令

异常向量表

下表展示了异常向量地址:

地址异常进入的模式
0x00000000RestSupervisor
0x00000004Undefined instructionUndefined
0x00000008Software InterruptSupervisor
0x0000000CAbort(prefetch)Abort
0x00000010Abort(data)Abort
0x00000014ReservedReserved
0x00000018IRQIRQ
0x0000001CFIQFIQ

异常优先级

当同时产生异常时,系统以固定的顺序处理。

高优先级:

  1. Rest
  2. Data abort
  3. FIQ
  4. IRQ
  5. Prefetch abort

低优先级:

  • Undefined instruction,Software Interrupt

注意:并不是所有的异常都能同时发生
未定义指令和软件中断异常他们是互斥的

如果数据abort异常和FIQ异常同时发生,并且FIQ异常被允许,ARM920T进入数据abort异常处理程序,然后立刻去处理FIQ的异常。FIQ异常退出之后,继续在abort异常处理程序中执行。

数据abort的优先级高于FIQ是有道理的,他能够保证第一时间捕获到传输错误。进入这个异常的时间,应该加上FIQ的延迟。

中断延迟

如果FIQ打开,则最长的延时包括:传递给同步器(Tsyncmax)的最长请求时间,加上,最长的指令时间(Tldm),加上,数据abort进入的时间(Texc),加上FIQ进入的时间(Tfiq)。然后才是ARM920T在0x1c处执行。

Tsyncmax三个处理器周期,Tldm20个处理器周期,Texc3个处理器周期,Tfiq2个处理器周期。总共需要28个处理器周期。在一个连续的20Mhz的处理器上大约消耗1.4微秒。

最大的IRQ延迟计算方式跟上面类似。但是必须考虑到FIQ有更高的优先级,可以延迟任意时间进入IRQ异常处理程序。

FIQ和IRQ的最小时间则由Tsyncmin加上Tfiq组成,为4个处理器周期。

复位异常

当nREST输入为低时,ARM920T放弃执行指令,然后继续从递增的字地址中取指令。

当nRest再次变高,ARM920T:

  1. 将当前的PC和CPSR,写入到R14_svc和SPSR_svc。
  2. 将M[4:0]改为1011(supervisor模式),CPSR的I,F位置位,清楚CPSR的T位
  3. 将PC为0x00
  4. 在arm模式下,继续执行
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值