专题3-汇编语言得玩转

第1课-汇编概述

1.为什么学习汇编指令

以后的工作中我们用的都是中高端的处理器,基本不会用汇编去编程完成这个产品。但是在bootloader和内核的编程中我们都是要用汇编语言的,这期间c语言的运行环境还没有搭建。在对效率有有特殊要求的地方我们还是需要汇编语言的。

2.分类

目前常用的ARM的汇编指令有两种:

(1)ARM标准汇编:适用于ARM公司的汇编器,适合在windows平台下使用,如ADS中使用。ADS是基于windows的集成程序。

(2)GNU汇编:适用于GNU交叉编译器工具链中的汇编器,适合linux开发平台。我们使用的是GNU汇编

3.汇编程序框架

.sectiom.data

<初始化的数据>

.section.bss

<未初始化的数据>

.section.text      /*代码段*/

.global _start     /*全局访问*/

_start:

<汇编代码>

简化:

.text

.global _start

_start:

<汇编代码>

4.编程准备

(1)首先在相应的文档里面建立一个名字为start.s的文件,文件内容如下:

.text

.global _start                  //定义全局变量

_start:                       //程序入口

mov r1,#1             /*将1这个立即数,放在r1寄存器里面*/

mov r2,#2

mov r3,#3

(2)建立一个Makefile,内容如下:

all:start.o

arm-linux-ld -Ttext 0x20000000 -o start.elf $^    /*指明程序运行的起止地址*/

%.o : %.S

Arm-linux-gcc -g -o $@ $^ .c

Clean

rm *.o *.elf

/*针对210的开发板,代码段的指定开头就是20000000,对于6410是50000000,2440是30000000*/

连接器脚本对整个程序的地址进行排布,可以在开头进行运行地址的设置。

以Jlink的方式连接开发板与电脑,运行Jlink发现联接上了,启动我们自己安装的eclipse软件,编译我们编译的软件。按上面章节的方法,进行一系列的配置与初始化调试。

第二课-指令分类学习

GUN汇编和ARM标准汇编是有区别的,一般来说GUN是小写的,标准ARM是大写的。

1. 算数和逻辑指令

(1)mov装载

mov{条件}[S]  <dest>, <op_1>

C语言转换:dest = op_1

mov从一个寄存器、被位移的寄存器、或一个立即数装载到目的寄存器。

dest必须是通用寄存器,op_1可以是通用寄存器、状态寄存器也可以是数字。

注:汇编语言的注释是@符号后面加注释的。

(2)mvn取反装载

mvn{条件}[S]  <dest>, <op_1>

C语言转换:dest = !op_1

mvn从一个寄存器、被位移的寄存器、或一个立即数装载到目的寄存器。不同之处是在传送之前位被取反了,是把取反的值传给一个寄存器。这是逻辑操作不是算数操作,这个取反的值加1才是它的取负的值。

mov R0, #4            R0变成-5

mov R0, #0            R0变成-1

(3)sub相减

sub{条件}[S]  <dest>, <op_1> <op_2>

dest= op_1- op_2

sub用来执行减法操作,操作数1是一个寄存器,操作数2可以是一个寄存器、被位移的寄存器或者是一个立即数。

(4)add相加

add{条件}[S]  <dest>, <op_1> <op_2>

dest= op_1+op_2

add用来执行加法操作,操作数1是一个寄存器,操作数2可以是一个寄存器、被位移的寄存器或者是一个立即数。

(5)and逻辑与

and{条件}[S]  <dest>, <op_1> <op_2>

dest= op_1&op_2

and用来执行逻辑与操作。操作数1是一个寄存器,操作数2可以是一个寄存器、被位移的寄存器或者是一个立即数。

(6)bic位清除

bic{条件}[S]  <dest>, <op_1> <op_2>

dest= op_1and(!op_2)

在一个字中清除位的一种方法,与or位设置是相反的操作。操作数2是一个32位的位操作符(mask)。如果在操作码中设置了某一位,就清除这一位。未设置操作码的位保持不变。

bic r0, r0, #1011        表示清除r0中的第0、1、3位,其余的位不变

2. 比较指令

(1)cmp比较

cmp{条件}[S]  <op_1> <op_2>

status= op_1-op_2

status为1表示操作数1大,为-1表示操作数2大,为0表示一样大。它改变的是CPSR寄存器的31位(M位)于30位(N位)。

例子

mov r1, #2

cmp r1, #1

cpsr为200001d3

mov r1, #2

cmp r1, #1

cpsr为800001d3

mov r1, #2

cmp r1, #2

cpsr为600001d3

