历史上的今天
返回首页

历史上的今天

今天是:2024年10月05日(星期六)

正在发生

2018年10月05日 | ARM单片机汇编指令使用二

2018-10-05 来源:eefocus

目录:

11、STMFD和LDMFD指令

1)STMFD SP! ,{R0-R7,LR}   2)LDMFD SP! ,{R0-R7,LR}

99、伪指令

1)PROC伪指令   2)EXPORT伪指令   3)IMPORT伪指令                    4)DCD与DCDU伪指令

5)ALIGN伪指令  6)AREA伪指令       7)SPACE和DCD伪指令的区别    8)ENTRY伪指令

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

说明:

ARM单片机汇编指令使用一

ARM单片机汇编指令使用二


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

11、STMFD和LDMFD指令

根据ATPCS规则,一般使用FD(FullDescending)类型的数据栈!所以经常使用的指令就有STMFD和LDMFD。这两个指令一般用于进行程序搬移等大规模操作前的cpu现场保护和操作结束后的现场恢复,属于非单一连续的压栈和出栈。

1)STMFD SP! ,{R0-R7,LR}

意义是:

SP = SP-9x4

ADDRESS =SP

for  i = 0 to 7

     memory[address] = Ri

     address =address+4

memory[address] = LR

由于ARM堆栈结构是从高向低压栈的,此时SP即是栈顶。

这里的sp = sp-4,是因为处理器是32位的ARM,所以每次压一次栈SP就会移动4个字节(32位)。

假设此时SP地址为: 0x40000460,减去0x24(9x4=36d)得0x4000043C,由前面解释伪代码可得下图(蓝色填充区为地址):

蓝色标注的SP为执行指令前的SP地址,红色标注的SP是执行指令后的SP地址,由此看出STMFD指令是向下压栈的。

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

2)LDMFD SP! ,{R0-R7,LR}

过程算是STMFD的逆过程

address = SP;

  for i = 0 to 7

     Ri = Memory[address ,4]

    address = address + 4;

 

  SP = address;

假设此时SP地址为: 0x4000043C,由前面解释伪代码可得下图(蓝色填充区为地址):

蓝色标注的SP为执行指令前的SP地址,红色标注的SP是执行指令后的SP地址。


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

99、伪指令

1)PROC伪指令

一般格式:<过程名>   PROC   [类型]

此指令为过程定义指令。过程即子程序,一个过程可以被其他程序调用(CALL指令)。

<过程名>   PROC  [类型]

                   …….

                   …….

    ENDP

注:PROC和ENDP必须成对出现。

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

2)EXPORT伪指令

语法格式:    
    EXTERN 标号 {[WEAK]}    
    EXTERN 伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,如果当前源文件实际并未引用该标号,该标号就不会被加入到当前源文件的符号表中。标号在程序中区分大小写,[WEAK] 选项表示当所有的源文件都没有定义这样一个标号时,编译器也不给出错误信息,在多数情况下将该标号置为 0 ,若该标号为 B 或 BL 指令引用,则将 B 或 BL指令置为 NOP 操作。
    使用示例:
    AREA Init , CODE , READONLY
    EXTERN Main ;通知编译器当前文件要引用标号Main,但Main 在其他源文件中定义……
    END

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

3)IMPORT伪指令

 语法格式:
    IMPORT 标号 {[WEAK]}
    IMPORT 伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,而且无论当前源文件是否引用该标号,该标号均会被加入到当前源文件的符号表中。类似于C语言中的EXTERN。
    标号在程序中区分大小写, [WEAK] 选项表示当所有的源文件都没有定义这样一个标号时,编译器也不给出错误信息,在多数情况下将该标号置为0 ,若该标号为B 或BL指令引用,则将B或BL指令置为 NOP 操作。    
    使用示例:
    AREA Init , CODE , READONLY
    IMPORT Main ;通知编译器当前文件要引用标号Main,但Main在其他源文件中定义
    ……
    END

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

4)DCD与DCDU伪指令

(1)DCD指令定义与作用

DCD指令是数据定义( Data Definition )伪指令,一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。DCD用于分配一片连续的字存储单元并用指定的数据初始化。

(2)DCD语法格式

标号 DCD 表达式

DCD伪指令用于分配一片连续的字存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为程序标号或数字表达式。 DCD 也可用“ & ”代替。

用 DCD 分配的字存储单元是字对齐的,而用DCDU分配的字存储单元并不严格字对齐。

(3)使用示例

DataTest DCD 4 , 5 , 6 ;分配一片连续的字存储单元并初始化。

举例1:

SwiFunction
        DCD     TASK_SW                    ;0
        DCD     ENTER_CRITICAL         ;1
        DCD     EXIT_CRITICAL             ;2
        DCD     ISRBegin                      ;3
        DCD     ChangeToSYSMode    ;4
        DCD     ChangeToUSRMode   ;5
        DCD     __OSStartHighRdy       ;6
        DCD     TaskIsARM                   ;7
        DCD     TaskIsTHUMB              ;8
        DCD     OSISRNeedSwap         ;9
        DCD     GetOSFunctionAddr    ;10
        DCD     GetUsrFunctionAddr    ;11

