ARM指令

  1. 编绎执行下列汇编程序sy1.S,要示在开发板上执行。程序执行后返回到调用处,使用uboot的md 0x20009000 1命令查看0x20009000处的值。理解程序如何返回的调用处的,程序调用要做哪些工作。如果省去最后mov pc,lr指令,则会出现什么结果,为什么?
.text
.global _start
_start:
    mov r0,#0x04
    mov r1,#0x03
    add r2,r0,r1
    Ldr r3,=0x20009000
    str r2,[r3]
    
    mov pc,lr # 函数返回 下一题将会解释此条代码的作用
.end
  1. 将sy1程序下载到0x20007000处,编写汇编程序sy2.S,调用sy1,并能正确返回。

由于三级流水线:

所以当第七行指令执行时,pc已经指向到第十行指令。所以第一题函数将lr赋值给pc,即将pc重新指向第10行指令。

.global _start
_start:
	ldr r0,=0x20007000
	
	push {lr} # 保存lr

	mov lr,pc
	mov pc,r0
	
	pop {lr}
	
	mov pc,lr # 同上一题作用
.end
  1. 编写程序sy3.S,功能:开中断,禁止快速中断。
.global _start
_start:
	# I F T M[4:0]
	mrs r0,cpsr  	# 保存当前状态寄存器
	bic r0,r0,#0x80 # 第8位清零 
	orr r0,r0,#0x40 # 逻辑或 
	msr cpsr,r0  	# 还原当前程序状态寄存器
	
	mov pc,lr
  1. 编写程序sy4.S,读取内存地址为0x20008000处的值入r0,修改r0低8位为0x1f 修改某几位的值可以采用,先置零,再逻辑或的方式,其他位保持不变。并将r0的值存入内存单元0x20009000处。
.global _start
_start:
	ldr r1,=0x20008000 # r1赋值为
	ldr r0,[r1] 		# 再从r1读取
	
	bic r0,r0, #0xff   # ro置零
	orr r0,r0, #0x1f   # 修改r0第八位为0x1f

	ldr r1,=0x20009000
	str r0,[r1]

	mov pc,lr
  1. Sy5.S使用循环计算1+2+…+100 并将结果存入0x20009000处
.global _start
_start:
	mov r0,#0
	mov r1,#1

loop:
	cmp r1,#100
	bgt exit
	add r0,r0,r1
	add r1,r1,#1
	b loop
exit:
	ldr r1,=0x20009000
	str r0,[r1]
	mov pc,lr
.end
  1. 编写程序sy6.S计算 1+(1+2)+(1+2+3)+….+(1+2+..+20),并将结果存入0x20009000处,要编写子程序addn 计算1+2+..n,主程序调用该子程序最终完成计算( 结果: 0x604 )。

BL: 带链接的跳转。 首先将当前指令的下一条指令地址保存在LR寄存器,然后跳转的lable。通常用于调用子程序,可通过在子程序的尾部添加mov pc, lr 返回。

.global _start
_start:

mov r3,#0  // save sum
mov r4,#1  // count
push {lr}

for:
	cmp r4,#20
	bgt endfor
	
	mov r0,r4
	bl addn
	add r3,r3,r0
	add r4,r4,#1
	b for
endfor:
	ldr r0,=0x20009000
	str r3,[r0]
	pop {lr}
	mov pc,lr

addn:
	mov r1,#1  // count  r0:refrence ,return value
	mov r2,#0  //save result

loop:
	cmp r1,r0
	bgt exit
	
	add r2,r2,r1
	add r1,r1,#1
	b loop	

exit:
	mov r0,r2
	mov pc,lr
.end
原文地址:https://www.cnblogs.com/mayapony/p/14956297.html