汇编语言的学习

	preserve8  ;使用栈,需要8字节对齐
	area reset, code, readonly
	code32
	entry

	;初始化异常向量表
	b start		 ;reset	 复位		 
	nop			 ;undef	 未定义指令
	b deal_swi   ;swi	 软中断
	nop          ;prefetch abort  预取中止
	nop			 ;data abort	  数据中止
	nop			 ;reserved		  保留
	nop			 ;irq			  中断
	nop			 ;fiq			  快中断
	
deal_swi		;类似于C语言中的信号处理函数
	stmfd sp!, {r4-r12, lr}	 
	sub r0, lr, #4			   ;获取swi #7的地址
	ldr r1, [r0]               ;[r0]表示取r0地址里的值,类似指针的*运算			
	bic r0, r1, #0xff000000    ;r0 = 7
	import c_deal_swi		   ;处理swi的C函数
	bl c_deal_swi
	ldmfd sp!,{r4-r12, pc}^    ;^ 带模式切换的恢复现场

start
	ldr sp, =0x40001000 ;初始化svc模式的栈 ldr : 加载一个内存地址

	;切换到user模式,切换模式后,原来的栈也就没了,因为每种工作模式都有自己的栈
	mrs r0, cpsr ;mrs:读取cpsr的值 将cpsr的值读取r0中
	bic r0, r0, #0x1f	;先清零
	orr r0, r0, #0x10	;再置一
	msr cpsr_c, r0 ;msr:把值写入cpsr cpsr_c(修改工作模式==>修改低5位) 域叠加:cpsr_fsxc
	ldr sp, =0x40000c00	;初始化user模式的栈 3k

	mov r0, #1		 ;立即数:一个数右移偶数位或按位取反后,所有的1都能放进低八位中
	mov r1, #2
	add r2, r0, r1
	sub r3, r1, r0

	mov r0, #0xff
	mov r1, #0x55
	and r2, r0, r1
	orr r3, r0, r1
	eor r4, r0, r1

	mov r0, #0xff
	mov r1, #0x0f	  ;0xf <==> 0x0f
	bic r2, r0, r1	  ;按位与,再取反

	;0x 0001 ffff ffff
	;0x 0002 0000 0003  相加
	;相加结果应为:0x 0004 0000 0002
	;实现了在32位计算机里进行64位数字的运算 
	mov r0, #0xffffffff
	mov r1, #1
	mov r2, #0x3
	mov r3, #0x2
	adds r4, r0, r2  ;adds 更新进位标志,cpsr中的C位变为1
	adc r5, r1, r3	 ;adc 带进借位的加法

	;cmp cmn tst teq
	;这些比较和测试指令都是专门用来影响cpsr的那几个标志的
	mov r0, #4
	mov r1, #5
	cmp r0, r1  ;cmp 比较大小 为负 C位为0 N位为1表示ALU运算结果为负
	movlt r2, r0   ;<==>if(r0 < r1)
			  	   ;	  r2 = r0;	  lt gt eq 分别为 <  >  = 都是条件码的一种
	
	swi #5  ;软中断指令,当复位或者软中断指令执行的时候,就会切换到SVC模式	

	mov r0, #5
	mov r1, #6
	mov r2, #7
	cmp r0, r1		;<==>if(r0 < r1 && r0 < r2)	{
	cmplt r0, r2	;           r3 = r0;
	movlt r3, r0	;			r4 = r0;
	movlt r4, r0	;			}
	movlt r5, r0    ;<==> if(r0 > r2) r5 = r0; 

	;1+ ..... + 100 实现1到100的累加
	mov r0, #1
	mov r1, #0
loop
	add r1, r1, r0
	add r0, r0, #1
	cmp r0, #100
	ble loop		; 条件码 le 表示 <=


	mov r0, #1	  ;函数传参规则: r0 - r3 以及 栈  栈指针就是SP所指的地址 (满减栈)
	mov r1, #2	  ;函数的返回值存放在r0中
	import c_add  ;import --> 声明,c_add 是定义的一个C语言的函数
	bl c_add	  ; bl 带链接返回的调整,自动把返回地址保存在LR里边

	mov r0, #1
	mov r1, #2
	mov r6, #6
	bl asm_add

	nop
	b start		 ; b 类似于 C中的go to

	export asm_add  ;汇编里的一个符号要被外部使用,需要用 export 声明
asm_add
	stmfd sp!, {r4-r12, lr}	  ;保护现场  stmfd:入栈,{}里放着的是要入栈的寄存器  封装函数时必须要将返回地址入栈
	add r0, r0, r1
	mov r6, #7				  ;不希望外部的数据因为调用函数而发生改变,所以需要入栈,保护这些数据
	ldmfd sp!,{r4-r12, pc}	  ;恢复现场  ldmfd:出栈  这两条出入栈指令是封装函数必备的

	end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值