【ARM】基本汇编指令——Keil
来源:互联网 发布:广电网络中山分公司 编辑:程序博客网 时间:2024/05/29 13:15
area reset, code ; 定义一个代码段叫reset;/*汇编文件中的符号*/ ;1.指令:编译完成后作为一条指令存储在内存单元当中,CPU执行时能完成一定的操作 ;2.伪操作:不会生成代码也不会占用内存,告诉编译器怎样编译 ;3.伪指令:本身不是指令,编译器在编译的时候将其替换成CPU能识别的指令;/*指令*/ ;1.数据操作指令:对数据进行逻辑、数学等运算与处理 ;2.跳转指令:实现程序的跳转,实质是修改PC ;3.Load/Store:对内存的读写操作 ;4.状态寄存器传送指令:对CPSR进行读写操作 ;5.异常中断产生指令:触发软中断 ;6.协处理器指令:操作协处理器的指令entry ; 汇编的入口 ;/*********************数据处理指令**********************/ ; 数据搬移指令 ; mov r1, #1 ; r1 = 1 ; mov r2, r1 ; r2 = r1 ; mvn r1, #0x000000FF ; r1 = ~(0x000000FF) ; 立即数 ; mov r1, #0xFF000000 ; 立即数0xFF000000由0xFF循环右移(0x4*2)次得到 所以机器码中【7:0】为0xFF 【11:8】为0x4 ; 立即数的本质是包含在指令当中的数 ; 在mov指令中给立即数留了12位的存储空间,所以立即数只包含了2的12次方个 ; 一个立即数是由一个八位的数循环右移偶数次得到的 ; mov r1, #0xFFFFFFFF ; 编译器将其进行了指令的替换 ; 加法指令 ; mov r1, #1 ; mov r2, #2 ; add r3, r1, r2 ; r3 = r1 + r2 ; add r3, r1, #2 ; r3 = r1 + 2 ;数据运算指令的基本格式 ;《操作码》《目标寄存器》《第一操作寄存器》《第二操作数》 ;默认情况下,数据处理指令不影响标志位,可以选择通过添加后缀“S”来影响标志位。 ; mov r1, #0xFFFFFFFE ; adds r2, r1, #3 ; 带进位的加法指令 ; 两个64位数相加,第一个数的低32位放在r0高32位放在r1,第二个数的低32位放在r2高32位放在r3 ; 编写代码实现两个64位数的和,结果的低32位放在r4高32位放在r5 ; MOV R0, #0xFFFFFFFE ; MOV R1, #1 ; MOV R2, #0x5 ; MOV R3, #1 ; ADDS R4, R0, R2 ; ADC R5, R1, R3 ; 本质:r5 = r1 + r3 + 'C' ; 减法指令 ; mov r1, #5 ; mov r2, #3 ; subs r3, r1, r2 ; r3 = r1 - r2 ; 带借位的减法指令 ; mov r0, #5 ; mov r1, #3 ; mov r2, #6 ; mov r3, #1 ; subs r4, r0, r2 ; sbc r5, r1, r3 ; 本质:r5 = r1 - r3 - '!C' ; 逆向减法 ; mov r1, #5 ; rsb r2, r1, #8 ; r2 = 8 - r1 ; 乘法指令 ; mov r1, #3 ; mov r2, #5 ; mul r3, r1, r2 ; 乘法指令不能使用立即数 ;逻辑与 ;mov r0, #0xf0 ;mov r1, #0x0f ;and r2, r0, r1 ;r2 = r0 & r1 ;逻辑或运算 ;mov r0, #0xf0 ;mov r1, #0x0f ;orr r2, r0, r1 ;r2 = r0 | r1 ;逻辑异或运算 ;mov r0, #0xff ;mov r1, #0xff ;eor r2, r1, r0 ;r2 = r1 eor r0 ; 位清零指令 ; mov r0, #0xff ; bic r1, r0, #0xf ;比较指令 ;mov r1, #1 ;mov r2, #1 ;cmp r1, r2 ;实质:减法指令 ;没有目标寄存器 ;比较的结果在Z位显示 ;移位器 ; mov r1, #0xFF ; lsl r1, r1, #4 ; 逻辑左移 高位移出 低位补零 ; lsr r1,r1, #4 ; 逻辑右移 低位移出 高位补零 ; mov r1, #0x7FFFFFFF ; asr r1, r1, #16 ; 算数右移 低位移出 高位补符号位 ; mov r1, 0xff ; ror r2, r1, #4 ; 循环右移 低位移出 高位补低位 ; mov r2, #0xFF ; mov r1, r2, lsl #4 ; r1 = (r2 << 4);/*********************跳转指令**********************/ ;mov r1, #1 ;mov r2, #2 ;mov r3, #3 ;b loop ;mov r4, #4 ;mov r5, #5;loop ;mov r6, #6 ;mov r7, #7 ;跳转指令的实质就是将PC修改为跳转标签下的第一条指令的地址 ;带返回的跳转;MAIN; MOV R1, #1; MOV R2, #2; BL FUNC; MOV R5,#5; MOV R6,#6;FUNC; MOV R3,#3; MOV R4,#4; MOV PC,LR ;ARM指令的条件执行 ;mov r1, #1 ;mov r2, #2 ;cmp r1, r2 ;beq loop ;if(eq){b loop} => 实质:if(z==1){b loop} ;bne loop ;if(ne){b loop} => 实质:if(z==0){b loop} ;mov r3, #3 ;mov r4, #4;loop ;mov r5, #5 ;mov r6, #6 ;练习 ;mov r0, #9 ;mov r1, #15;loop ;cmp r0, r1 ;beq stop ;subgt r0, r0, r1 ;sublt r1, r1, r0 ;b loop;stop ;b stop;/*********************Load/Store指令**********************/ ; mov r1, #0xF000000F ; mov r2, #0x40000000 ; str r1, [r2] ; 将r1寄存器中的值存储到内存中以0x40000000为起始地址的连续的4字节空间 ; strb r1, [r2] ; 将r1的低8位存储到内存0x40000000地址中 ; strh r1, [r2] ; 将r1寄存器中的低16位存储到内存中以0x40000000为起始地址的连续的2字节空间 ; ldr r3, [r2] ; 将内存中以r2为起始地址的连续的4字节读取到r3寄存器 ; 单寄存器操作索引方式 ; 前索引 ; mov r1, #0xFFFFFFFF ; mov r2, #0x40000000 ; str r1, [r2, #4] ; 将r1的值存储到r2+4地址 ; 后索引 ; str r1, [r2], #4 ; 将r1的值存储到r2地址,然后r2=r2+4 ; 自动索引 ; str r1, [r2, #8]! ; 将r1的值存储到r2+48地址, 然后r2=r2+8 ; 三种索引方式同样适用于ldr ; 批量寄存器操作 ; mov r1, #1 ; mov r2, #2 ; mov r3, #3 ; mov r4, #4 ; mov r5, #5 ; mov r11,#0x40000000 ; stm r11, {r1-r5} ; 将r1-r5寄存器的值存储到内存以r11为起始地址的20个字节 ; stm r11, {r1,r3,r5} ; 如果寄存器列表中的寄存器编号不连续 使用逗号隔开 ; stm r11!, {r1-r5} ; 自动索引适用于批量寄存器操作 ; stm r11, {r2,r5,r1,r4,r3} ; 不管寄存器列表顺序如何,永远是小编号的寄存器对应低地址 ; ldm r11, {r6-r10} ; 将内存中r11为起始地址的20个字节读取到r6-r10寄存器 ;批量寄存器操作中地址的增长方式 ;mov r1, #1 ;mov r2, #2 ;mov r3, #3 ;mov r4, #4 ;mov r5, #5 ;mov r11,#0x40000020 ; stmia r11!, {r1-r5} ; 先存储数据 后增长地址 ; stmib r11!, {r1-r5} ; 先增长地址 后存储数据 ; stmda r11!, {r1-r5} ; 先存储数据 后递减地址 ; stmdb r11!, {r1-r5} ; 先递减地址 后存储数据 ;增栈:每次压栈后栈指针向高地址方向增长 ;减栈:每次压栈后栈指针向低地址方向增长 ;满栈:栈指针指向的是最后一次压入到栈中的数据 所以再压栈的时候需要先移动栈指针后压栈 ;空栈:栈指针指向的是最后一次压入到栈中的数据相邻的内存空间 所以再压栈的时候可以直接先压栈再移动栈指针 ;所以栈可以分为满增(FA) 满减(FD) 空增(EA) 空减(ED) 四类 ;习惯上我们使用满减栈 ;stmfd r11!, {r1-r5} ;ldmfd r11!, {r6-r10} ;模拟子程序调用过程 ; 初始化栈 ;MOV SP, #0x40000020 ;MAIN ;MOV R1, #3 ;MOV R2, #5 ;BL FUNC ;ADD R3, R1, R2 ;B STOP;FUNC ;压栈保护现场 ;STMFD SP!, {R1,R2} ;MOV R1, #10 ;MOV R2, #20 ;SUB R3, R2, R1 ;出栈恢复现场 ;LDMFD SP!, {R1,R2} ;MOV PC, LR;STOP ;B STOP ;优化 ;初始化栈 ;MOV SP, #0x40000020 ;MAIN ;MOV R1, #3 ;MOV R2, #5 ;BL FUNC ;ADD R3, R1, R2 ;B STOP;FUNC ;压栈保护现场 ;STMFD SP!, {R1,R2,LR} ;MOV R1, #10 ;MOV R2, #20 ;SUB R3, R2, R1 ;出栈恢复现场 ;LDMFD SP!, {R1,R2,PC};STOP ;B STOP ;信号量操作 ;MOV R3, #0x40000000 ;MOV R2, #0x34 ;STR R2, [R3] ;MOV R2, #0x12 ;SWP R1, R2, [R3] ;在内存和CPU寄存器之间进行一次数据交换 ;数据交换过程不会被其他事件打断 常用于操作信号量;/*********************状态寄存器传送指令**********************/ ;1.读CPSR ; MRS R1, CPSR ; R1 = CPSR ;2.改 ; BIC R1, R1, #0x3 ;3,写CPSR ; MSR CPSR_C, R1 ; CPSR = R1 写CPSR的控制域【7:0】;/*********************异常中断产生指令**********************/ ;MRS R1, CPSR ;BIC R1, R1, #0xC3 ;MSR CPSR_C, R1 ;MOV R1, #1 ;MOV R2, #2 ;MOV R3, #3 ;SWI #1 ;MOV R4, #4 ;MOV R5, #5;/*********************协处理器指令**********************/ ;协处理器指令的种类 ;1.协处理器的数据处理指令 ;2.协处理器操作存储器的指令 ;3.ARM处理器对协处理器内部寄存器的读写 ;MRC-从协处理器寄存器移到ARM寄存器 ;MCR-从ARM寄存器移到协处理器寄存器;/*********************伪指令**********************/ ldr r1, =0x12345678 ; r1 = 0x12345678 ldr r2, = 0x12 ; 编译器将其替换成了CPU认识的指令end ; 汇编的结束
阅读全文
0 0
- 【ARM】基本汇编指令——Keil
- arm汇编—str指令
- arm汇编—str指令
- arm汇编—str指令
- arm汇编—str指令
- ARM汇编编程基础之三 —— 基本寻址方式与基本指令
- ARM汇编编程基础之三 —— 基本寻址方式与基本指令
- ARM汇编编程基础之三 —— 基本寻址方式与基本指令
- arm汇编—str,mov等指令
- arm汇编—str,mov等指令
- ARM编程进阶之一 —— ARM汇编伪指令
- ARM编程进阶之一 —— ARM汇编伪指令
- ARM编程进阶之一 —— ARM汇编伪指令
- ARM汇编基础教程——ARM指令集
- ARM编程进阶之一 —— ARM汇编伪指令
- ARM汇编指令——算数和逻辑指令
- arm汇编—ldr加载指令,ldr伪指令
- arm汇编—ldr加载指令,ldr伪指令
- 封装ajax方法(统一处理登录超时异常)
- js截取字符串的常用方法
- 【深度学习】深度学习中常用的激活函数
- python学习(五)----Python标准异常总结
- 用Eclipse建spring mvc项目(图解)
- 【ARM】基本汇编指令——Keil
- Android studio中导入第三方jar、aar及JNI库
- BZOJ3679 数字之积
- spring mvc项目中配置跨域访问过滤器
- 让eclipse 启动速度变快
- 使用crontab分隔日志---1
- 上传多个单文件
- 2017.7.28
- Netty介绍