AREA Block,CODE,READONLY <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
;设置将要复制的字数(定义变量num,并赋值为20)
num EQU 20 ;程序入口标志
ENTRY
start
;r0寄存器指向源数据区(SRC 标识的地址放入R0)
LDR r0,=src
;r1寄存器指向目标数据区(DST 标识的地址放入R1)
LDR r1,=dst
;r2指定将要复制的字数(装载num 的值到R2)
MOV r2, #num
;设置数据栈指针(R13),用于保存工作寄存器数值(设定SP堆栈开始地址为0x400)
MOV sp, #0x400
;进行以8个字节为单位的数据复制
blockcopy
;需要进行的以8个字为单位的复制次数( R2 右移3 位后的值放入R3)
MOVS r3,r2, LSR #3
;对于剩下的不足8个字的数据,跳转到copywords,以字为单位复制(判断是否为0,为0 跳移)
BEQ copywords
;保存工作寄存器(把R4 到R11 的值保存到SP 标识的堆栈中)
STMFD sp!, {r4-r11}
octcopy
;从数据区读取8个字节的数据,放到8个寄存器中,并更新目标数据区指针r0(把R0 中的地址标识的内容顺序装载到R4 到R11 中)
LDMIA r0!, {r4-r11}
;将这8个字数据写入到目标数据区,并更新目标数据区指针r1(把R4 到R11 的值顺序保存到以R1 起始地址的内存中)
STMIA r1!, {r4-r11} ;将块的复制次数减1 (R3 -1 计数)
SUBS r3, r3, #1 ;循环,直到完成以8个字为单位的块复制
BNE octcopy
;需要注意的是,LDMIA 或者STMIA 指令执行后,R0,R1 的值产生变化,每一次寄存器操作,R0 或者R1 的值会自动增加一个字节的量,这里操作了8 个寄存器,R0 或者R1 的值也相应增加了8 个字节
;恢复工作寄存器值(把刚才保存的SP 堆栈中的值恢复到R4 到R11 中)
LDMFD sp!, {r4-r11}
copywords
;剩下不足8个字的数据的字数(逻辑与,把R2 前7 位扔掉)
ANDS r2, r2, #7
;数据复制完成(判断是否为0,为0 跳移)
BEQ stop
wordcopy
;从源数据区读取18个字的数据,放到r3寄存器中,并更新目标数据区指针r0(把R0 表示地址的内容的后4 位全部拷贝到R3)
LDR r3, [r0], #4
;将这r3中数据写入到目标数据区中,并更新目标数据区指针r1 (把R3 的内容,放入以R1 为起始地址的4 位内存中)
STR r3, [r1], #4
;将字数减1;(R2 -1 放回R2)
SUBS r2, r2, #1
;循环,直到完成以字为单位的数据复制(判断是否为0,不为0 跳移,同样的,这里R0,R1 操作后,R0,R1 会自动加上便宜量)
BNE wordcopy
stop
;从应用程序中退出
MOV r0, #0x18
LDR r1, =0x20026
SWI 0x123456
;定义数据区bloackdata
AREA Bloackdata, DATA, READWRITE
;定义源数据区src及目标数据区dst
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
程序调试式:如果一开始PC值定位为0x30100000,则寄存器的变化过程为:R0=0x30100060,r1=0x301000B0,r2=0x14,r3=0x2
第一次复制8个子数据,r4--r11=1--8,r0=0x30100080,r1=0x301000D0,第二次 r0=x301000A0,r1=0x301000F0
注意FD时,堆栈递减的,r11-r4,r4对应sp=0x3E0最低地址。
恢复工作寄存器组,以前用FD方式,现在也用FD方式
剩下的不足8个数据的字数,即使把最后三位前面的数全扔掉,所以#7相与
文章评论(0条评论)
登录后参与讨论