(2)tst按位与

tst{条件}[S]  <op_1> <op_2>

status= op_1 AND op_2

按位与之后的结果是0,CPSR的30位(Z位)置1,否则CPSR的30位(Z位)不置1。

例子

mov r1, #0b101

tst  r1, #0b001

cpsr为200001d3

mov r1, #0b101

tst  r1, #0b101

cpsr为600001d3

3. 跳转指令

汇编的程序需要分支指令完成C语言中的if…else操作

(1)b分支

b{条件} <地址>

存储在分支指令中的实际的值是相当于当前的r15的一个偏移量,并不是一个绝对地址。它的值由汇编器来计算,它是24位有符号量,左移两位后有符号扩展为32位,表示的有效偏移量是26位(+/-32M)。

例子:

mov r1,#6

mov r2,#5

cmp r1,r2

bgt branch1:

add r3, r1, r2

b end

branch1:

sub r3,r1,r2

end:

nop

EQ : 等于

如果一次比较之后设置了 Z 标志。

NE : 不等于

如果一次比较之后清除了 Z 标志。

VS : 溢出设置

如果在一次算术操作之后设置了 V 标志,计算的结果不适合放入一个 32bit 目标寄存器中。

VC : 溢出清除

如果清除了 V 标志,与 VS 相反。

HI : 高于(无符号)

如果一次比较之后设置了 C 标志并清除了 Z 标志。

LS : 低于或同于(无符号)

如果一次比较操作之后清除了 C 标志或设置了 Z 标志。

PL : 正号

如果一次算术操作之后清除了 N。出于定义‘正号’的目的,零是正数的原因是它不是负数...

MI : 负号

如果一次算术操作之后设置了 N 标志。

CS : 进位设置

如果一次算术操作或移位操作之后设置了 C 标志,操作的结果不能表示为 32bit。你可以把 C 标志当作结果的第 33 位。

CC : 进位清除

与 CS 相反。

GE : 大于或等于(有符号)

如果一次比较之后...
设置了 N 标志并设置了 V 标志
或者...
清除了 N 标志并清除了 V 标志。

GT : 大于(有符号)

如果一次比较之后...
设置了 N 标志并设置了 V 标志
或者...
清除了 N 标志并清除了 V 标志
并且...
清除了 Z 标志。

LE : 小于或等于(有符号)

如果一次比较之后...
设置了 N 标志并清除了 V 标志
或者...
清除了 N 标志并设置了 V 标志
并且...
设置了 Z 标志。

LT : 小于(有符号)

如果一次比较之后...
设置了 N 标志并清除了 V 标志。
或者...
清除了 N 标志并设置了 V 标志。

AL : 总是

缺省条件,所以不用明显声明。

NV : 从不

不是特别有用,它表示应当永远不执行这个指令。是穷人的 NOP。
包含 NV 是为了完整性(与 AL 相对),你不应该在你的代码中使用它。

(2)bl带链接返回的分支

b指令在跳转之前不能将返回地址保存,bl就可以将返回地址保存,可以起到类似C语言的对函数进行封装的效果。

例如:

mov r1, #6

cmp r1, #5

bl func1:

mov r1, #2

cmp r1, #3

func1:

mov r1, #r2

mov r2, #3

mov pc, lr

4. 移位指令

(1)lsl逻辑(算数)左移

例如:

mov r1, #0b1

mov r1,r1, lsl#2

对r1左移两位,将结果再存在r1中,r1从0b1变成0b100

(2)ror循环右移

例如:

mov r1, #0b11

mov r1,r1, ror#1

r1的值从0b11变成0b1000000000000000000000000000001,一共32位。

5. 程序状态字访问指令

程序状态寄存器所用的访问指令和前面的指令不能是一样的,对它们的修改,需要将CPSR或者SPSR中的指令搬移到通用寄存器,改好后再搬回程序状态寄存器。

msr(搬入)和mrs(搬出)两条指令:

例子:

mrs r0, cpsr

orr r0, 0b100

msr cpsr, r0

将cpsr的第三位设置为1

6. 存储器访问指令

(1)ldr将内存中的值导入寄存器

str    rd, [Rbase]          存储 rd 到 Rbase 所包含的有效地址。

str    rd, [Rbase, Rindex]  存储 rd 到 Rbase + Rindex 所合成的有效地址。