TASK_SW
        MRS     R3, SPSR    ;保存任务的CPSR

        MOV    R2, LR         ;保存任务的PC

举例2:

语句如下:
FiqStackSpace SPACE FIQ_Stack_Legth
FiqStack DCD FiqStackSpace + FIQ_Stack_Legth

最后一条语句,DCD的后面跟FiqStackSpace + FIQ_Stack_Legth,
DCD后面的FiqStackSpace,表示一串空字符,这好理解
但是再上FIQ_Stack_Legth,就不明白了,WHY?

FiqStackSpace是标号,相当与地址,实际上就是在FiqStackSpace SPACE FIQ_Stack_Legth 这个语句给分配的空间的首地址,FiqStackSpace+ FIQ_Stack_Legth 是这个地址空间的结束地址,将FiqStack指向这个地址,当做栈的顶部,该栈向下生长,长度FIQ_Stack_Legth.

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

5)ALIGN伪指令

作用:对指令或者数据的存放地址进行对齐

有些CPU架构要求固定的指令长度并且存放地址相对于2的幂指数圆整,否则程序无法正常运行,比如ARM。

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

6)AREA伪指令

指示汇编程序汇编新的代码节或数据节。程序是以程序段为单位组织代码的。段是相对独立的指令或代码序列,拥有特定的名称。段的种类有代码段、数据段和通用段,代码段的内容为执行代码,数据段存放代码运行时需要用到的数据,通用段不包含用户代码和数据,所有通用段共用一个空间。

AREA 伪指令用于定义一个代码段或数据段。 

    语法格式:
    AREA 段名 属性 1 ,属性 2 ,……
    其中,段名若以数字开头,则该段名需用 “ | ” 括起来,如 |1_test|
    属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。常用的属性如下:    
— CODE 属性:用于定义代码段,默认为 READONLY 
— DATA 属性:用于定义数据段,默认为 READWRITE 
— READONLY 属性:指定本段为只读,代码段默认为 READONLY
— READWRITE 属性:指定本段为可读可写,数据段的默认属性为 READWRITE 
— ALIGN 属性:使用方式为ALIGN表达式。在默认时, ELF (可执行连接文件)的代码段和数据段是按字对齐的,表达式的取值范围为 0 ~ 31 ,相应的对齐方式为表达式2次方。    
— COMMON 属性:该属性定义一个通用的段,不包含任何的用户代码和数据。各源文件中同名的COMMON段共享同一段存储单元

— NOINIT属性:  指定此数据段仅仅保留了内存单元,而没有将各初始值写入内存单元,或者将各个内存单元值初始化为0

   一个汇编语言程序至少要包含一个段,当程序太长时,也可以将程序分为多个代码段和数据段。
    使用示例: 
AREA Init , CODE , READONLY    
   该伪指令定义了一个代码段,段名为 Init ,属性为只读

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

7)SPACE和DCD伪指令的区别

SPACE和DCD的功能类似,SPACE申请一片内存空间,DCD申请一个字(32bit)的内存空间。

SPACE和DCD的区别在于,SPACE申请空间但不赋初值,DCD申请一个字的空间,并赋初值。

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

8)ENTRY伪指令
ENTRY 伪指令用于指定汇编程序的入口点。   
    语法格式:    
    ENTRY    
    在一个完整的汇编程序中至少要有一个ENTRY(当有多个ENTRY时,程序的真正入口点由链接器指定),但在一个源文件里最多只能有一个ENTRY(可以没有)。    
    使用示例:    
    AREA Init , CODE , READONLY    
    ENTRY ;指定应用程序的入口点    
    ……    

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


推荐阅读

史海拾趣

Decawave公司的发展小趣事

2020年,美国RF解决方案的领先供应商Qorvo宣布收购Decawave。这一收购对于Decawave来说是一个重要的里程碑。Qorvo看中了Decawave在UWB技术领域的创新能力和市场潜力,通过收购整合,Qorvo能够更好地将Decawave的技术应用于其移动、汽车、消费类和工业物联网市场的产品中。同时,Decawave也借助Qorvo的全球资源和市场渠道,进一步扩大了其市场份额和影响力。

AF International公司的发展小趣事

随着公司业务规模的不断扩大,AF International意识到建立完善的质量管理体系至关重要。公司引进了先进的质量管理理念和方法,建立了严格的质量控制流程,确保从原材料采购到产品生产的每一个环节都符合质量标准。同时,AF International还加强了对员工的培训和教育,提高员工的质量意识和操作技能。这些措施使得公司的产品质量得到了有效保障,赢得了客户的广泛赞誉。

Herotek Inc公司的发展小趣事

在全球倡导绿色低碳的背景下,Henkel也积极投身于绿色材料的研发和应用中。在电子行业中,Henkel推出了多款环保型粘合剂产品,这些产品不仅具有优异的性能表现,还符合国际环保标准和法规要求。通过推广绿色材料和技术解决方案,Henkel不仅为电子行业的可持续发展做出了贡献,也进一步巩固了其在该领域的领先地位。

