寻址方式
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
01、立即数寻址
数据保存在指令中可以立即使用。所以称为立即数。
例如:
mov r0 , # 50 ;将立即数50传送到r0寄存器中。
使用规则:
01、★立即数前面必须使用"#"做标记,这是和MASN32不同之处,初学ARM汇编很容易忘记。
02、如果没有明确标识默认的进制为10进制。
03、16进制数使用"0x"做标记如:0x64。不能使用MASM32中的在末尾加H的写法。64H是错误的。
04、2进制数据使用"2_"做标记如:2_0101。
05、立即数寻址可以使用4则运算例如:mov r0 , # 50 + 50
06、立即数寻址可以使用逻辑运算例如:mov r0 , # 1 | 0
07、★特别注意:由于立即数保存在指令中所以并不是任意立即数都可以使用。立即数必须满足这样的条件:常数必须由一个8位的常数循环移位偶数位得到的。比如:[0,256]之间的数都可以,1024,2048等常数都正确。如果出错则在编译的时候就会出现提示,Xarm构建时控制台会出现白底红字的显示效果。
02、寄存器寻址
操作数的值保存在寄存器中,指令执行时直接取寄存器中数据操作。
例如:
mov r1 , r0 ;将r0中的数据传递到r1寄存器中。
add r0 , r0 , r1 ;将r0和r1中数据累加后保存到r0中。
03、寄存器偏移寻址
这种寻址方式是ARM处理器特有的。当第二个操作数是寄存器寻址时,可以首先进行移位操作再和第一个操作数结合。
例如:
mov r0 , r1 , lsl #1 ;将r1中的数据逻辑左移一位再传送到r0中。相当于r0 = r1 * 2
这是ARM指令的一个特点:可以将移位操作放在其他操作中在一条指令中完成。这样就提高了指令效率。
移位指令有5种这里简单介绍一下在后面的文章中详细说明:
lsl:逻辑左移。
lsr:逻辑右移。
asr:算术右移。
ror:循环右移。
rrx:带扩展的循环右移。
04、寄存器间接寻址
所需要的操作数位于在寄存器保存的地址数据指向的内存中。寄存器中保存的实际上是一个指针。
例如:
ldr r0 , [r1] ;将r1中保存的内存地址中的数据传送到r0中。
显然这类寻址方式很重要,因为通过它们可以实现内存和寄存器之间的数据交换。
05、基址变址寻址
基址变址寻址是将基址寄存器中的内容和指令中给出的偏移量相加,形成操作数的有效地址。这种寻址方式适合访问基址附近的存储单元,常用于查表和数组操作。举个实战中的例子在编写PE程序加密软件时需要读取大量的PE文件头中的信息。一个简单的方法就是用一个基址寄存器保存文件头在内存中的偏移量,然后加上待取数据的偏移量就可以很方便、整齐的读取到所有需要的数据信息。
ldr r0,[r1,#4];r0 ←[r1+4]
ldr r0,[r1,#4]!;r0 ←[r1+4]、r1 ←r1+4
ldr r0,[r1] ,#4;r0 ←[r1]、r1 ←r1+4
ldr r0,[r1,r2];r0 ←[r1+r2]
在第一条指令中,将寄存器r1的内容加上4形成操作数的有效地址,从而取得操作数存入寄存器r0中。
在第二条指令中,将寄存器r1的内容加上4形成操作数的有效地址,从而取得操作数存入寄存器r0中,然后,r1的内容自增4个字节。
在第三条指令中,以寄存器r1的内容作为操作数的有效地址,从而取得操作数存入寄存器r0中,然后,r1的内容自增4个字节。
在第四条指令中,将寄存器r1的内容加上寄存器R2的内容形成操作数的有效地址,从而取得操作数存入寄存器r0中。
06、多寄存器寻址
采用多寄存器寻址方式,一条指令可以完成多个寄存器值的传送。这种寻址方式可以用一条
指令完成传送最多16个通用寄存器的值。以下指令:
ldmia r0,{r1,R2,R3,R4}
;r1←[r0]
;r2←[r0+4]
;r3←[r0+8]
;r4←[r0+12]
该指令的后缀ia表示在每次执行完加载/存储操作后,r0按字长度增加,因此,指令可将连续存储单元的值传送到r1~r4。
07、堆栈寻址
堆栈是一种数据结构,按先进后出(First In Last Out,FILO)的方式工作,使用一个称作堆栈指针的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。当堆栈指针指向最后压入堆栈的数据时,称为满堆栈(Full Stack),而当堆栈指针指向下一个将要放入数据的空位置时,称为空堆栈(Empty Stack)。同时,根据堆栈的生成方式,又可以分为递增堆栈(Ascending Stack)和递减堆栈(Decending Stack),当堆栈由低地址向高地址生成时,称为递增堆栈,当堆栈由高地址向低地址生成时,称为递减堆栈。这样就有四种类型的堆栈工作方式,ARM微处理器支持这四种类型的堆栈工作方式,即:
满递增堆栈:堆栈指针指向最后压入的数据,且由低地址向高地址生成。例如:ldmfa和stmfa等。
满递减堆栈:堆栈指针指向最后压入的数据,且由高地址向低地址生成。例如:ldmfd和stmfd等。
空递增堆栈:堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生成。例如:ldmea和stmea等。
空递减堆栈:堆栈指针指向下一个将要放入数据的空位置,且由高地址向低地址生成。例如:ldmed和stmed等。
堆栈寻址经常用在函数的首尾,在函数首部用于保存连接寄存器(函数返回地址)、r4以上寄存器等,在函数尾部恢复寄存器数据并将返回地址写入PC。
08、相对寻址
与基址变址寻址方式相类似,相对寻址以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。以b开头的跳转指令(包括函数调用指令bl)都是使用这类寻址方式。
mov r0 , # 100
cmp r0 , # 100
beq LabelTest ;相等时跳转到标号LabelTest位置处继续执行。