STM 常用汇编指令

合集下载

stm32汇编教程

stm32汇编教程

stm32汇编教程STM32是一款非常流行的嵌入式微控制器系列,广泛应用于各种不同的嵌入式系统中。

了解STM32的汇编语言编程对于理解和优化嵌入式系统非常重要。

在本篇文章中,我将向大家介绍STM32汇编教程的基本知识和技巧。

首先,让我们了解一下什么是汇编语言。

汇编语言是一种低级编程语言,它使用特定的符号和指令来告诉计算机执行特定的指令和操作。

汇编语言的代码直接翻译成机器码,可以直接在处理器上执行。

相对于高级语言,汇编语言更加底层和直接。

在开始学习STM32汇编之前,我们首先需要了解汇编语言的基本概念和语法。

汇编语言由一系列的指令组成,每条指令都对应着底层的机器操作。

指令由操作码和操作数组成,操作码用于指定执行的操作,操作数则提供了指令所需要的数据。

在STM32汇编教程中,我们将介绍一些常用的指令和操作,例如加载/存储指令、算术指令、逻辑指令等。

我们将学习如何使用这些指令来实现各种功能,例如对寄存器和内存的读写、数学运算、逻辑运算等。

我们还将介绍一些特殊的指令,例如中断处理和异常处理。

除了指令和操作,STM32汇编教程还将介绍一些常用的编程技巧和优化方法。

例如,我们将学习如何优化循环和条件语句,如何使用位操作和移位操作提高性能,以及如何利用寄存器和内存的特性来提高程序效率。

在学习STM32汇编教程时,我们将结合实际的例子和案例来演示每个概念和技巧的使用。

我们将使用Keil编译器和开发环境来编写和调试汇编代码。

我们还将介绍如何使用调试工具来分析和优化汇编代码的性能和效率。

总结一下,本篇文章向大家介绍了STM32汇编教程的基本知识和技巧。

了解STM32汇编语言编程对于嵌入式系统的开发和优化非常重要。

通过学习STM32汇编教程,我们可以掌握汇编语言的基本概念和语法,学习常用的指令和操作,以及掌握一些编程技巧和优化方法。

希望这篇文章对大家学习STM32汇编有所帮助!。

常见汇编语言指令解释

常见汇编语言指令解释

常见汇编语言指令解释:1.Rn 表示R0~R7中的一个2.#data 表示8位的数值 00H~FFH3.direct 表示8位的地址 00H~FFH4.#data16 16位立即数5.@Ri 表示寄存器间接寻址只能是R0或者R16.@DPTR 表示数据指针间接寻址,用于外部64k的RAM/ROM寻址7.bit 表示位地址8.$ 表示当前地址寄存器寻址 MOV A,R1 将R1中的数值赋予A直接寻址 MOV A,3AH 将地址3AH中的数值赋予A立即寻址 MOV A,#3AH 将3AH数值赋予Amov dptr,#1828h寄存器间址 MOV A,@Ri 将 Ri中地址的数值赋予A, Ri或是R0或是R1MOV A,@DPTR变址寻址 MOVC A,@A+DPTR 以A中的数值为地址偏移量进行查表;变址寻址区是程序存储器ROM,而不是数据存储器RAM相对寻址 AJMP MAIN 跳转到行号为MAIN处位寻址 MOV C,7FH 将位地址7FH的数值赋予CMOV C,2FH.7;MOV C,ACC.7MOV A,#3AH 数据传输、赋值命令PUSH direct 将direct为地址的数值压入堆栈中POP direct 将direct为地址的数值弹出堆栈XCH A,direct 将direct中的数值与A进行交换ADD A,direct 将direct中的数值与A中的数值相加INC direct 将direct中的数值加1SUBB A,direct 将A中的数值减去direct中的数值和Cy值,并保存在A中,如果想使用不带Cy减法,可以在运算前对Cy清零 CLR CDEC direct 将direct中的数值减1DA A 用于对BCD码加减法后进行10进制调整MUL AB 将A和B相乘,并把高八位放在B中,低八位放在A中DIV AB 将A和B相除,并把商的整数部分放在A中,余数放在B中ANL A,direct 将A与direct中的数值进行与运算,结果保留在A中(与运算规律:有0出0,全1出1)ORL A,direct 将A与direct中的数值进行或运算,结果保留在A中(或运算规律:有1出1,全0出0)XRL A,direct 将A与direct中的数值进行异或运算,结果保留在A中(异或运算规律:全0出0,全1出0,01、10出1)CLR A 对A清零CPL A 对A取反RL A 对A中数左移RR A 对A中数右移RLC A 对A中数带Cy左移RRC A 对A中数带Cy右移SWAP A 对A中的数高4位低4位互相交换LJMP 长跳转指令,64K地址范围AJMP 短跳转指令,2K地址范围JZ rel 如果A为0就跳转到rel行号处JNZ rel 如果A不为0就跳转到rel行号处CJNE A,#data,rel 如果A不等于data就跳转到rel行号处DJNZ R1,rel 如果R1减1后不为0就跳转到rel行号处ACALL rel 调用rel子程序,2K地址以内LCALL rel 调用rel子程序,64K地址以内RET 子程序返回指令RETI 中断程序返回指令NOP 空操作指令MOV C,bit 将位地址bit中的值赋予CCLR bit 将bit位地址清0SETB bit 将bit位地址置1CPL bit 将bit位地址取反ANL C,bit 将地址bit中的值和C做与运算,结果存放在C中ORL C,bit 将地址bit中的值和C做或运算,结果存放在C中JC rel 如果Cy为1,就跳转到rel行号处JNC rel 如果Cy为0,就跳转到rel行号处JB bit,rel ;若BIT=1则转移JNB bit,rel ;若BIT=0则转移JBC bit,reL ;若BIT=1则转移,且BIT置11 加法指令:ADD A,Rn ;ADD A,direct ; ADD A,@Ri ;ADD A,#DATA2 带CY的加法指令:ADDC A,Rn ;ADDC A,direct ; ADDC A,@Ri ;ADDC A,#DATA3 加一指令:INC A ;INC Rn ; INC direct ; INC @Ri ;INC DPTR4 减法指令:SUBB A,Rn ;SUBB A,direct ; SUBB A,@Ri ;SUBB A,#data5 减一指令: DEC A ;DEC Rn ;DEC direct ;DEC @Ri6 十进制调整指令:DA A7 乘法和除法指令:MUL AB ;乘积高八位放在B中,低八位放在A中DIV AB ;商的整数放在A中,余数放在B中8 逻辑异或: XRL A,Rn。