以上五个故事展示了Henkel公司在电子行业中的发展历程和成就。凭借其创新的技术、全面的解决方案以及对可持续发展的承诺,Henkel将继续在电子行业中发挥重要作用。

Doodle Labs公司的发展小趣事

Doodle Labs非常重视企业文化的建设和发展。公司倡导开放、创新、协作、共赢的价值观,为员工提供良好的工作环境和发展机会。同时,Doodle Labs还积极参与公益事业和社会活动,为社会做出贡献。在未来,Doodle Labs将继续秉承这些价值观和精神,致力于成为全球领先的无线通信技术提供商和物联网解决方案提供商。

COMPUTAR公司的发展小趣事

进入90年代,电动变焦镜头逐渐成为市场的新宠。CBC株式会社紧跟时代潮流,于1992年成功推出电动6倍系列镜头。这款镜头采用电动变焦设计,操作简便、速度快捷,极大地提高了拍摄效率。电动6倍系列镜头的全球上市,不仅进一步扩大了CBC的市场影响力,也为公司的未来发展奠定了坚实的基础。

通过以上五个故事,我们可以看到COMPUTAR公司(前身为CBC株式会社)在电子行业中的发展历程。从创立之初的艰苦创业,到逐步拓展国际市场;从手动变焦镜头的研制成功,到非球面高速镜头和电动6倍系列镜头的诞生与上市,每一步都凝聚着COMPUTAR人的智慧和汗水。正是这些不懈的努力和持续的创新,使得COMPUTAR在电子行业中脱颖而出,成为一家备受尊敬的企业。

Avel Lindberg公司的发展小趣事

随着技术的不断进步和市场需求的扩大,CBC株式会社开始寻求更广阔的发展空间。1960年,CBC香港公司成立,这标志着CBC的镜头产品开始走向国际市场。香港作为当时亚洲的金融中心和贸易枢纽,为CBC提供了宝贵的国际资源和市场机遇。通过香港公司的努力,CBC的镜头产品逐渐在国际市场上获得认可。

问答坊 | AI 解惑

目前市场上测量心率的是什么方法啊?

最近想做个简单的测量心率的小玩意,先后尝试了网上的压电陶瓷片,电路搭不好,无从下手感觉,这里有没有这方面的感人啊,介绍下,谢谢…

查看全部问答>

数字幅频均衡功率放大器

本帖最后由 paulhyde 于 2014-9-15 09:23 编辑 本科组F题——数字幅频均衡功率放大器本科 一、任务 设计并制作一个数字幅频均衡功率放大器。该放大器包括前置放大、带阻网络、数字幅频均衡和低频功率放大电路,其组成框图如图1所示。 下载 (1 ...…

查看全部问答>

咨询,北京地区DSP视频编码硬件工程师月研发成本大概是多少

我指的是公司对下面员工的成本评估,包括员工的人力成本,办公费用等,盼答复谢谢…

查看全部问答>

se8a73up

是一USB芯片谁用过? 可以简单介绍下么? 英文资料看起来吃力…

查看全部问答>

AT91RM9200 启动问题

前提环境:AT91Rm9200 +S29Gl064A R6 SDRAM MT48LC16 问题描述:由内部rom启动后将boot.bin、u-boot.bin.gz烧入flash。能够正常烧录,没有问题! 由flash启动,u-boot 能够启动正常,停留在Uboot->处!但写数据到flash,会报timeout错误! 个人问 ...…

查看全部问答>

WinCE DDK 的问题

WinCE DDK 的问题 1) WinCE6.0 的DDK 怎么搞到? 2) HidD_GetHidGuid Windows DDK函数。 WinCE 下与之对应的DDK 的函数是什么 3) WinCE6.0 下获取USB信息是不是要DDK ?…

查看全部问答>

贴片三极管

印字是72p贴片三极管是什么型号…

查看全部问答>

易电源学习心得

最近老板让我做个电源板,前几天一直忙着选型号。之前老板给我挑了型号LMZ10503ext,后来一查是个军品,价格高不可攀。做这个电源板主要是学习之用,对温度范围没有太高的要求,所以确定了 LMZ10503TZ-ADJ LMZ12001TZ-ADJ LMZ12002TZ-ADJ。有个问题 ...…

查看全部问答>

但使用了统计任务后,无法切换到自己的任务中

但使用了统计任务后,无法切换到自己的任务中。 进入OSStatInit后就一直跳到空闲任务中,不能切换到自己的任务。求大神啊…

查看全部问答>

讨论开发linux到MTD设备时,如何确定NAND FLASH一些参数。

开发linux到MTD设备时,如何确定NAND FLASH一些参数。 struct nand_flash_dev {         char * name;//名字。这个容易理解         int manufacture_id;//制造商。芯片手册上有。     &nbs ...…

查看全部问答>