<?xml version="1.0" encoding="gbk"?> <rss version="2.0"><channel> <title>定阅帖子更新</title> <link>http://www.broadkey.com.cn/XML.ASP</link><description>TEAM Board - 科伟奇电子</description> <copyright>TEAM 2.0.5 Release</copyright><generator>TEAM Board by TEAM5.Cn Studio</generator> <ttl>30</ttl><item><link>http://www.broadkey.com.cn/Thread.asp?tid=335 </link><title>ARM汇编程序中常见的伪指令分析</title><author>peter00</author><pubDate>2009/12/8 12:02:43</pubDate><description><![CDATA[<div class="resizeimg"><span style="line-height: 20px; font-family: Arial; color: rgb(51,51,51); -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px" class="Apple-style-span">
<p style="line-height: normal">ARM汇编程序分析过程中，比较难理解的是他的伪操作、宏指令和伪指令。在读vivi时遇到很多不懂的，所以在此对引导程序中出现伪操作、宏指令和伪指令进行总结，&nbsp;<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 一、GET option.s<br style="line-height: normal" />
// GET和INCLUDE功能相同<br style="line-height: normal" />
功能：引进一个被编译过的文件。<br style="line-height: normal" />
格式：GET&nbsp;&nbsp;&nbsp;&nbsp; filename<br style="line-height: normal" />
其中：fiename&nbsp;&nbsp;&nbsp;&nbsp; 汇编时引入的文件名，可以有路径名。<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; GET符号在汇编时对宏定义，EQU符号以及存储映射时是很有用的，在引入文件汇编完以后，汇编将从GET符号后开始。在被引入的文件中可能有GET符号再引入其他的文件。GET符号不能用来引入目标文件。<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 二、INTPND EQU 0x01e00004<br style="line-height: normal" />
//EQU可以用&ldquo;*&rdquo;代替，在阅读源程序时注意。<br style="line-height: normal" />
功能：对一个数字常量赋予一个符号名。<br style="line-height: normal" />
格式：name&nbsp;&nbsp;&nbsp;&nbsp; EQU&nbsp;&nbsp;&nbsp; expression<br style="line-height: normal" />
其中：name&nbsp;&nbsp;&nbsp; 符号名。Expression&nbsp;&nbsp;&nbsp;&nbsp; 寄存器相关或者程序相关的固定值。<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 使用EQU定义常量，与C语言中用#define定义一个常量相同。<br style="line-height: normal" />
例：num&nbsp;&nbsp;&nbsp; EQU&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp; ； 数字2赋予符号num<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 三、GBLL&nbsp;&nbsp;&nbsp;&nbsp; THUMBCODE<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ {CONFIG} = 16<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; THUMBCODE SETL {TRUE}<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CODE32<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; THUMBCODE SETL {FALSE}<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ]<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ THUMBCODE<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CODE32&nbsp;&nbsp;&nbsp; ;for start-up code for Thumb mode<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ]<br style="line-height: normal" />
//其中[=IF ，|=ELSE ，]= ENDIF， CODE32 表明一下操作都在ARM状态。这些都是伪操作这段理解为设定THUMCODE的值，然后确定，用户的程序是在ARM状态还是THUM状态。<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 四、MACRO<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $HandlerLabel HANDLER $HandleLabel<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $HandlerLabel<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub sp,sp,#4 ;decrement sp(to store jump address)<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmfd sp!,{r0} ;PUSH the work register to stack<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ldr r0,=$HandleLabel;load the address of HandleXXX to r0<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MEND<br style="line-height: normal" />
//MACRO&hellip;&hellip;MEND<br style="line-height: normal" />
功能：标志一下宏的定义。<br style="line-height: normal" />
格式：MACRO<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Macro_prototype<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MEND<br style="line-height: normal" />
宏表达式的格式如下：<br style="line-height: normal" />
{$label}&nbsp;&nbsp;&nbsp; macroname&nbsp;&nbsp;&nbsp;&nbsp; {$ parameter{,parameter2}&hellip;}<br style="line-height: normal" />
其中：<br style="line-height: normal" />
$ label&nbsp;&nbsp;&nbsp; 参数，在宏使用时，被给定的符号替代。<br style="line-height: normal" />
Macroname&nbsp;&nbsp;&nbsp; 宏的名称，并不一定以一条指令或者符号名开始。<br style="line-height: normal" />
$parameter&nbsp;&nbsp;&nbsp;&nbsp; 在宏使用时，被替代的参数，格式为：$parameter=&ldquo;default value&rdquo;<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp; 在宏体中，参数如：$parameter和变量一样使用，在被宏引用时，被赋于新值，参数必须用&ldquo;$&rdquo;符号加于区别。$label在宏定义内部符号 时很有用，可以看作宏的参数。使用&ldquo;|&rdquo;符号作为使用一个参数缺省值的变量，如果使用的是一个空格符串，将省去该变量。在使用内部标志的宏定义中，将内部 标志定义为带后缀的标志，将会很有用。如果在扩展中空间不够，可以作为参数和后继文字之间或者参数之间使用圆点隔开，但在文本和后继参数之间不能使用圆点。宏可以定义局部变量的范围。宏还可以嵌套使用。<br style="line-height: normal" />
例：<br style="line-height: normal" />
MACRO<br style="line-height: normal" />
$label&nbsp;&nbsp;&nbsp;&nbsp; xmac&nbsp;&nbsp;&nbsp;&nbsp; $p1,$p2<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LCLS&nbsp;&nbsp;&nbsp; err<br style="line-height: normal" />
$labell,loopl<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BGE&nbsp;&nbsp;&nbsp;&nbsp; $pl<br style="line-height: normal" />
$labell,loop2<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $p1<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BEG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $p1<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BEG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $labell,loop2<br style="line-height: normal" />
MEND&nbsp;<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 五、$和$$<br style="line-height: normal" />
//$临时变量替换，若程序中需要用字符$则用$$来表示，通常情况下，包含在两个||之间的$并不表示进行变量替换，但是如果|线是在双引号内，则将进行变量替换。用&ldquo;.&rdquo;来分割出变量名的用法，<br style="line-height: normal" />
GBLS STR1<br style="line-height: normal" />
GBLS STR2<br style="line-height: normal" />
STR1 SETS &quot;AAA&quot;<br style="line-height: normal" />
STR2 SETS &quot;BBB$$STR1.CCC&quot;&nbsp;&nbsp; //汇编后STR2的值为bbAAACCC<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 六、 IMPORT&nbsp;&nbsp; Main&nbsp;&nbsp;&nbsp;&nbsp; ; The main entry of mon program<br style="line-height: normal" />
//该伪操作告诉编译器当前的符号不是在本文件中定义的，在本源文件中可能引用该符号，而不论该源文件是否使用该符号，该符号都将被加入到本源文件中。<br style="line-height: normal" />
格式：<br style="line-height: normal" />
IMPORT symbol {[WEAK]}<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; symbol 引用的符号的名称，他是区分大小写的，[WEAK]指定这个选项后，如果symbol所在的源文件中没有被定义，编译器也不会报错。他和EXTERN作用相同，不同之处在于，如果本源文件没有实际引用该符号，该符号将不会被加入到本源文件的符号表中。<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 七、AREA&nbsp;&nbsp;&nbsp;&nbsp; Init,CODE,READONLY<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENTRY<br style="line-height: normal" />
//功能：指示汇编器汇编一段新的代码或新的数据区。<br style="line-height: normal" />
格式：<br style="line-height: normal" />
name&nbsp;&nbsp; 给出的特定段名。以数字开头，必须加竖线，否则，将报错，例如：|1_Data-Area|。某些名字已保留，如：|C$$code|已经被C编译器用作代码，或者用作与C库相连的代码段。<br style="line-height: normal" />
Attr&nbsp;&nbsp;&nbsp;&nbsp; 段名属性，下列属性是有效的：<br style="line-height: normal" />
ALIGN=expression<br style="line-height: normal" />
缺省状态下，AOF段将按4个字节对准，expression可以是2~31之间的整数，该段将按2（上标为expression）字节对准。例如，espression等于<br style="line-height: normal" />
10，该段将按1KB对准。<br style="line-height: normal" />
CODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 特定机器指令，缺省为READONLY。<br style="line-height: normal" />
COMDEF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通用段定义。该AOF段可能包括代码和数据，但必须与其他段名相区别。<br style="line-height: normal" />
COMMON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通用数据段，无须再注释定义任何代码和数据，通常由链接器初始化为零。<br style="line-height: normal" />
DATA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 包含数据，但是不包含指令，缺省为READWRITE<br style="line-height: normal" />
INTERWORK&nbsp;&nbsp;&nbsp; 表明代码段可以适用ARM/Thumb interworking功能。<br style="line-height: normal" />
NOINIT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 表明数据段可以初始化为零，只包含指示符。<br style="line-height: normal" />
PIC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 表明定位独立段，可以不修改情况下，在任意地址执行。<br style="line-height: normal" />
READONLY&nbsp;&nbsp;&nbsp;&nbsp; 表明该段可读可写。<br style="line-height: normal" />
汇编时，必须至少有一个AREA指示符。使用AREA符号可以将源程序区分，但是必须不重名。通常需要独立的AOF段做为代码或者数据段，较大程序 可以分为多个代码段。AOF段可以定义局部标签的范围，可以使用ROUT符号。如果没有任何的AREA指示符定义，汇编器将会产生名为|$$$$$$$| 的AOF段和一条诊断信息，将限制由于缺少指示符而产生的错误信息，但是并不一定会成功汇编。<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 八、LTORG<br style="line-height: normal" />
//LTORG是在此指令出现的地方放一个文本池(literal pool). 在ARM汇编中常用到<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; ldr&nbsp;&nbsp;&nbsp; r0, =instruction&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将地址instruction载入r0<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 此时编译器将ldr尽可能的转变成mov或mvn指令。 如果转变不成, 将产生一个ldr指令，通过pc相对地址从一块保存常数的内存区读出instruction的值。此内存区既是文本池。一般的, 文本池放在END指令之后的地方。但是, 如果偏移地址大于4k空间, ldr指令会出错(因为ldr的相对偏移地址为12-bit的值). 此时使用LTORG放到会出错的ldr指令附近，以解决此问题。编译器会收集没有分配的ldr的值放到此文本池中<br style="line-height: normal" />
。所以必须在LDR指令前后4KB的范围内用LTORG显式地在代码段中添加一个文字池。<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 九、LDR r0,=WTCON ;watch dog disable&nbsp;<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDR r1,=0x0<br style="line-height: normal" />
功能：将一个32位常量或地址读取至寄存器。<br style="line-height: normal" />
格式：<br style="line-height: normal" />
LDR{condition} register,=[expression|Label-expression]<br style="line-height: normal" />
其中：<br style="line-height: normal" />
condition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可选的条件代码。<br style="line-height: normal" />
register&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 读取的寄存器。<br style="line-height: normal" />
expression&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数字常量：<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 如果该数字常量在MOV或MVN指令的范围中，汇编器会产生合适的指令；<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 如果该数字量不在MOV或MVN指令的范围中，汇编器把该常量于程序后，用程序相关的LDR伪指令读取，PC与该常量的偏移量不得超过4KB。<br style="line-height: normal" />
Label-expression&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 程序相关的或外部的表达式。汇编器将其存放在程序后的常量库（称为文字池（literal pool））中，用程序相关的LDR伪指令读取，PC与与该常量的偏移量不得超过4KB。</p>
<p style="line-height: normal">LDR伪指令的使用有两个目的:<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于不能被MOV和MVN指令所读取的立即数,将其变成常量,进行读取。<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将一个程序相关的或外部的表达式读取进寄存器中。<br style="line-height: normal" />
例:<br style="line-height: normal" />
LDR&nbsp;&nbsp; R1, =0xfff<br style="line-height: normal" />
LDR&nbsp;&nbsp; R2, =place<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 十、DCD 0x11110090<br style="line-height: normal" />
;Bank0=OM[1:0], Bank1~Bank7=16bit, bank2=8bit;<br style="line-height: normal" />
//DCD或&ldquo;&amp;&rdquo;<br style="line-height: normal" />
功能： 分配一个或多个字，从4个字节边界开始。<br style="line-height: normal" />
格式：<br style="line-height: normal" />
{label}DCD&nbsp;&nbsp; expression{,expression}&hellip;<br style="line-height: normal" />
其中：<br style="line-height: normal" />
expression&nbsp;&nbsp;&nbsp;&nbsp; 可以是：<br style="line-height: normal" />
一个数学表达式；<br style="line-height: normal" />
一个程序相关的表达式。</p>
<p style="line-height: normal">如果在Thumb代码中，使用DCD符号定义带标志的数据时则必须使用DATA符号。<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 按4个字节对准时，DCD符号会在第一个字节之前插入3个字节的空字符，如果无须对准的话，可以使用DCDU符号。<br style="line-height: normal" />
例：<br style="line-height: normal" />
datal&nbsp;&nbsp;&nbsp; DCD&nbsp;&nbsp;&nbsp;&nbsp; 1,5,20<br style="line-height: normal" />
data2&nbsp;&nbsp;&nbsp; DCD&nbsp;&nbsp;&nbsp;&nbsp; mem06<br style="line-height: normal" />
data3&nbsp;&nbsp;&nbsp;&nbsp; DCD&nbsp;&nbsp; glb+4<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 十一、ALIGN<br style="line-height: normal" />
//功能：从1个字边界开始。<br style="line-height: normal" />
格式：<br style="line-height: normal" />
ALIGN&nbsp;&nbsp; {expression&nbsp;&nbsp; {,offset-expression} }<br style="line-height: normal" />
其中：<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; expression&nbsp;&nbsp;&nbsp;&nbsp; 2(上标为0)到2（上标为31）之间的任意数幂，当前按2（上标为n）字节对准，如果该参数没有指定，ALIGN将按字对准。<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; Offset-expression&nbsp;&nbsp; 定义expression指定的对准方式的字节偏移量。<br style="line-height: normal" />
使用ALIGN符号，保证程序正确对准。对于Thumb地址，使用ALIGN符号保证其按字对准，例如：ADR&nbsp;&nbsp; Thuub伪指令只能读取字对准的地址。<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 在代码段出现数据定义符时，使用ALIGE符号。当在代码段使用数据定义符（DCB，DCW，DCWU，DCDU和%），程序计数器PC并不一定按字对准。<br style="line-height: normal" />
汇编器会在下一条指令时插入3个字节，保证：<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; ARM状态下按字对准；<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; Thumb状态下按半字对准。<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 在Thumb状态下，可以使用ALIGN2对Thumb代码按半字对准。<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 使用ALIGN状态下，还可以充分利用一些ARM处理器的Cache，例如，ARM940T有一个每行4字的Cache，使用ALIGN16按16字节对准，从而最大限度使用Cache。<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 十二、^ _ISR_STARTADDRESS<br style="line-height: normal" />
//MAP与&quot;^&quot;<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; MAP用于定义一个结构化的内存表（StorageMAP）的首地址。此时，内存表的位置计数器{VAR}（汇编器的内置变量）设置成该地址值。MAP可以用&rdquo;^&rdquo;代替。<br style="line-height: normal" />
语法：MAP&nbsp;&nbsp; expr {,base-register}<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 其中，expr为数字表达式或者是程序中已经定义过的标号。Base-register为一个寄存器。当指令中没有Base-register时， expr为结构化内存表的首地址。此时，内存表的位置计数器{VAR}设置成该地址值。当指令中包含这一项时，结构化内存表的首地址为expr和Base -register寄存器内容的和。<br style="line-height: normal" />
使用说明：MAP伪操作和FIELD伪操作配合使用来定义结构化的内存表结构。</p>
<p style="line-height: normal">举例：MAP伪操作<br style="line-height: normal" />
MAP&nbsp;&nbsp; fun&nbsp;&nbsp; ;fun就是内存表的首地址<br style="line-height: normal" />
MAP&nbsp;&nbsp;&nbsp; 0x100,R9&nbsp;&nbsp; ;内存表的首地址为 R9+0x100<br style="line-height: normal" />
*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 十三、HandleReset # 4&nbsp;<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HandleUndef # 4&nbsp;<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HandleSWI # 4<br style="line-height: normal" />
//FIELD和&quot;#&quot;<br style="line-height: normal" />
FIELD 用于定义一个结构化的内存表中的数据域。FIELD 可用&ldquo;#&rdquo;代替。<br style="line-height: normal" />
语法：{label} FIELD expr<br style="line-height: normal" />
其中：{label}为可选的。当指令中包含这一项时，label的值为当前内存表的位置计数器{VAR}的值。汇编编译器处理了这条FIELD伪操作后。<br style="line-height: normal" />
内存表计数器的值将加上expr.expr表示本数据域在内存中所占的字节数。<br style="line-height: normal" />
使用说明：MAP伪操作和FIELD伪操作配合使用来定义结构化的内存表结构。MAP伪操作定义内存表的首地址。FIELD伪操作定义内存表的数据域的字节长度，并可以为每一格数据域指定一个标号，其他指令可以引用该标号。<br style="line-height: normal" />
MAP伪操作中的Base-registe寄存器值队以其后所有FIELD伪操作定义的数据域是默认使用的，直到遇到新的包含Base-registe项的MAP伪操作需要特别注意的是，MAP伪操作和FIELD伪操作仅仅是定义数据结构，他们并不实际分配内存单元。由MAP伪操作和FIELD伪操作配合 定义的内存表有3种：基于绝对地址的内存表，基于相对地址的内存表和基于PC的内存表。<br style="line-height: normal" />
举例：基于绝对地址的内存表<br style="line-height: normal" />
用伪操作序列定义一个内存表，其首地址为固定的地址8192（0X2000），该内存表中包括5个数据域。&nbsp;&nbsp;&nbsp;<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; Consta长度为4个字节；constb长为4个字节，x长为8字节；y长为8字节；string长为16字节。这种内存表成为基于绝对地址的内存表。<br style="line-height: normal" />
MAP&nbsp;&nbsp; 8192 ； //内存表的首地址8192（0x2000）<br style="line-height: normal" />
Consta FIELD 4 ; //consta 长为4字节，相对位置为0<br style="line-height: normal" />
Constb FIELD 4; //constb长为4字节，相对位置为4<br style="line-height: normal" />
X&nbsp;&nbsp;&nbsp; FIELD&nbsp;&nbsp; 8; // X长为8字节，相对位置为8<br style="line-height: normal" />
Y&nbsp;&nbsp;&nbsp;&nbsp; FIELD 8; // y长为8字节，相对位置为16<br style="line-height: normal" />
String FIELD 16 ;// String为16字节，相对位置为24<br style="line-height: normal" />
在指令中，可以这样引用内存表中的数据域；<br style="line-height: normal" />
LDR R0，consta； //将consta地址处对应内存加载到R0上面的指令仅仅可以访问LDR指令前后4KB地址范围的数据域。<br style="line-height: normal" />
举例：相对绝对地址的内存表<br style="line-height: normal" />
下面的伪操作序列定义一个内存表，其首地址为0与R9寄存器值得和，该内存表中包含5个数据域。这种表称为相对地址的内存表。<br style="line-height: normal" />
MAP 0，R9；//内存表的首地址寄存器R9的值<br style="line-height: normal" />
Consta FIELD 4 ; //consta 长为4字节，相对位置为0<br style="line-height: normal" />
Constb FIELD 4; //constb长为4字节，相对位置为4<br style="line-height: normal" />
X&nbsp;&nbsp;&nbsp; FIELD&nbsp;&nbsp; 8; // X长为8字节，相对位置为8<br style="line-height: normal" />
Y&nbsp;&nbsp;&nbsp;&nbsp; FIELD 8; // y长为8字节，相对位置为16<br style="line-height: normal" />
String FIELD 16;// String为16字节，相对位置为24<br style="line-height: normal" />
可以通过下面的指令访问地址范围超过4KB的数据；<br style="line-height: normal" />
ADR&nbsp;&nbsp; R9， Field ;&nbsp;&nbsp; //伪指令<br style="line-height: normal" />
LDR&nbsp;&nbsp; R5，Constb；//相当于LDR R5，[R9，#4]<br style="line-height: normal" />
在这里，内存表中的数据都是相对于R9寄存器的内容，而不是相对于一个固定的地址。通过在LDR中指定不同的基址寄存器的值，定义的内存表结构可以在程序中有多个实例。可多次使用LDR指令，用以实现不同的程序实例。<br style="line-height: normal" />
举例：基于PC的内存表<br style="line-height: normal" />
Data&nbsp;&nbsp;&nbsp; SPACE 100 ; //分配100字节的内存单元，并初始化为0<br style="line-height: normal" />
MAP Data；//内存表的首地址为Datastruc内存单元<br style="line-height: normal" />
Consta FIELD 4 ; //consta 长为4字节，相对位置为0<br style="line-height: normal" />
Constb FIELD 4; //constb长为4字节，相对位置为4<br style="line-height: normal" />
X&nbsp;&nbsp;&nbsp; FIELD&nbsp;&nbsp; 8; // X长为8字节，相对位置为8<br style="line-height: normal" />
Y&nbsp;&nbsp;&nbsp;&nbsp; FIELD 8; // y长为8字节，相对位置为16<br style="line-height: normal" />
String FIELD 16;// String为16字节，相对位置为24<br style="line-height: normal" />
可以通过下面的指令访问范围不超过4kb的数据；<br style="line-height: normal" />
LDR R5，constb ；相当于 LDR R5,[PC,offset]*****************************************************<br style="line-height: normal" />
&nbsp;&nbsp;&nbsp;&nbsp; 十四、RN<br style="line-height: normal" />
在局部标号中：<br style="line-height: normal" />
%表示引用操作<br style="line-height: normal" />
F指示编译器只向前搜索。<br style="line-height: normal" />
B指示编译器只向后搜索。<br style="line-height: normal" />
A指示编译器搜索宏的所有嵌套层。<br style="line-height: normal" />
T指示编译器搜索宏的当前层次。<br style="line-height: normal" />
若F、B没有指定则先向前搜索，再向后搜索。<br style="line-height: normal" />
若A、T都没有指定则先从当前层到最高层，比当前层低的不再搜索</p>
</span></div>]]></description></item></channel></rss>