单片机(学习)2024.10.9

目录

汇编整体分类

1.指令

2.伪操作

3.伪指令

汇编代码

汇编初始化

数据搬运指令

算术运算指令

加法

减法

乘法

比较指令

跳转指令

逻辑运算指令

与或,异或

左移右移

[内存操作 LOAD/STORE 指令](#内存操作 LOAD/STORE 指令)

CPU的栈机制

栈的概念

栈的种类

1.空栈(Empty)

2.满栈(Full)

栈的基本操作

PUSH/POP

栈的应用

叶子函数

非叶子函数


汇编整体分类

1.指令

编译完生成一条机器码存储在内存单元当中,CPU执行时能完成对应的操作(类似于C中的语句)

2.伪操作

伪操作(相当于c中的#的内容,告诉编译器怎么编译),不会生成机器码也不会占用内存,其作用是告诉编译器怎样编译(类似于C中的预处理指令)

3.伪指令

伪指令不是指令,编译器在编译时将其替换成等效的指令 (如:cpu中没有乘法器,对应没有乘法指令,3*3 ---》用加法器实现3+3+3,替换实现)

汇编代码

汇编初始化

bash 复制代码
 AREA    STACK, NOINIT, READWRITE
__initial_sp
                AREA    RESET, DATA, READONLY
__Vectors       DCD     __initial_sp
                DCD     main              
                AREA    |.text|, CODE, READONLY
                ENTRY
main


loop
                B loop                  
                END

1.AREA STACK, NOINIT, READWRITE : 这一行指定了一个名为STACK的内存区域,它用于存储堆栈。NOINIT表示这个内存区域在程序启动时不需要初始化,READWRITE表示这个内存区域可以被读取和写入。

2.__initial_sp : 这一行定义了一个名为`__initial_sp`的符号,它表示堆栈指针的初始值。在这里,它被定义为堆栈的起始地址。通常,这个符号会在链接脚本中进一步定义为实际的堆栈内存区域的起始地址。

3.AREA RESET, DATA, READONLY : 这一行指定了一个名为RESET的内存区域,用于存储重置向量表。DATA表示这个区域包含数据,READONLY表示这个区域只能被读取。

4.__Vectors DCD __initial_sp : 这一行定义了一个重置向量表,用于指示程序启动时应该执行的操作。`DCD`表示存储一个双字(32位)的数据。在这里,第一个双字存储的是堆栈指针的初始值,即__initial_sp。

5.DCD main : 这一行将程序的入口地址(main函数)添加到重置向量表中。这意味着程序在启动时将跳转到main函数开始执行。

6.AREA |.text|, CODE, READONLY : 这一行指定了一个名为.text的内存区域,用于存储代码。CODE表示这个区域包含代码,READONLY表示这个区域只能被读取。

7.ENTRY main : 这一行指定了程序的入口点为main函数。这意味着程序将从`main`函数开始执行。

8.loop B loop : 这一行是一个无限循环,它会不断地跳转到`loop`标签所在的位置,导致程序永远循环执行这条指令。

9.END: 这一行表示程序的结束。

数据搬运指令

改变PC的值实现程序跳转

cpp 复制代码
 AREA    STACK, NOINIT, READWRITE
__initial_sp                 
    AREA                 RESET, DATA, READONLY
__Vectors       DCD     __initial_sp                  
    DCD     main                               
    AREA    |.text|, CODE, READONLY                 
    ENTRY
main  
MOVS R0,#2
MOVS R1,R0
;改变PC的值实现程序跳转,0x08000008
;先把地址给一个寄存器,再把这个寄存器的值赋给PC
LDR R2,=0x08000008
MOV PC,R2
loop                 
    B loop                                   
END

算术运算指令

加法

bash 复制代码
    AREA    STACK, NOINIT, READWRITE
__initial_sp                 
    AREA                 RESET, DATA, READONLY
__Vectors       DCD     __initial_sp                  
    DCD     main                               
    AREA    |.text|, CODE, READONLY                 
    ENTRY
main  
MOVS R0,#2
MOVS R1,R0
ADDS R3,R0,R1  ;R3=0X04
LDR R8,=0X01
ADD R8,R8,R3   ;R8=R8+R3 =0X05
loop                 
    B loop                                   
END

减法

bash 复制代码
    AREA    STACK, NOINIT, READWRITE
__initial_sp                 
    AREA                 RESET, DATA, READONLY
__Vectors       DCD     __initial_sp                  
    DCD     main                               
    AREA    |.text|, CODE, READONLY                 
    ENTRY
main  
MOVS R0,#2
MOVS R2,#2
MOVS R1,R0
SUBS R2,R0,R1  ;R2=R0-R1
loop                 
    B loop                                   
END

乘法

bash 复制代码
    AREA    STACK, NOINIT, READWRITE
__initial_sp                 
    AREA                 RESET, DATA, READONLY
__Vectors       DCD     __initial_sp                  
    DCD     main                               
    AREA    |.text|, CODE, READONLY                 
    ENTRY
main  
MOVS R0,#2
MOVS R2,#2
MOVS R1,R0
MULS R2,R0,R2  ;R2=R0*R2
loop                 
    B loop                                   
END

比较指令

跳转指令

bash 复制代码
    AREA    STACK, NOINIT, READWRITE
__initial_sp                 
    AREA                 RESET, DATA, READONLY
__Vectors       DCD     __initial_sp                  
    DCD     main                               
    AREA    |.text|, CODE, READONLY                 
    ENTRY
JUMP
MOVS R0,#1
MOVS R2,#1
LDR R3,=0X0800001A
MOV PC,R3

main  
MOVS R0,#2
MOVS R2,#2
MOVS R1,R0
CMP R0,R2  ;if(a==b)
BEQ JUMP  
MOVS R0,#3
loop                 
    B loop                                   
END
cpp 复制代码
    AREA    STACK, NOINIT, READWRITE
__initial_sp                 
    AREA                 RESET, DATA, READONLY
__Vectors       DCD     __initial_sp                  
    DCD     main                               
    AREA    |.text|, CODE, READONLY                 
    ENTRY
JUMP
MOVS R0,#1
MOVS R2,#1
MOV PC,LR

main  
MOVS R0,#2
MOVS R2,#2
MOVS R1,R0
BL JUMP
MOVS R0,#3
loop                 
    B loop                                   
END

逻辑运算指令

与或,异或

bash 复制代码
    AREA    STACK, NOINIT, READWRITE
__initial_sp                 
    AREA                 RESET, DATA, READONLY
__Vectors       DCD     __initial_sp                  
    DCD     main                               
    AREA    |.text|, CODE, READONLY                 
    ENTRY


main  
MOVS R0,#2   ;R0:0010
MOVS R1,#1 ;R1:0001
ANDS R1,R1,R0   ;R1=R1&R0 R1=0000
EORS R1,R1,R0   ; 0010  0000  0010
loop                 
    B loop    

END

左移右移

cpp 复制代码
  AREA    STACK, NOINIT, READWRITE
__initial_sp                 
    AREA                 RESET, DATA, READONLY
__Vectors       DCD     __initial_sp                  
    DCD     main                               
    AREA    |.text|, CODE, READONLY                 
    ENTRY


main  
MOVS R0,#2   ;R0:0010  左移1位  0100--4
MOVS R1,#1 ;R1:1
LSLS R0,R0,R1
loop                 
    B loop    

END

内存操作 LOAD/STORE 指令

CPU的栈机制

栈的概念

栈是一种具有特殊的访问方式的存储空间,特殊性就在于后进先出

栈的种类

1.空栈(Empty)

栈指针指向的地址是空的,在栈中存储数据时,可以直接存储,存储完成之后需要将栈指针再次指向空的位置。

EA:Empty Ascending 空增栈

ED:Empty Descending 空减栈

2.满栈(Full)

栈指针指向的地址有数据,在栈中存储数据时,需要先将栈指针,指向一个空的位置,然后在存储数据。

增栈(Ascending)

栈指针向高地址方向移动

减栈(Descending)

栈指针向低地址方向移动

FA:Full Ascending 满增

FD:Full Descending 满减
ARM默认采用的是满减栈

栈指针指向有数据的顶,接收数据时,栈指针先移动,再放数据。指针的移动是地址的降低

栈的基本操作

栈有两种基本的操作:入栈和出栈

1.入栈:将一个新的元素放到栈顶

2.出栈:从栈顶取出一个元素

栈顶元素总是最后一个入栈的,需要出的时候,又会是第一个被取出的

操作规则:LIFO后进先出

PUSH/POP

PUSH 入栈,压栈

POP 出栈,弹栈

bash 复制代码
//主程序给R1,R2,R3,R4分别存入:0x11111111 0x22222222 0x33333333 0x44444444然后跳入函数JUMP
//2.写一个函数JUMP,函数内修改R1为0x20000001 R3为0x00000000
//3.修改结束后返回主函数
//4.主函数再使R1和R3相加后存入R1跳出主程序进入死循环
//子程序返回主程序时,不可以使用MOV指令和B BL BX BXL

    AREA    STACK, NOINIT, READWRITE
__initial_sp                 
    AREA                 RESET, DATA, READONLY
__Vectors       DCD     __initial_sp                  
    DCD     main                               
    AREA    |.text|, CODE, READONLY                 
    ENTRY
main  
    ADD SP,SP,#0X100;上调栈指针
    LDR R1,=0X11111111;
    LDR R2,=0X22222222;
    LDR R3,=0X33333333;
    LDR R4,=0X44444444;
    BL JUMP
    ADD R1,R1,R3
    B loop
JUMP
    PUSH {R0-R4,LR} ;保护现场
    LDR R1,=0X44324302;
    LDR R3,=0X33222055;
    POP{R0-R4,PC} ;恢复现场
loop                 
    B loop    
END

栈的应用

叶子函数

叶子函数是指一个函数内部没有调用其他函数的函数,也就是说,它是程序调用树的末端节点,不依赖于其他函数。

非叶子函数

非叶子函数是指一个函数内部调用了其他函数的函数,也就是说,它不是程序调用树的末端节点,可以被其他函数调用。

相关推荐
halo1416几秒前
uni-app 界面TabBar中间大图标设置的两种方法
开发语言·javascript·uni-app
醉陌离6 分钟前
渗透测试学习笔记—shodan(2)
笔记·学习
froginwe118 分钟前
Go 语言数组
开发语言
youcans_8 分钟前
【动手学电机驱动】STM32-FOC(8)MCSDK Profiler 电机参数辨识
stm32·单片机·嵌入式硬件·电机控制·foc
瑞雨溪9 分钟前
python中的OS模块的基本使用
开发语言·python
醒过来摸鱼13 分钟前
【Golang】协程
开发语言·后端·golang
时光追逐者14 分钟前
.NET 9 中 LINQ 新增功能实操
开发语言·开源·c#·.net·.netcore·linq·微软技术
Leuanghing16 分钟前
使用Python生成F分布表并导出为Excel文件
开发语言·python·excel·f分布
理论最高的吻16 分钟前
98. 验证二叉搜索树【 力扣(LeetCode) 】
数据结构·c++·算法·leetcode·职场和发展·二叉树·c
IT枫斗者18 分钟前
如何解决Java EasyExcel 导出报内存溢出
java·服务器·开发语言·网络·分布式·物联网