原来只知道一个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)表示在数据传送前,基址寄存器的值递减
到这里算是全部搞懂了,要是您觉得哪里存在问题请留言,谢谢!