56章 汇编语言程序设计final.docx

上传人:b****6 文档编号:2921325 上传时间:2022-11-16 格式:DOCX 页数:34 大小:37.02KB
下载 相关 举报
56章 汇编语言程序设计final.docx_第1页
第1页 / 共34页
56章 汇编语言程序设计final.docx_第2页
第2页 / 共34页
56章 汇编语言程序设计final.docx_第3页
第3页 / 共34页
56章 汇编语言程序设计final.docx_第4页
第4页 / 共34页
56章 汇编语言程序设计final.docx_第5页
第5页 / 共34页
点击查看更多>>
下载资源
资源描述

56章 汇编语言程序设计final.docx

《56章 汇编语言程序设计final.docx》由会员分享,可在线阅读,更多相关《56章 汇编语言程序设计final.docx(34页珍藏版)》请在冰豆网上搜索。

56章 汇编语言程序设计final.docx

56章汇编语言程序设计final

第5章ARM汇编语言程序设计

5.1ARM汇编语言伪指令

伪指令并不是真正的arm指令或者thumb指令,编译时伪指令会被处理成对应的arm或thumb指令序列。

不同的编译器提供的伪指令不同,这里主要介绍ARM编译器常用的伪指令。

5.1.1符号定义伪指令

1全局变量声明

GBLA声明一个全局算术变量,并将其初始化为0。

GBLL声明一个全局逻辑变量,并将其初始化为{FALSE}。

GBLS声明一个全局字符串变量,并将其初始化为NULL。

语法格式:

GBLAvariable

GBLLvariable

GBLSvariable

例:

GBLAnum1

GBLLlogic_x

GBLSstring_y

2局部变量声明

LCLA声明一个局部算术变量,并将其初始化为0。

LCLL声明一个局部逻辑变量,并将其初始化为{FALSE}。

LCLS声明一个局部字符串变量,并将其初始化为NULL。

语法格式:

LCLAvariable

LCLLvariable

LCLSvariable

例:

LCLAnum1

LCLLlogic_x

LCLSstring_y

3变量赋值

SETA给一个算术变量赋值。

SETL给一个逻辑变量赋值。

SETS给一个字符串变量赋值。

语法格式:

variableSETAexpr

variableSETLexpr

variableSETSexpr

例:

num1SETA0xff

logic_xSETL{TRUE}

string_ySETS“stringtest”

4RLIST

为通用寄存器列表定义名称,定义的名称可以在LDM/STM指令中使用。

列表中的寄存器以逗号分隔,连续编号的寄存器可以用“-”包括,例如:

r7-r9表示寄存器r7、r8、r9。

语法格式:

nameRLIST{listofregisters}

例:

reg_listRLIST{r0-r4,r6,r7-r9}

STMFDsp!

reg_list;将r0-r4,r6,r7-r9的内容压入满降序栈中保存

5RN

为寄存器定义名称。

语法格式:

nameRNexpr

例:

spRNr13

6CN、CP

CN为协处理器的寄存器定义名称。

CP为协处理器定义名称。

语法格式:

nameCNexpr

nameCPexpr

例:

powerCN6

dmuCP6

7DN、SN、FN

DN为一个双精度的VFP寄存器定义名称。

SN为一个单精度的VFP寄存器定义名称。

FN为一个FPA浮点寄存器定义名称。

语法格式:

nameDNexpr

nameSNexpr

nameFNexpr

例:

heightDN6

widthSN16

lowerFN6

8EQU

为数字常量、标号或寄存器定义一个字符名称。

语法格式:

nameEQUexpr{,type}

当expr表示绝对地址时,可以使用type选项,type可以为:

CODE16(表示Thumb指令地址)、CODE32(表示ARM指令地址)或DATA(表示数据区地址)。

例如:

addr_aEQU0x20,CODE32;将绝对地址0x20赋值给addr_a,并标记为32位地址。

5.1.2空间分配伪指令

9SPACE

SPACE伪指令常常用来分配一块内存区域供程序使用,并且将这个内存区域初始化为0。

该伪指令可以用“%”代替。

语法格式:

{label}SPACEexpr;其中label为可选项

例:

dataroomSPACE256;以dataroom为起始地址,分配256个字节的内存单元,并初始化为0

10DCB

DCB用于定义并初始化一个或多个字节的内存区域。

该伪指令可以用“=”代替。

语法格式:

{label}DCBexpr{,expr,…}

例:

data1DCB1,3,5

stringDCB“hello!

”,0;构造一个以NULL结尾的字符串,字符串的起始地址为string

注意,当DCB后面紧跟一个指令时,为了使指令保持字对齐,需要用到ALIGN伪指令,ALIGN伪指令将在下面讲到。

11DCD、DCDU

DCD和DCDU用于定义并初始化一个或多个字的内存区域,其中DCD可以用“&”代替。

DCD和DCDU的区别在于DCD可以保证分配的内存单元是严格的字对齐的,而DCDU不能保证。

语法格式:

{label}DCDexpr{,expr,…}

例:

data1DCD0,2,4,6

data2DCDU1,3,5

12DCDO

DCDO用于定义并初始化一个或多个字的内存区域,且保证分配的内存单元是字对齐的。

语法格式:

{label1}DCDOlabel2

DCDO与DCD的区别在于DCDO将内存单元label1初始化为DCDO后面的标号label2相对于静态基址寄存器R9(sb)的偏移量。

例:

IMPORTexternlabel