常用汇编指令

常用汇编指令

常用汇编指令汇编语言是一种低级机器语言的抽象表示,通过使用汇编指令可以编写出与硬件相关的程序。

在计算机科学领域中,汇编指令是非常重要的,是理解计算机底层原理和实现的关键。

本文将介绍一些常用的汇编指令,以帮助读者更好地理解和应用这些指令。

一、数据传输指令1. MOV指令:MOV指令用于将数据从一个位置复制到另一个位置。

例如,MOV AX, BX将寄存器BX的内容复制到AX中。

2. LEA指令:LEA指令用于将内存地址加载到寄存器中。

例如,LEA BX, [SI+10]将[S1+10]的内存地址加载到寄存器BX中。

3. PUSH指令:PUSH指令用于将数据压入栈中。

例如,PUSH AX将AX中的数据压入栈中。

4. POP指令:POP指令用于从栈中弹出数据。

例如,POP BX将栈中的数据弹出到BX中。

二、算术运算指令1. ADD指令:ADD指令用于将两个操作数相加,并将结果存储在目标操作数中。

例如,ADD AX, BX将BX的值加到AX中。

2. SUB指令:SUB指令用于将源操作数的值从目标操作数中减去,并将结果存储在目标操作数中。

例如,SUB AX, BX从AX中减去BX的值。

3. MUL指令:MUL指令用于将源操作数与累加器中的值相乘,并将结果存储在累加器中。

例如,MUL BX将累加器的值与BX相乘。

4. DIV指令:DIV指令用于将累加器的值除以源操作数,并将商存储在累加器中,余数存储在另一个寄存器中。

例如,DIV BX将累加器的值除以BX。

三、逻辑运算指令1. AND指令:AND指令用于对两个操作数进行逻辑与运算,并将结果存储在目标操作数中。

例如,AND AX, BX将AX与BX进行逻辑与操作。

2. OR指令:OR指令用于对两个操作数进行逻辑或运算,并将结果存储在目标操作数中。

例如,OR AX, BX将AX与BX进行逻辑或操作。

3. NOT指令:NOT指令用于对操作数进行逻辑非运算,并将结果存储在目标操作数中。

汇编的基本常用指令

汇编的基本常用指令

汇编的基本常用指令汇编语言是一种底层的程序设计语言,主要用于编写机器码指令。

以下是一些常用的汇编指令:1. MOV:将数据从一个位置复制到另一个位置。

2. ADD:将两个操作数相加,并将结果存储在目的操作数中。

3. SUB:将第二个操作数从第一个操作数中减去,并将结果存储在目的操作数中。

4. INC:将一个操作数的值增加1。

5. DEC:将一个操作数的值减少1。

6. CMP:比较两个操作数的值,并将结果影响到标志寄存器中。

7. JMP:无条件跳转到指定的代码位置。

8. JZ / JE:当指定的条件成立时,跳转到指定的代码位置(零标志或相等标志)。

9. JNZ / JNE:当指定的条件不成立时,跳转到指定的代码位置(非零标志或不相等标志)。