str    rd, [Rbase, #index]  存储 rd 到 Rbase + index 所合成的有效地址。

index 是一个立即值。

例如,rTR rd, [R1, #16] 将把 rd 存储到 r1+16。

str    rd, [Rbase, Rindex]! 存储 rd 到 Rbase + Rindex 所合成的有效地址,

并且把这个新地址写回到 Rbase。

str    rd, [Rbase, #index]! 存储 rd 到 Rbase + index 所合成的有效地址,

并且并且把这个新地址写回到 Rbase。

str    rd, [Rbase], Rindex  存储 rd 到 Rbase 所包含的有效地址。

把 Rbase + Rindex 所合成的有效地址写回 Rbase。

str    rd, [Rbase, Rindex, lsl #2]

存储 rd 到 Rbase + (Rindex * 4) 所合成的有效地址。

str    rd, place            存储 rd 到 PC + place 所合成的有效地址。

(2)str将寄存器中的值保存到内存

第3课-伪指令

一.ARM机器码

汇编程序通过汇编器转化成机器码,机器码才能够在嵌入式芯片上运行。Arm机器码是32位的整数,机器码被分成不同大小的段,每个段都有各自独特的功能

mov r0, r1的机器码是e1a00001

二进制是:1110 00 0 1101 0 0000 0000 000000000001

moveq r0, #255的机器码是03a000ff

二进制是:0000 00 1 1101 0 0000 0000 000011111111

对于mov指令它的机器码格式如下:

第一段前4位表示条件,1110表示无条件,0000表示等于的条件

第二段是保留位,是00

第三段表示0-11存的是立即数的话就是1,存的是寄存器的话就是0

第四段opcode,它的作用是区分指令,mov指令就是1101

第五段是S,程序运行后影响CPSR寄存器就是1,不影响就是0

第六段是Rn,

第七段是目的寄存器,我们用的是r0,用的是0来标号,r1是0001

第八段是源操作数,寄存器r1是00000000001,#255是00001111111

这样我们可以观测到,第八段中存放数的大小是有限的,这样引出伪指令的概念。

二.定义类伪指令

伪指令本身并没有对应的机器码,它只是在编译而定时候起作用,或者转化为其他的实际指令来运行。

(1)       global标明全局符号

(2)       data标明数据段

(3)       ascii标明字符串指令

(4)       byte标明字节的指令

(5)       word标明字的指令

例子:

.data

hello:

.ascii “hellloworld”

bh:

.byte 0x1

ADD

.word 0xff

(6)       equ相当于宏定义

.equ DA,0x89

mov r0, DA

(7)       align对齐,在文件前面加上.align就会表示按四字节对齐

三.操作类伪指令

(1)nop

空操作,主要的作用是延时的作用。

(2)ldr(与存储器的访问指令不同)

mov r0, 0x1ff运行的时候会出错,因为mov指令只能处理8位的二进制数,0x1ff是9位,机器码的0-11位中有四位是存储左移与右移操作的,所以存储的内容不能超过8位。

它可以在r0里面填充超过8位的立即数,但是格式特殊:

ldr r0, =0x1ff

第4课-协处理访问指令

一.什么是协处理器

协处理器用于执行特定的处理任务,如:数学协处理器可以控制数字处理,以减轻处理器的负担。ARM可支持最多16个协处理器,其中CP15是最重要的一个。

  1. CP15的作用

CP15是系统控制协处理器,提供了额外的寄存器,通过这些寄存器,可以达到配置与控制caches、MMU以及时钟参数。

  1. CP15寄存器

CP15提供了16组寄存器,具体的使用可以在Arm公司提供的芯片手册中找到。我们通过它提供的16组寄存器,可以访问cp15寄存器。

二.协处理器访问

1. mcr

r表示通用寄存器,c表示协处理器寄存器

2.mrc

格式:

例子:读取mainID

mrc p15, 0, r0, c0, c0, 0             表示读取mianID寄存器的值

转载于:https://www.cnblogs.com/free-1122/p/11451986.html

第二季-专题3-汇编语言得玩转相关推荐

  1. Python可以这样学(第二季:tkinter案例精选)-董付国-专题视频课程

    Python可以这样学(第二季:tkinter案例精选)-3592人已学习 课程介绍         董付国老师系列教材<Python程序设计基础>(ISBN:9787302410584) ...

  2. 火星人敏捷开发1001问(第二季)-陈勇-专题视频课程

    火星人敏捷开发1001问(第二季)-17497人已学习 课程介绍         此课程为敏捷开发的课程,聚焦于敏捷开发中似是而非的各种问题.每个问题都会有分析与解决的环节,从而令学员不但得到可行的答 ...

  3. 跟着王进老师学开发C#篇第二季:面向对象-王进-专题视频课程

    跟着王进老师学开发C#篇第二季:面向对象-9471人已学习 课程介绍         面向对象的思想在现在程序开发中非常重要,很多刚入门的程序员没有真正理解面向对象的思想而被挡在在软件开发的门外,本次 ...

  4. 血腥大地-第二季(资源破解与管理)-张立铜-专题视频课程

    血腥大地-第二季(资源破解与管理)-2426人已学习 课程介绍         课程继承<血腥大地>游戏内容 1.主要完成游戏资源的获取,从原血腥大地游戏中获取(不涉及任何商业利益,不能将 ...

  5. Android自动化测试第二季(提高篇)-金阳光-专题视频课程

    Android自动化测试第二季(提高篇)-17804人已学习 课程介绍         [金阳光测试]是由金阳光等创办的国内个人免费培训测试.欢迎喜欢测试的朋友来观看学习,提意见. 课程收益      ...

  6. 新星计划第二季|量身打造、全新互动,快来报名

    活动官网: https://marketing.csdn.net/p/1d9bedb178313a415dfd4b5839766206 <新星计划>第一季,我们汇集了各大领域的优秀新人,在 ...

  7. 旁观天使湾Demo Day第二季:创意亮闪闪,运营苦哈哈

    6月2日,杭州人的特有的节日之一."62″在杭州土话里,是笨蛋的意思.也许有激情的笨蛋才可能在这波移动互联网时代掘金.反正在这个很适合一起2的日子,庞小伟找了个很有情调的山庄,让他的天使湾d ...

  8. 哈工程计算机学院领导门志国,电气学院“钥匙工程”第二季:赵洪教授为2018级新生打开专业之门...

    以引领电气新生代感受专业魅力.感悟专业精神.坚定专业信仰.铭记专业使命.立志忠于祖国.忠于人民.忠于专业为宗旨的"钥匙工程"第二季迎来了第三位主讲嘉宾.9月4日8:30,电气与电子 ...

  9. 优酷直播节目“冠军体育课”第二季收官 共吸引近百万用户观看互动

    [TechWeb]3月5日消息,昨天,阿里体育联合优酷少儿推出的直播节目"冠军体育课"第二季收官,张丹.张虹.朱芳雨.王仕鹏等七位体育明星分别走进优酷体育直播间,分享他们疫情宅家期 ...

  10. 《原力计划【第二季】》第 4 周周榜揭晓!!!

    自 2 月 21 日开始<原力计划[第二季]- 学习力挑战>,已经到了第 4 周,累计 14000+ 名博主参与了本次活动. 本周共收到活动投稿 18790 篇原创文章,经过层层筛选,最后 ...

最新文章

  1. OEA 框架演示 - 快过原型的开发
  2. ***远程连接MYSQL提示1130 - Host is not allowed to connect to this MySQL server
  3. Minimizing Difference CodeForces - 1244E(贪心题)
  4. jboss项目导入idea_如何导入任何JBoss BRMS示例项目
  5. FreeRTOS任务通知
  6. Excel 2016新增函数之IFS
  7. orm mysql_PHP基于ORM方式操作MySQL数据库实例
  8. 成也炒作,败也炒作?孙宇晨遭遇最大信任危机
  9. 389. Find the Difference
  10. [译]R语言——Shiny框架之构建(一):1.结构——1.独立应用程序——1.应用的格式和启动
  11. EVEREST Ultimate Edition 4.50 Build 1330 Final
  12. Python计算器练习
  13. matlab按行读文件
  14. 高德地图集成之基础定位
  15. 遇见更好的自己 -- 90后农村姑娘非洲四年驻外生涯,和她的学渣“逆袭”川大的人生故事
  16. JAVA架构师之路十:设计模式之组合模式
  17. ubuntu桌面进不去的解决办法
  18. 笑喷了,我用Python帮韦小宝选最佳老婆组合
  19. 使用神器vscode代替beyond compare进行文本比较高亮显示
  20. ArcEngine编辑模块——移动单个要素的实现方法

热门文章

  1. Android AsyncTask源代码浅析
  2. 在计算机领域提到的假说,量子力学中假说的发展及相关影响
  3. card如何添加复选框 vant_Vant Weapp小程序蹲坑之使用card组件显示价格
  4. 打造AS酷炫dimens适配插件
  5. VSCode 上竟然也能约会,谈对象了???
  6. 2017中国程序员薪资生存现状调查报告
  7. Go基础-go语言的编码规范
  8. 多个项目共用同一个redis_比Redis快5倍的中间件,为啥这么快?
  9. 订单编号的数据类型是什么_电商仓储是如何进行发货的?拣货的原则是什么?...
  10. 算法知识点——(2)模型评估