本节介绍多数据加载指令和多数据保存指令。
多数据加载指令包括LDM、LDMIA和LDMFD。它们使用基址寄存器中的地址从连续的存储器位置中加载多个寄存器后,加载多个增量。连续的存储器位置从该地址开始,并且当基址寄存器Rn不属于<registers>列表时,这些位置的最后一个地址之上的地址将写回基址寄存器。
下面对LDM指令进行详细说明。该指令有两种形式,包括:
注: (1)!的作用是:使指令将修改后的值写回<Rn>。如果没有!,则指令不会以这种方式修改<Rn>。
(2)registers是要加载的一个或多个寄存器的列表,用逗号分隔,并且用{}符号包围。编号最小的寄存器从最低的存储器地址加载,直到从最高的存储器地址加载到编号最大的寄存器。
该汇编助记符指令的机器码格式如图4.28所示。从该指令的机器码格式可知,Rn所使用寄存器的范围为R0~R7。
图4.28 LDM指令的机器码格式
注: register_list字段中的每一位都对应一个寄存器。register_list[7]对应寄存器R7;register_list[6]对应寄存器R6;register_list[5]对应寄存器R5;register_list[4]对应寄存器R4;register_list[3]对应寄存器R3;register_list[2]对应寄存器R2;register_list[1]对应寄存器R1;register_list[0]对应寄存器R0。当<registers>存在某个寄存器时,register_list字段中对应的位置为1,否则为0。
指令LDM R0!,{R1,R2-R7},其机器码为(C8FE) 16 。该指令实现以下功能。
(1)将寄存器R0所指向存储器地址单元的内容复制到寄存器R1中。
(2)将寄存器R0+4所指向存储器地址单元的内容复制到寄存器R2中。
(3)将寄存器R0+8所指向存储器地址单元的内容复制到寄存器R3中。
……
(7)将寄存器R0+24所指向存储器地址单元的内容复制到寄存器R7中。
(8)用R0+4×7的值更新寄存器R0的内容。
注: LDMIA和LDMFD为LDM指令的伪指令。LDMIA是LDM指令的别名,用法同LDM。LDMFD是同一指令的另一个名字,在使用软件管理堆栈的传统Arm系统中,该指令用于从全递减堆栈中还原数据。
多数据保存指令包括STM、STMIA和STMEA。使用来自基址寄存器的地址将多个寄存器的内容保存到连续的存储器位置。随后的存储器位置从该地址开始,并且这些位置的最后一个地址之上的地址将写回基址寄存器。指令格式为
注: (1)!的作用是:使指令将修改后的值写回<Rn>。
(2)registers是要加载的一个或多个寄存器的列表,用逗号分隔,并且用{}符号包围。编号最小的寄存器从最低的存储器地址加载,直到从最高的存储器地址加载到编号最大的寄存器。不推荐在寄存器列表中使用<Rn>。
该汇编助记符指令的机器码格式如图4.29所示。
图4.29 STM<Rn>!,<registers>指令的机器码格式
注: register_list的具体含义同图4.28。
指令STM R0!,{R1,R2-R7},其机器码为(C0FE) 16 。该指令实现以下功能。
(1)将寄存器R1的内容复制到寄存器R0所指向存储器地址的单元中。
(2)将寄存器R2的内容复制到寄存器R0+4所指向存储器地址的单元中。
(3)将寄存器R3的内容复制到寄存器R0+8所指向存储器地址的单元中。
……
(7)将寄存器R7的内容复制到寄存器R0+24所指向存储器地址的单元中。
(8)用R0+7×4的值更新R0寄存器的值。
思考与练习4.6:说明以下指令实现的功能。
(1)LDM R0,{R0,R3,R4}_______________________________
(2)STMIA R1!,{R2-R4,R6}_______________________________