【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    ; 立即数0xFF0000000xFF循环右移(0x4*2)次得到  所以机器码中【7:0】为0xFF11:8】为0x4    ; 立即数的本质是包含在指令当中的数    ; 在mov指令中给立即数留了12位的存储空间,所以立即数只包含了212次方个    ; 一个立即数是由一个八位的数循环右移偶数次得到的    ; 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     ; 汇编的结束 
原创粉丝点击