data1DCDOexternlabel;将地址为data1的字单元初始化为标号externlabel相对于R9的偏移量

13DCFD、DCFDU、DCFS、DCFSU

DCFD用于为双精度的浮点数分配字对齐的内存单元,每个双精度浮点数占据两个字单元。

语法格式:

{label}DCFDfpliteral{,fpliteral,…}

DCFDU与DCFD的不同之处在于DCFDU分配的内存单元并不是严格字对齐的。

DCFS用于为单精度的浮点数分配字对齐的内存单元,每个单精度浮点数占据1个字单元。

DCFSU与DCFS的不同之处在于DCFSU分配的内存单元并不是严格字对齐的。

例:

data1DCFD2.1E204,-3E-100

data2DCFDU236,-.5,3E25

data3DCFS2.1E2,-3E-10

14DCI

DCI用于分配并初始化一段内存单元,且认为内存单元中的数值为指令数据。

当DCI位于ARM代码中的时候,分配的内存是严格字对齐的;当DCI位于Thumb代码中的时候,分配的内存是半字对齐的。

语法格式:

{label}DCIexpr{,expr,…}

15DCQ、DCQU以及DCW、DCWU

DCQ和DCQU用于分配双字(8个字节)的内存单元,其中DCQ是严格字对齐的,DCQU不能保证严格字对齐。

DCW和DCWU用于分配半字(2个字节)的内存单元,其中DCW是严格字对齐的,DCWU不能保证严格字对齐。

语法格式:

{label}DCQexpr{,expr,…}

16LTORG

LTORG用于声明一个数据缓冲池(literalpool)的开始。

通常放在无条件跳转指令之后,或者子程序返回指令之后,以免处理器错误的将数据缓冲池中的数据作为指令来执行。

例:

func1

:

;代码

MOVPC,lr

LTORG

dataSPACE256;从data标号开始预留256个字节的内存单元

END

17MAP、FIELD

MAP和FIELD用于描述结构化的内存表。

其中MAP用于定义结构化内存表的首地址,MAP也可以用“^”来表示;FIELD用于定义结构化内存表中的数据域,FIELD可以用“#”来表示。

语法格式:

MAPexpr{,base-register};内存表的起始地址为expr+base-register,其中base-register为可选项,若没有此项,则内存表的起始地址为expr。

例:

MAP4000;内存表的起始地址为4000

IntegerFIELD4;从4000开始为Integer分配4个字节

StringFIELD64;从4004开始为String分配64个字节

DoubleaFIEDL8;从4068开始为Doublea分配8个字节

5.1.3汇编控制伪指令

18IF、ELSE和ENDIF

IF、ELSE和ENDIF用于控制汇编器是否将一段汇编指令的源代码包含在汇编语言程序内。

例:

IFFLAG=1

:

;如果条件满足,则包含此段代码

ELSE

:

;如果条件不满足,则包含此段代码

ENDIF

19WHILE、WEND

WHILE和WEND用来控制编译器根据条件重复汇编一段源代码。

例:

WHILEFLAG=1

:

;如果条件满足,则重复汇编此段代码

WEND

20MACRO、MEND、MEXIT

MACRO和MEND用来定义一段宏体。

所谓宏实际上是一段汇编语言指令序列,将多条指令定义成一条宏语句,编译时宏语句被展开。

例:

MACRO

$labelsubmac$sum,$num1,$num2

$labelCMP$num1,$num2

$label.1SUBGE$sum,$num1,$num2

$label.2SUB$sum,$num2,$num1

MEND

在这个例子中定义了一个名为“submac”的宏,其中$label、$label.1、$label.2为宏中语句的标号,$label并不是必需的,只有当宏中的其他语句需要标号时,$label才是必需的。

其他语句的标号可以根据需要设置成其他的名字,如$label.1、$label.2可以定义成$label.sub、$label.ressub等。

$sum、$num1、$num2是宏的参数,宏中所有的变量都是以“$”开头的。

若在程序中引用宏submac:

submacr0,r1,r2

则编译后展开为下面的语句:

CMPr1,r2

SUBGEr0,r1,r2

SUBr0,r2,r1

使用宏时应注意,宏操作中不遵循APCS原则,寄存器也不会受到保护。

MEXIT为从宏中跳出的伪指令。

5.1.4格式控制伪指令

21ALIGN

通过填充0将当前的位置以某种形式对齐。

语法格式:

ALIGN{expr{,offset}}

expr通常为2的整数次幂,表示对齐的方式。

例如,当expr为4时,表示其后的指令对齐到下一个字的边界处;offset表示在上述对齐方式下的偏移量。

若ALIGN后不带任何参数,则表示把当前位置对齐到下一个字的起始位置。

例如:

ALIGN4,1

表示其后的指令以字(4个字节)为起始位置,且偏移量为1。

若下一个字地址为0xC0004,则下面指令的起始地址为0xC0005。

22CODE16、CODE32

CODE16表示其后的指令为16位的THUMB指令。

CODE32表示其后的指令为32位的ARM指令。

语法格式:

CODE16

CODE32

23AREA

定义一个代码段或数据段及其属性。

语法格式:

AREAsectionname{,attr}{,attr}…

sectionname为代码段或数据段的名称。

若该名称以数字开头,则必须用“|”括起来,如“|2_name|”。

还有一些代码段有约定的名称,如|.text|表示C语言编译器产生的代码段或者是C语言库相关的代码段。

attr表示代码段的属性,各属性间用逗号分隔

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 日语学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1