暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

arm汇编指令集

囧囧妹 2022-07-11
1001

点击上方蓝字【囧囧妹】一起学习,一起成长!


一、寄存器

arm架构有16个常用寄存器
寄存器作用
解释
R0~R7
通用寄存器(low)
16bits指令
R8~R12
通用寄存器(high)
16bits指令+32bits指令
R13
栈指针sp

MSP:复位默认SP指针

PSP:进入线程后的指针

R14
链接寄存器LC
函数调用时会首先将LC的值存入堆栈,用于保存返回地址,当调用函数完毕后,将LC的值赋给PC
R15
program countner当前执行指令的地址
二、汇编指令语法
    label 
    mnemonic operand1, operand2, ....;comments


    label
    标签用以表示一个参考地址。
    Label放在指令前,Label用以表达指令的地址。
    Label也可以用以表达数据的地址。

    mnemonic
    助记符,助记符是指令的名字,。


    operand
    操作数有,操作可以是立即数,也可以是寄存器,操作数的个数视具体汇编指令。


    ;comment 注释




    eg:
    MOVS R0, #0x12 ; Set R0 = 0x12 (hexadecimal)
    MOVS R1, #’A’ ; Set R1 = ASCII character A


    指令后缀含义:
    后缀
    解释
    S
    需要更新APSR标志
    EQ
    equal
    NE
    not equal
    LT
    小于
    GT
    大于
    .N
    使用16位指令集
    .W
    使用32位指令集
    • 数据拷贝

      MOV  R4, R0 ;            从R0拷贝数据到R4。
      MOV R4,[R0]; 从R0数据指向的地址中读取数据到R4;
      MOVS R4, R0; 从R0拷贝数据到R4,更新APSR。
      MOVS R4, [R0}; 从R0数据指向的地址中拷贝数据到R4,更新APSR。




      eg:


      MOV R4, #0x34; R4的值设置为0x34
      MOVS R4, #0x34;R4的值设置为0x34,更新APSR


      (move word指令)
      MOVW R4, #0x1234;把16位立即数放到寄存器的低16位,高16位清零 。(若执行指令前R4的值为全为F,执行完毕后,R4的值为0x00001234)
      MOVT R4, #0x1234;把16位立即数放到寄存器的高16位,低16位不变。(若执行指令前R4的值为0x00001234,执行完毕后,R4的值为0x12341234)


      MVN R4, R0;对R0按位取反,然后放入R4中。




      MSR CONTROL, R2; 把状态寄存器的值放到通用寄存器中。
      MRS R2, CONTROL;      把通用寄存器的值放到状态寄存器中。
      • 内存访问

        预锁引寻址
        数据的传输的内存地址是寄存器的值与立即数的值的总和。
        这个立即数的值可正可负。
        LDRB R0,[R1,#0x1234]; 从内存地址Ro+0x1234中读取一个byte,然后放入RO寄存器中。
        LDRB R0, [R1,#0x1234]! 从内存地址Ro+0x1234中读取一个byte,然后放入RO寄存器中。同时R1的值更新为R1+0x1234
        Note:指令中!表明指令完成后,地址需要被更新。


        LDRD R0, R1,[R2,#0x5]; 从内存地址中R2+0x5中读取2个bytes,然后放入R0,R1寄存器中。
        STRD R0,R1,[R2,#0x05]; 把R0,R1的值写入内存R2+0x05中


          寄存器寻址
          LDR R0, [R1,R2, LSL #2]; 从内存地址R1 + (R2<<2)中读取一个字到R0中。
          STR R0,[R1,R2]; 把R0的值写入地址R1+R2中。
          LDR R0, R1,#0x05;从内存地址为R1的值的内存中读取数据到R0中,并更新R1 = R1+5.


            连续读/写多个寄存器从一个连续的地址空间内。
            LDM指令 Load multiple registers
            STM指令 Store multiple register
              LDR R4,=0x8000; 设置R4的值为0x8000.
            LDMIA R4, {R0-R3};读取4个words并且把他们依次存取到R0,R1,R2,R3中。
            寄存器组的设置是灵活的;如{R1,R3,R5-R7,R9,R10-R12}.


              堆栈操作:
              PUSH {R0, R4-R7, LC}; push R0,R4,R5,R6,R7进去堆栈
              POP {R2, R3};POP R2,R3从堆栈里。


              通常PUSH与POP指令是成对出现,且寄存器列表是一致的。

              PUSH {R0, R4-R7, LC}; push R0,R4,R5,R6,R7进去堆栈
              POP{R0, R4-R7, PC}; 恢复R4_R7,直接把LC的值赋给PC。


              LC返回的是函数执行的地址,返回的LC会直接赋值给PC,所以可以直接POP LC的值给PC


              • 算术操作

                算数加 addition
                ADD R0, R0, R2 ;R0 = R0 + R2
                ADDS R0, R0, R2 ;R0 = R0 + R2,更新APSR


                ADD RO, R1,#0x5;RO = R0 +5;
                ADDS RO, R1,#0x4‘ RO = R0 +5;更新APSR


                ADC(ADD with carry)
                ADC RO,R1, R2;R0 = R1 + R2 + carry
                ADC R0, #0x3; R0 = R0 + 3 + carry




                算数减 subtraction
                SUB R0, R1, R2; R0 = R1 - R2
                SUB R0, #3; R0 = R0 -3
                SUB R0, R1, #5; R0 = R1 -5


                SBC R0, R1, R2; R0 = R1 - R2 - borrow


                逆向算数减 Reserve subtraction
                RSB R0, R1, R2; R0 = R2 - R1
                RSB R0, R1, #0x55; R0 = 0x55 - R1



                算数乘 multiply
                MUL RO, R1, R2 ; R0 = R1 * R2


                算数除法 divide
                UDIV R0, R1, R2; R0 = R1/R2 (unsigned)
                SDIV R0, R1, R2; R0 = R1/R2 (Signed)




                • 逻辑操作

                  逻辑按位与 & and
                  AND R0, R1; R0 = R0 & R1
                  AND R0, R1, R2; R0 = R1 & R2
                  AND R0, R1, #3; R0 = R1 & 3


                  按位或 | or
                  ORR R0, R1; R0 = R0 | R1
                  ORR R0, R1, R2; R0 = R1 | R2
                  ORR R0, R1, #3 R0 = R1 | 3


                  按位清除 bit clear
                  BIC R0, R1;R0 = R0 & ~R1
                  BIC R0, R1, R2; R0 = R1 & ~R2
                  BIC R0, R1, #3; R0 = R1 &~3


                  按位异或 bitwise exclusive or
                  EOR R0,R1; R0 = R0 ^ R1;


                  • 移位操作

                    算术右移  Arithmetic shift right
                    ASR R0, R1; R0 = R0 >> R1
                    ASR R0, R1, R2 R0 = R1 >> R2
                    ASR R0, R1, #0x3 R0 = R1 >> 0x3


                    逻辑右移动 Logic shift right
                    LSR R0, R1; R0 = R0 >> R1
                    LSR R0, R1, R2; R0 = R1 >> R2
                    LSR R0, R1, #0x3 R0 = R1 >> 3


                    逻辑左移动 Logic Shift Left
                    LSL R0, R1;R0 = R0 << R1
                    LSL R0, R1, R2; R0 = R1 << R2
                    LSL R0, R1, #0x3 R0 = R1 << 0x03


                    • 位操作

                      6.1 BFC(Bit filed cler)
                      LDR R0, = 0x1234FFFF
                      BFC R0,#4,#8; #4代表其实的bit,#8代表c户里的bit长度;指令完毕后 R0 = 0x1234F00F


                      6.2 BFI(Bit filed insert)
                      命令格式: BFI R0, R1, #lsb, #width
                      该命令会从R1中拷贝width指定的bit到R0的LSB指定的位置。


                      LDR R0, = 0x12345678
                      LDR R1, = 0x3355AACC
                      BFI R0, R1, #8, #16;命令执行完毕R0 = 0x335678CC;


                      • 比较与测试

                        7.1 CMP - compare
                        CMP R0, R1; 计算R0-R1,更新APSR
                        CMP R0,#0x5;计算R0-3,更新APSR


                        7.2 CMN- Compare negtive
                        CMP R0, R1; 计算R0+R1;更新APSR
                        CMP R0,#0x3;计算R0+3;更新APSR


                        7.3 TST-bitwise AND
                        TST R0, R1;
                        TST R0,#0x3;
                        7.4 TE!-bitwise XOR
                        TEQ R0, R1;
                        TEQ R0,#0x3;


                        • 程序流程控制

                          8.1 函数调用
                          BL Label;Branch and link instruction-跳转到Label指定的地址并且保存返回值在LR中
                          函数调用时,如果函数有三个参数,会把参数依次放进R0,R1,R2中,如果函数有返回值会把返回值放进R0中。


                          eg:


                          8.2 条件分支
                          B<Conditon> Label;跳转到Label如果满足条件。


                          8.3 用于循环的 指令
                          CBZ Compare and Branch if Zero
                          CBNZ Compare and branch if not Zero

                          8.4 IT If-Then 指令
                          待更新




                          觉得不错,点击“分享”,“赞”,“在看”传播给更多热爱嵌入式的小伙伴吧!

                          文章转载自囧囧妹,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                          评论