10. JL / JB:当源操作数小于目的操作数时,跳转到指定的代码位置(小于标志或借位标志)。

11. JG / JA:当源操作数大于目的操作数时,跳转到指定的代码位置(大于标志或进位标志)。

12. CALL:调用一个子程序或函数。

13. RET:返回子程序或函数的调用处。

14. NOP:空操作,用于占位或调整程序代码的位置。

15. HLT:停止运行程序,将CPU置于停机状态。

这里只列举了一些基本的汇编指令,实际上汇编语言有更多更复杂的指令,具体使用哪些指令取决于所使用的汇编语言和目标处理器的指令集架构。

继续列举一些常用的汇编指令:16. AND:将两个操作数进行按位与运算,并将结果存储在目的操作数中。

17. OR:将两个操作数进行按位或运算,并将结果存储在目的操作数中。

18. XOR:将两个操作数进行按位异或运算,并将结果存储在目的操作数中。

19. NOT:对一个操作数的每一位进行取反操作。

20. SHL / SAL:将一个操作数的每一位向左移动指定的位数。

对于无符号数,使用SHL指令;对于带符号数,使用SAL指令。

21. SHR:将一个操作数的每一位向右移动指定的位数,高位空出的位使用0填充。

单片机汇编指令集合(中英指令翻译)

单片机汇编指令集合(中英指令翻译)

一、数据传送类指令(8种助记符)MOV(英文为Move):对内部数据寄存器RAM和特殊功能寄存器SFR的数据进行传送;P55PUSH (Push onto Stack) 入栈;PUSH directPOP (Pop from Stack) 出栈;POP directXCH (Exchange) 字节交换;XCH A,源/@RiXCHD (Exchange low-order Digit) 低半字节交换;同上SWAP (Swap) 低4位与高4位交换;SWAP A MOVC(Move Code)读取程序存储器数据表格的数据传送;MOVC A,@A+DPTR/PC MOVX (Move External RAM) 对外部RAM的数据传送;MOVX @DPTR,A MOVX A,@DPTR/@Ri MOVX @Ri,A二、算术运算类指令(8种助记符)ADD(Addition) 加法;ADDC(Add with Carry) 带进位加法;INC(Increment) 加1;INC A/Rn/direct/@Ri/源/DPTRDA(Decimal Adjust) 十进制调整;SUBB(Subtract with Borrow) 带借位减法;DEC(Decrement) 减1;DEC A/Rn/direct/@Ri/源MUL(Multiplication、Multiply) 乘法;MUL AB 高B,低A。

Cy=0 大于256,OV=1 DIV(Division、Divide) 除法;DIV AB 商A,余B。

Cy=0 OV=B(同上)三、逻辑运算类指令(9种助记符)CLR(Clear) 清零;CLR ACPL(Complement) 取反;CPL ARL(Rotate left) 循环左移;(同上)RLC(Rotate Left throught the Carry flag) 带进位循环左移;(同上)RR(Rotate Right) 循环右移;(同上)RRC (Rotate Right throught the Carry flag) 带进位循环右移;(同上)ANL(AND Logic) 逻辑与;ANL A,#data/Rn/direct/@Ri ANL direct,A/#dataORL(OR Logic) 逻辑或;ORL A,#data/Rn/direct/@Ri ANL direct,A/#dataXRL(Exclusive-OR Logic) 逻辑异或;(同上)四、位操作指令(6种助记符)MOV 位数据传送指令;MOV C,bit MOV bit,CCLR 位清零;C bitSETB(Set Bit)位置1;C bitCPL位取反;(同上)ANL位逻辑运算指令;ANL C,bit//bitORL位逻辑或运算指令;(同上)五、控制转移类指令(18种助记符)AJMP(Absolute Jump)绝对转移;AJMP addr11/ LABELLJMP(Long Jump)长转移;(同上)SJMP(Short Jump)短转移;SJMP rel/ LABELJMP间接转移指令; JMP @A+DPTRJZ (Jump if Zero)结果为0则转移;JZ rel/ LABELJNZ (Jump if Not Zero) 结果不为0则转移;(同上)CJNE (Compare Jump if Not Equal)比较不相等则转移;CJNE A,direct,rel/ LABEL CJNE A/Rn/@Ri,#data,rel/ LABELJC (Jump if the Carry flag is set)有进位则转移;JC rel/ LABELJNC (Jump if Not Carry)无进位则转移;(同上)JB (Jump if the Bit is set)位为1则转移;JB bit, rel/ LABELJNB (Jump if the Bit is Not set) 位为0则转移;(同上)JBC(Jump if the Bit is set and Clear the bit) 为1则转移,并清除该位;DJNZ (Decrement Jump if Not Zero)减1后不为0则转移;DJNZ Rn,rel/ LABEL DJNZ direct,rel/ LABELLCALL(Long subroutine Call)子程序长16调用;LCALL addr16/ SUBROUTINEACALL(Absolute subroutine Call)子程序绝对11调用;(同上)RET(Return from subroutine)子程序返回;RETI(Return from Interruption)中断返回;NOP (No Operation) 空操作;8种常用伪指令1.ORG 16位地址;此指令用在原程序或数据块的开始,指明此语句后面目标程序或数据块存放的起始地址。

