【ARM】基本汇编指令——Keil

    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     ; 汇编的结束 

你可能感兴趣的:(嵌入式,arm,基本,汇编,指令,keil)