代码文件夹:E:\keil-4.12\asm_project\project1
一、前提知识
立即数的判断(重点1)
12位立即数的条件:
如果某个数的数值范围是0~0xFF之间,那么这个数一定是立即数;
把某个数展开成2进制,这个数的最高位1至最低位1之间的二进制数序列的位数不能超过8位;
这个数的二进制序列凑够8位之后的的右边必须为偶数个连续的 0
0x3f4 = 0000 0000 0000 0000 0000 0011 1111 0100
0x132 = 0000 0000 0000 0000 0000 0001 0011 0010
栈 ARM使用的是满减栈
分类:空增栈,空减栈,满增栈,满减栈
- 增栈:入栈时,sp指针向上移动
- 减栈:入栈时,sp指针向下移动
- 空栈:先写数据再挪动指针
- 满栈:先挪动指针,再写数据
满减栈:*--sp,先让sp-,再写数据
二、主要内容
学习目的
- 编写arm启动代码,引导程序到c语言环境下运行
运算符
gt:大于号(>) lt:小于号(<) ge:大于等于号(≥)
应用格式:指令+运算符(当满足条件时执行指令)
例:movgt,movlt,bgt,blt
指令
指令内容:mov,add,sub,ldr,str,bic,orr,cmp,
重点指令
1.跳转指令**(b类指令)**
格式:b 代码区名
区别:
- bl:函数调用时,会将返回地址保存到Ir寄存器
- b:函数调用时,无法将返回地址保存到Ir寄存器
- bx:跳转到Ir寄存器对应返回地址
死循环 while(1)
finished
b finished ;
2.ram数据操作指令
目的:实现对ram数据的写入与读取
写数据指令 ldr
功能
- 读取ram数据,并写入寄存器(指针化)
- 向寄存器加载一个非立即数
示例:ldr r0,=0x40000000 ;r0存放ram的空间地址,r0成为该空间指针
ldr rl,[r0] ;r1中存放对应ram的具体数据 即 r1 = *r0
读数据指令 str
功能:读取寄存器的值,并写入ram
示例:ldr r0,=0x40000000
ldr r1,=0x1A2B3C4D
str r1,[r0] ;向地址为0x40000000的ram空间写入数据0x1A2B3C4D
注:数据写入方式默认为小端写入(可修改)
应用:两数求和(见文末)
拓展指令(了解即可)
mvn:按位取反指令
bic:将寄存器中的值某几位清0(取决于立即数哪几位为1)
orr:将寄存器中的值某几位置1(取决于立即数哪几位为1)
栈的应用
ARM使用的是满减栈
嵌套调用
栈的分类
入栈保护
指令 STMFD
stmfd sp!, {r0-r1, lr}
出栈恢复
ldmfd
附录
拓展知识
汇编指令的s后缀
几乎所有的汇编指令都可以在指令后面加上s后缀
s后缀的含义是在指令执行过程中会更新cpsr 寄存器的N,V,C,Z位
- N:在结果是有符号的二进制补码情况下,
如果结果为负数,则N=1;如果结果为非负数,则N=0- Z:如果结果为0,则Z=1;如果结果为非0,否则Z=0
- C:针对无符号数,
加法中最高有效位向更高位进位 时C=1;减法中运算结果的最高有效位从更高位借位时C=0- V:针对有符号数,会在下面两种情形变为1,
两个最高有效位均为0的数相加,得到的结果最高有效位为1;
两个最高有效位均为1的数相加,得到的结果最高有效位为0;
除了这两种情况以外V位为0
代码示例
1.两数求和代码
r0存放地址,r1,r2存放加数,r3存放求和结果,最后根据r0地址写入内部ram
ldr r0, =0x40000000 ldr r1, [r0] ldr r0, =0x40000004 ldr r2, [r0] add r3, r1, r2 ldr r0, =0x40000008 str r3, [r0]
b
实现指令跳转
功能:实现分支结构和循环结构
格式:b (指令区)
eg:b lable
特殊情况:cmp+bgt/blt
指令跳转的实现
b lable
lable
死循环
finished
b finished ;while(1)
bl
函数调用实现
函数调用时,将返回地址保存到
bx
mov px lr
嵌套调用
栈的分类
入栈保护
指令 STMFD
stmfd sp!, {r0-r1, lr}
出栈恢复
ldmfd
入栈保护和出栈恢复只能由主调方进行


汇编文件调用c语言函数
import声明函数
依赖于通用寄存器实现传参(参数不超过4个)
通过栈实现传输(参数超过4个)
函数返回结果保存到R0寄存器


c语言文件调用汇编函数
在c文件中extern 声明函数
在汇编文件中export导出函数
模式切换
重点
立即数的判断规则
b,bl,bx的指令区别
栈的分类,区别(空增空减满增满减)
ARM使用的是满减栈
汇编中调用c函数
c中调汇编函数