嵌入式系统原理与应用常用Cortex-M汇编指令

嵌入式系统原理与应用常用Cortex-M汇编指令

常用Cortex-M汇编指令附录1列出了常用的Cortex-M汇编指令,包括:数据操作指令、转移指令、存储器数据传送指令、异常及其他指令等,上述每一类指令都按照16位指令和32位指令分别讲解。

1. 数据操作指令表1.1 16位数据操作指令SUB <Rd>, <Rn>, <Rm> Rd= Rn-RmSUB(减法)SUB SP, #<imm7> * 4 SP-= imm7*4TST(测试)TST <Rn>, <Rm> 执行Rn & Rm,并根据结果更新标志位REV <Rd>, <Rn> Rd=Rn字内的字节顺序反转REV(反转)REVH/REV16(反转)REV16 <Rd>, <Rn> Rd=Rn两个半字内的字节顺序反转SXTB(字节提取扩展符号位)SXTB <Rd>, <Rm> 从寄存器Rm中提取字节[7:0],传送到寄存器Rd中,并用符号位扩展到32位SXTH(半字提取扩展符号位)SXTH <Rd>, <Rm> 从寄存器Rm中提取半字[15:0],传送到寄存器Rd中,并用符号位扩展到32位UXTB(字节提取扩展零位)UXTB <Rd>, <Rm> 从寄存器Rm中提取字节[7:0],传送到寄存器Rd中,并用零位扩展到32位UXTH(半字提取扩展零位)UXTH <Rd>, <Rm> 从寄存器Rm中提取半字[15:0],传送到寄存器Rd中,并用零位扩展到32位表1.2 32位数据操作指令操作,Rm 的值不变LSL (逻辑左移) LSL{S}.W <Rd>, <Rn>, <Rm> Rd= Rn<<Rm LSR (逻辑右移) LSR{S}.W <Rd>, <Rn>, <Rm> Rd= Rn>>Rm MLA (乘加) MLA.W <Rd>, <Rn>, <Rm>, <Racc> Rd= Racc+Rn*Rm MLS (乘减) MLS.W <Rd>, <Rn>, <Rm>, <Racc> Rd= Racc-Rn*RmMOVW.W <Rd>, #<imm16> 将16位立即数传送到Rd 的低半字中,并把高半字清零MOVW (加载) MOVT (加载) MOVT.W <Rd>, #<imm16> 将16位立即数传送到Rd 的高半字中,Rd 的低半字不受影响 MUL (乘法) MUL.W <Rd>, <Rn>, <Rm> Rd= Rn*Rm ORR{S}.W <Rd>, <Rn>, #<imm12 Rd= Rn | imm12ORR{S}.W <Rd>, <Rn>, <Rm>{, <shift>} 先移位Rm ,然后Rd= Rn | 新Rm ORN{S}.W <Rd>, <Rn>, #<immed12) Rd= Rn | ~imm12ORR (按位或) ORN (按位或) ORN{S}.W <Rd>, <Rn>, <Rm>{, <shift>} 先移位Rm ,然后Rd= Rn | ~新Rm RBIT (位反转) RBIT.W <Rd>, <Rm> Rd=Rm 按位反转后的值 REV.W <Rd>, <Rm> Rd=Rm 字内的字节顺序反转 REV16.W <Rd>, <Rn> Rd=Rn 每个半字内的字节顺序反转 REV (反转)REVH/REV (16反转) REVSH (反转) REVSH.W <Rd>, <Rn> Rd=Rn 低半字内的字节反转后再符号扩展ROR (循环右移) ROR{S}.W <Rd>, <Rn>, <Rm> Rd= Rn 循环右移Rm 位 RRX (带进位循环右移一位)RRX.W Rd, RnRd = (Rn>>1)+(C<<31)SBFX (带符号位段提取)SBFX.W <Rd>, <Rn>, #<lsb>, #<width> 抽取Rn 中以lsb 位为最低有效位,共width 宽度的位段,并带符号扩展到Rd 中 SDIV (带符号除法) SDIV<c><Rd>,<Rn>,<Rm>Rd= Rn/RmSMLAL (带符号64位乘加)SMLAL.W <RdLo>, <RdHi>, <Rn>, <Rm> RdHi:RdLo+= Rn*Rm SMULL 带符号64位乘法SMULL.W <RdLo>, <RdHi>, <Rn>, <Rm> RdHi:RdLo= Rn*RmSSAT (带符号数饱和运算) SSAT<C><Rd>, #<imm>, <Rn>{, <shift>} 先移位Rn ,再把Rn 的低imm 位执行带符号饱和操作,并把结果带符号扩展后写到RdSBC{S}.W <Rd>, <Rn>, #<imm12>Rd= Rn- imm12-C SUB{S}.W <Rd>, <Rn>, #<imm12> Rd= Rn-imm12SUB{S}.W <Rd>, <Rn>, <Rm>{, <shift>} 先移位Rm ,Rd= Rn-新Rm SBC (减法) SUB (减法) SUBW (减法) SUBW.W <Rd>, <Rn>, #<imm12> Rd= Rn-imm12SXTB (带符号扩展) SXTH (带符号扩展)SXTB.W <Rd>, <Rm>{,ROR #<imm>}先循环移位Rm ,然后取出Rm 的低8位,带符号扩展到32位,并存储到RdSXTH.W <Rd>, <Rm>{,ROR #<imm>}先循环移位Rm ,然后取出Rm 的低16位,带符号扩展到32位,并存储到RdTEQ.W <Rn>, #<imm12>Rn 与imm12按位异或,并根据结果更新标志位TEQ (按位异或)TEQ.W <Rn>, <Rm>{, <shift>} 先移位Rm ,然后 Rn 与Rm 按位异或,并根据结果更新标志位 TST.W <Rn>, #<imm12)>Rn 与imm12按位与,并根据结果更新标志位TST (按位与)TST.W <Rn>, <Rm>{, <shift>}先移位Rm ,然后 Rn 与Rm 按位与,并根据结果更新标志位UBFX (抽取) UBFX.W <Rd>, <Rn>, #<lsb>, #<width> 抽取Rn 中以lsb 位为最低有效位,共width 宽度的位段,并无符号扩展到Rd 中UDIV (无符号除法) UDIV<c><Rd>,<Rn>,<Rm>Rd= Rn/RmUMLAL (无符号64位乘加)UMLAL.W <RdLo>, <RdHi>, <Rn>, <Rm> RdHi:RdLo+= Rn*Rm UMULL (无符号64位乘法)UMULL.W <RdLo>, <RdHi>, <Rn>, <Rm> RdHi:RdLo= Rn*RmUSAT <c><Rd>, #<imm>, <Rn>{, <shift>} 先移位Rn ,再把Rn 的低imm 位执行带符号饱和操作,将结果无符号扩展后写到Rd 中UXTB.W <Rd>, <Rm>{, <rotation>}先循环移位Rm ,然后取出Rm 的低8位,无符号扩展到32位,并存储到RdUSAT (无符号扩展) UXTB (无符号扩展) UXTH (无符号扩展)UXTH.W <Rd>, <Rm>{, <rotation>}先循环移位Rm ,然后取出Rm 的低16位,无符号扩展到32位,并存储到Rd2. 转移指令表1.3 16位转移指令CBZ <Rn>, <label> 比较结果为零时跳转CBZ (比较转移)CBNZ(比较转移)CBNZ <Rn>, <label> 比较结果不为零时分支IT<cond> 以下面一条指令为条件IT<x><cond> 以下面两条指令为条件IT(条件转移)IT<x><y><cond> 以下面三条指令为条件IT<x><y><z><cond> 以下面四条指令为条件表1.4 32位转移指令3. 存储器数据传送指令表1.5 16位存储器数据传送指令STRB <Rd>, [<Rn>, #< offset5>] *( (U8*) (Rn+offset5) ) = (U8)Rd STRB(将寄存器中的低字节存储到存储器中)STRB <Rd>, [<Rn>, <Rm>] *( (U8*) (Rn+Rm) ) = (U8)Rd LDMIA(多字加载)LDMIA <Rn>!, <register> 多个连续的存储器字加载STMIA(多字存储)STMIA <Rn>!, <registers> 将多个寄存器字保存到连续的存储单元中,首地址由Rn给出,每保存完一个Rn+4PUSH <registers> 若干寄存器压栈PUSH(压栈)PUSH <registers, LR> 若干寄存器和LR压栈POP <registers> 若干寄存器出栈POP(出栈)PUSH <registers, PC> 若干寄存器和PC出栈表1.6 32位存储器数据传送指令中LDRSH.W <Rxf>, [PC, #+/–< offset12>] 加载PC+/–offset12地址处的半字,并带符号扩展到Rxf 中LDRSB.W <Rxf>, [<Rn>, #< offset12>]加载Rn+ offset12地址处的字节,并带符号扩展到Rxf 中LDRSB.W <Rxf>. [<Rn>], #+/-< offset8>加载Rn 地址处的字节,并带符号扩展到Rxf 中,然后Rn+/-= offset8LDRSB.W <Rxf>, [<Rn>, #<+/–< offset8>]!先Rn+/-= offset8,再加载新Rn 地址处的字节,并带符号扩展到Rxf 中LDRSB.W <Rxf>, [<Rn>, <Rm>{, LSL#<shift>}]先把Rm 按要求左移0、1、2、3位,再加载Rn+新Rm 地址处的字节,并带符号扩展到Rxf 中 LDRSB (加载字节并扩展符号位)LDRSB.W <Rxf>, [PC, #+/–< offset12>]加载PC+/- offset12地址处的字节,并带符号扩展到Rxf 中LDRD.W <Rxf>, <Rxf2>, [<Rn>, #+/–<offset8>*4]{!}读取Rn 地址加上8位偏移量乘以4处的双字到Rxf(低32位), Rxf2(高32位),前索引。

