ARM汇编程序设计之数据搬移

原来只知道一个MOV指令,却不知道还有个MOVS,在书上查找了只有MOV传送指令,

num EQU 20;定义一个常量num,值为20

;---------------------------------------------------------------------------------------------------
;AREA分析如下:

;语法格式:
;AREA	段名	属性1,属性2,。。。

;AREA伪指令用于定义一个代码段或数据段。其中段名若以数字开头,则该段名需用"|"
;括起来,如|1_test|;属性字段表示该代码段(或数据段) 的相关属性,多个属性用逗号分开常用
;属性如下:

;CODE属性:用于定义代码段,默认为READONLY

;DATA属性:用于定义数据段,默认为READWRITE

;READONLY属性:指定本段为只读,代码段默认为READONLY

;READWRITE属性:指定本段为可读可写,数据段的默认属性为READWRITE

;ALIGN属性:使用方式为ALIGN表达式。

;COMMON属性:该属性定义一个通用的段,不包含任何的用户代码和数据。各源文件中同名的COMMON段共享
;同一段存储单元
;---------------------------------------------------------------------------------------------------


	AREA	EXAMPLE2,CODE,READONLY	;声明一个代码段,名为EXAMPLE2
	ENTRY	;指定程序入口点
	;-----------------------------------------------------------------------------------------------  
	;ENTRY:一个完整的汇编程序中至少要有一个ENTRY,也可以有多个。当有多个ENTRY时,程序的真正入口点由
	;连接器指定,但在一个源文件里最多只能有一个ENTRY,也可以没有。
	;-----------------------------------------------------------------------------------------------
Start
	LDR		r0, =src			;/*  r0 = pointer to source block 指向源操作数的首地址*/
	LDR		r1, =dst			;/*  r1 = pointer to destination block 指向目的操作数的首地址*/
	MOV		r2, #num			;/*  r2 = number of words to copy 要拷贝大小*/
	MOV		sp, #0x400			;/*  set up stack pointer (r13) 确定堆栈地址*/
	
blockcopy
	MOVS	r3,r2, LSR #3		;/*  number of eight word multiples */
	BEQ		copywords			;/*  less than eight words to move ? */
	STMFD	sp!, {r4-r11}		;/*  save some working registers */
octcopy
	LDMIA	r0!, {r4-r11}		;/*  load 8 words from the source */
	STMIA	r1!, {r4-r11}		;/*  and put them at the destination */
	SUBS	r3, r3, #1			;/*  decrement the counter */
	BNE		octcopy				;/*  ... copy more */
	LDMFD	sp!, {r4-r11}		;/*  don't need these now - restore originals */
copywords
	ANDS	r2, r2, #7     		;/*  number of odd words to copy */
	BEQ		stop           		;/*  No words left to copy ? */
wordcopy
	LDR		r3, [r0], #4		;/*  a word from the source */
	STR		r3, [r1], #4		;/*  store a word to the destination */
	SUBS	r2, r2, #1			;/*  decrement the counter */
	BNE		wordcopy			;/*  ... copy more */
stop
	B		stop				;/*在此进入死循环*/

	AREA	blockdata,DATA,READWRITE	;声明一个数据段,名为blockdata
	
src	DCD	1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4

dst	DCD	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	END

今天到这算是搞定这个程序了,算是完全弄懂了他是怎么执行的了,不容易啊!

还有一个要特别说明的寄存器操作方式:

多寄存器装载与存储:

用一条指令把存储器里的数据装载到多个寄存器,或者把多个寄存器里的数据存储到存储器,这类指令就是多寄存器装载与存储指令,他们特别适合两种情况:堆栈操作和数据块传输。

在这两种情况下,使用多寄存器传送指令比使用单寄存器传送指令效率要高很多。

实现方式和分类:

STMIA/LDMIA     IA(Increment After)表示在数据传送后,基址寄存器的值递增。

STMIB/LDMIB  IB(Increment Before) 表示在数据传送前,基址寄存器的值递增

STMDA/LDMDA  DA(Decrement After)表示在数据传送后,基址寄存器的值递减

STMDB/LDMDB  DB(Decrement Before)表示在数据传送前,基址寄存器的值递减

到这里算是全部搞懂了,要是您觉得哪里存在问题请留言,谢谢!

原文地址:https://www.cnblogs.com/tao560532/p/2276406.html