汇编常用指令

汇编常用指令

汇编常用指令1. 前言汇编语言是一种低级别的计算机语言,它是由一些指令组成的。

指令是一条计算机执行的命令,从基本上讲,这些指令代表着标准的操作,例如加、减、乘、除、移位和比较等。

汇编语言可以通过编写程序来控制一个计算机的行为,这些程序通常被称为汇编程序。

本文将介绍汇编语言中一些常用的指令。

2. 数据传送指令数据传送指令是汇编语言中最基本的指令之一,它主要用来将数据从一个位置传送到另一个位置。

在汇编语言中,数据传送指令通常使用MOV语句来实现。

下面是一些常用的数据传送指令:- MOV AX, BX:将BX中存储的数据传送到AX中。

- MOV AX, [BX]:将BX中存储的地址所指向的数据传送到AX中。

- MOV [BX], AX:将AX中存储的数据传送到BX所指向的地址中。

3. 算术运算指令算术运算指令主要用来执行各种数学运算,例如加法、减法、乘法和除法等操作。

下面是一些常用的算术运算指令:- ADD AX, BX:将BX中存储的数据与AX中存储的数据相加,并将结果存储在AX中。

- SUB AX, BX:将BX中存储的数据从AX中存储的数据中减去,并将结果存储在AX中。

- MUL BX:将AX中存储的数据与BX中存储的数据相乘,并将结果存储在AX中。

- DIV BX:将AX中存储的数据除以BX中存储的数据,并将结果存储在AX和DX中。

4. 位运算指令位运算是一种在二进制数字级别上的运算,它可以执行各种位操作,例如AND、OR、XOR和NOT等操作。

下面是一些常用的位运算指令:- AND AX, BX:将BX中存储的数据与AX中存储的数据按位进行AND运算,并将结果存储在AX中。

- OR AX, BX:将BX中存储的数据与AX中存储的数据按位进行OR 运算,并将结果存储在AX中。

- XOR AX, BX:将BX中存储的数据与AX中存储的数据按位进行XOR运算,并将结果存储在AX中。

- NOT AX:将AX中存储的数据按位进行取反操作。

简单的STM32汇编程序—闪烁LED

简单的STM32汇编程序—闪烁LED

简单的STM32汇编程序—闪烁LED要移植操作系统,汇编是道不得不跨过去的坎。

所以承接上篇的思路,我准备⽤汇编写⼀个简单的闪烁LED灯的程式。

以此练习汇编,为操作系统做准备。

第⼀步,还是和上篇⼀样,建⽴⼀个空的⽂件夹。

第⼆步,因为是要⽤汇编来写程式,所以不需要启动代码,这⾥选择否。

第三步,建⽴⼀个.s⽂件,并把⽂件添加到⼯程中。

第四步,在LED.s⽂件中添加如下代码。

LED0 EQU 0x422101a0RCC_APB2ENR EQU 0x40021018GPIOA_CRH EQU 0x40010804Stack_Size EQU 0x00000400AREA STACK, NOINIT, READWRITE, ALIGN=3Stack_Mem SPACE Stack_Size__initial_spAREA RESET, DATA, READONLY__Vectors DCD __initial_sp ; Top of StackDCD Reset_Handler ; Reset HandlerAREA |.text|, CODE, READONLYTHUMBREQUIRE8PRESERVE8ENTRYReset_HandlerBL LED_InitMainLoop BL LED_ONBL DelayBL LED_OFFBL DelayB MainLoopLED_InitPUSH {R0,R1, LR}LDR R0,=RCC_APB2ENRORR R0,R0,#0x04LDR R1,=RCC_APB2ENRSTR R0,[R1]LDR R0,=GPIOA_CRHBIC R0,R0,#0x0FLDR R1,=GPIOA_CRHSTR R0,[R1]LDR R0,=GPIOA_CRHORR R0,R0,#0x03LDR R1,=GPIOA_CRHSTR R0,[R1]MOV R0,#1LDR R1,=LED0STR R0,[R1]POP {R0,R1,PC}LED_ONPUSH {R0,R1, LR}MOV R0,#0LDR R1,=LED0STR R0,[R1]POP {R0,R1,PC}LED_OFFPUSH {R0,R1, LR}MOV R0,#1LDR R1,=LED0STR R0,[R1]POP {R0,R1,PC}DelayPUSH {R0,R1, LR}MOVS R0,#0MOVS R1,#0MOVS R2,#0DelayLoop0ADDS R0,R0,#1CMP R0,#330BCC DelayLoop0MOVS R0,#0ADDS R1,R1,#1CMP R1,#330BCC DelayLoop0MOVS R0,#0MOVS R1,#0ADDS R2,R2,#1CMP R2,#15BCC DelayLoop0POP {R0,R1,PC}; NOPEND///////////////////////////////////////////////////////代码的简单讲解1,预定义LED0 EQU 0x422101a0 ;PA8的Bit-Bond地址。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

BX Rm 带状态切换跳转指令 PC<----Rm ,切换状态(Rm[0]=1,thumb,Rm[0]=0,ARM)
%F2 表示跳转到当前指令后面的标号 2 处
%B0 表示跳转到当前指令前面的标号 0 处
[ ----- IF
;
----- ENDIF
| ----- ELSE ;
]
IF logical expression
存器,或一个立即数。该指令使用进位标志来表示借位,这样就可以做大于 32 位的减法。
注意不要忘记设置 S 后缀来更改进位标志。该指令可用于有符号数或无符号数的减法运算。
指令示例:
SUBS R0,R1,R2
; R0 = R1 - R2 - !C,并根据结果设置 CPSR 的进位标志

(10)BX 带状态切换的跳转指令
含义:(1)SP-->R8 SP=SP+4
(2)SP=SP+4 (3)SP-->R9 (4)SP=SP+4 (5)SP-->PC (6)
ldmia sp!
{ r0-r7 pc }^
^ 表示将 spsr 的值赋给 cpsr
B lable
跳转指令 PC<---lable
BL lable 带链接跳转指令
LR<----PC-4, PC<---lable
连续存储单元的值传送到 R1~R4。
(9)SBC 指令的格式为:
SBC{条件}{S} 目的寄存器,操作数 1,操作数 2
SBC 指令用于把操作数 1 减去操作数 2,再减去 CPSR 中的 C 条件标志位的反码,并将结果
存放到目的寄存器中。操作数 1 应是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄
LDR R0,[R1,R2] ! ;将存储器地址为 R1+R2 的字数据读入寄存器 R0,并将新地址 R1
+R2 写入 R1
LDR R0,[R1,#8] ! ;将存储器地址为 R1+8 的字数据读入寄存器 R0,并将新地址 R1
+8 写入 R1。
LDR R0,[R1],R2
;将存储器地址为 R1 的字数据读入寄存器 R0,并将新地址 R1
(8)采用多寄存器寻址方式,一条指令可以完成多个寄存器值的传送。这种寻址方式可以
用一条指令完成传送最多 16 个通用寄存器的值。以下指令:
LDMIA
R0,{R1,R2,R3,R4}
;R1←[R0]
;R2←[R0
+4]
;R3←[R0+8]
;R4←[R0+
12]
该指令的后缀 IA 表示在每次执行完加载/存储操作后,R0 按字长度增加,因此,指令可将
MSR{<cond>} CPSR_f | SPSR_f,#<32-bit immediate> MSR{<cond>} CPSR_<field> | SPSR_<field>,Rm msr cpsr, r0 mrs r0, cpsr
6、异常中断指令 异常中断指令可以分为一下两种: 软件中断指令(SWI) 断点指令(BKPT—仅用于 v5T 体系) 软件中断指令 SWI 用于产生 SWI 异常中断,用来实现在用户模式下对操作系统中特权模式的 程序的调用;断点中断指令 BKPT 主要用于产生软件断点,供调试程序用。 7、其他伪指令 .extern main .text .global _start _start:
件中引用,而且无论当前源文件是否引用该标号,该标号均会被加入到当前源文件的符号表
中。
IMPORT
BootloaderMain
IMPORT
MMUSetup
(4)BL 带返回的跳转指令
(5)BEQ 表示“相等则跳转”,即当 CPSR 中的 Z 标志置位时发生跳转
B
Label
;程序无条件跳转到标号 Label 处执行
作操作数 2,则此后的有 GT 后缀的指令将可以执行。 指令示例: CMP R1,R0 ;将寄存器 R1 的值与寄存器 R0 的值相减,并根据结果设置 CPSR 的标志位 CMP R1,#100 ;将寄存器 R1 的值与立即数 100 相减,并根据结果设置 CPSR 的标志位
(13)批量数据加载/存储指令 LDM(或 STM)指令的格式为: LDM(或 STM){条件}{类型} 基址寄存器{!},寄存器列表{∧} LDM(或 STM)指令用于从由基址寄存器所指示的一片连续存储器到寄存器列表所指示的多 个寄存器之间传送数据,该指令的常见用途是将多个寄存器的内容入栈(SDM)或出栈(LDM)。 其中,{类型}为以下几种情况: IA 每次传送后地址加 1; IB 每次传送前地址加 1; DA 每次传送后地址减 1; DB 每次传送前地址减 1; FD 满递减堆栈; ED 空递减堆栈; FA 满递增堆栈; EA 空递增堆栈; {!}为可选后缀,若选用该后缀,则当数据传送完毕之后,将最后的地址写入基址寄存器, 否则基址寄存器的内容不改变。
器将要执行的操作,源寄存器为 ARM 处理器的寄存器,目的寄存器 1 和目的寄存器 2 均为
协处理器的寄存器。
指令示例:
MCR
P3,3,R0,C4,C5,6
;该指令将 ARM 处理器寄存器 R0 中的数据传送到
协处理器 P3 的寄存器 C4 和 C5 中。
(12)CMP 指令的格式为: CMP{条件} 操作数 1,操作数 2 CMP 指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行比较,同时更新 CPSR 中条件标志位的值。该指令进行一次减法运算,但不存储结果,只更改条件标志位。 标志位表示的是操作数 1 与操作数 2 的关系(大、小、相等),例如,当操作数 1 大于操
;
CPSR--->r1
MSR (写状态寄存器) MSR cpsr_c, #0xD3 ; CPSR[7...0] = 0xD3
STMFD SP! {R8-R9}
含义:(1)SP=SP-4 字节 (2) R9--->SP (3)SP=SP-4 (4) R8-->SP
LDMFD SP! {R8-R9,PC}
CMP R1,#0
;当 CPSR 寄存器中的 Z 条件码置位时,程序跳转到标号 Label 处执行
BEQ Label
(6)LDR 指令的格式为:
LDR{条件} 目的寄存器,<存储器地址>
LDR 指令用于从存储器中将一个 32 位的字数据传送到目的寄存器中。该指令通常用于从存
储器中读取 32 位的字数据到通用寄存器,然后对数据进行处理。当程序计数器 PC 作为目
{TRUE}
(2)GET(或 INCLUDE) GET 伪指令用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行 汇编处理。可以使用 INCLUDE 代替 GET。 INCLUDE ..\\..\\kernel\\oal\\startup.s
(3)IMPORT 伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文
在嵌入式开发中,汇编程序常常用于非常关键的地方,比如系统启动时初始化,进出中断时 的环境保护,恢复等对性能有要求的地方。
ARM 指令集可以分为六大类,分别为数据处理指令、Load/Store 指令、跳转指令、程序状态
寄存器处理指令、协处理器指令和异常产生指令。
ARM 指令使用的基本格式如下:
〈opcode〉{〈cond〉}{S}
〈Rd〉,〈Rn〉{,〈operand2〉}
opcode 操作码;指令助记符,如 LDR、STR 等。
cond 可选的条件码;执行条件,如 EQ、NE 等。
S 可选后缀;若指定“S”,则根据指令执行结果更新 CPSR 中的条件码。
Rd 目标寄存器。
Rn 存放第 1 操作数的寄存器。
operand2 第 2 个操作数
b funa .... funa:
b funb ....
funb: .... 2、数据传送指令 mov,地址读取伪指令 ldr mov 指令可以把一个寄存器的值赋给另外一个寄存器,或者把一个常数赋给寄存器。 mov r1, r2
mov r1,#1024 mov 传送的常数必须能用立即数来表示。当不能用立即数表示时,可以用 ldr 命令来赋值。 ldr 是伪命令,不是真实存在的指令,编译器会把它扩展成真正的指令;如果该常数能用“立 即数”来表示,则使用 mov 指令,否则编译时将该常数保存在某个位置,使用内存读取指令 把它读出来。 ldr r1, = 1024
3、内存访问指令 ldr、str、ldm、stm ldr 既可以指低至读取伪指令,也可以是内存访问指令。当他的第二个参数前面有'='时标 伪指令,否则表内存访问指令。 ldr 指令从内存中读取数据到寄存器,str 指令把寄存器的指存储到内存中,他们的操作数 都是 32 位的。
ldr r1, [r2, #4] ldr r1,[r2] ldr r1,[r2], #4 str r1 ,[r2, #4] str r1, [r2] str r1, [r2],#4 寄存器传送指令可以用一条指令将 16 个可见寄存器(R0~R15)的任意子集合(或全部)存 储到存储器或从存储器中读取数据到该寄存器集合中。与单寄存器存取指令相比,多寄存器 数据存取可用的寻址模式更加有限。多寄存器存取指令的汇编格式如下: LDM/STM{<cond>}<add mode> Rn{!}, <registers>
[logical expression
Instructions Instructions
{ELSE |
Instructions Instructions
} ]
ENDIF
(1)GBLL 伪指令用于定义一个全局的逻辑变量,并初始化为{False}。
相关文档
最新文档