day2 ARM基础

@ 
.text
.globl _start
_start:
 mov  r0,#0  
 mov  r1,#0  


addfunc:
    
	  add  r0,r0,#1	 @r0自增1
	  adds r1,r1,r0  @R1实现1~100累加
      cmp r0,#100		@	判断r0是否到100
	  bleq loop       @r0等于100 进入死循环       
      blne addfunc    @r0等于100跳转至循环累加
loop:
		b loop
   
stop:
	b stop
	.end

【汇编工程创建】

1.汇编工程的创建步骤

参考汇编环境搭建PDF

2.汇编工程的编译

3.配置编辑器编码为UTF-8

4.示例汇编代码分析

.text @声明当前内容为文本段内容 .global _start @声明_start的内容为全局内容 _start: mov r1,#1 @将1保存在r1寄存器 loop: b loop @程序跳转到loop标签 .end @程序结束

5.程序的调试

map.lds文件是一个链接脚本文件 链接脚本的作用:当程序在编译的最后一个阶段-链接阶段中按照链接脚本的规定,链接不同的文件生成可执行文件

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") /*指定输出elf格式的适用于32位机器的镜像,镜像内部的数据按照小端存储方式 */ OUTPUT_ARCH(arm)/*生成的镜像架构是ARM架构的 */ ENTRY(_start)/* 程序执行的入口是_start*/ SECTIONS /* 内部指定了不同内容在内存中的存储位置*/ { . = 0x00000000; /*当前程序起始地址为0X0*/ . = ALIGN(4);/*程序中的指令遵循4字节对齐*/ .text : /*指定文本段的存储地址*/ { ./Objects/start.o(.text) /*将start.o的内容放在文本段最开始*/ *(.text)/*其他的文件保存位置由链接器自己决定*/ } . = ALIGN(4); .rodata : /*规定只读代码段的存储规则*/ { *(.rodata) } . = ALIGN(4); .data : { *(.data) } . = ALIGN(4); __bss_start = .; /*指定.bss段的起始位置*/ .bss : { *(.bss) } __bss_end__ = .;/* 指定.data段的起始位置*/ }

【汇编语言的相关语法】

1.汇编文件中的内容

1.伪操作:在汇编程序中不占用存储空间,但是可以在程序编译时起到引导和标识作用 .text .global .glbal .if .else .endif .data .word.... 2.汇编指令:每一条汇编指令都用来标识一个机器码,让计算机做一个指令运算 数据处理指令 数据搬移指令 算数运算指令 数据移位指令 位运算指令 数据比较指令 跳转指令 内存读写指令 状态寄存器传送指令 CPSR 软中断指令 3.伪指令:不是汇编指令,但是也可以让处理器做一些数据处理,通常一条伪指令会由多条汇编指令联合实现 4.注释 单行注释: @ ; 多行注释: /* */ 条件注释 .if 1/0 指令段1 .else 指令段2 .endif

2.汇编指令的基本语法格式

指令的基本格式: <opcode> {<cond>} {s} <Rd>, <Rn>, <shifter_operand> <opcode>:指令的操作码 cond:条件码后缀 s:指令的执行结果将会影响CPSR中的条件标志位。 <Rd>:目标寄存器,指令的运算结果保存在目标寄存器中 <Rn>:第一操作寄存器,只能是寄存器 <shifter_operand> :第二操作数,既可以是寄存器编号,又可以是立即数 意义:让第一操作寄存器中的值和第二操作数按照指令操作码进行运算,并且将运算的结果保存在目标寄存器中 注意: 1.一般一条汇编指令就占据一行代码 2.汇编不区分大小写 3.操作数前面要跟一个#

【汇编的指令】

1.数据搬移指令

1.1 基本格式

<opcode> {<cond>} {s} <Rd>, <shifter_operand> 解释: <opcode>:指令的操作码 cond:条件码后缀 s:指令的执行结果将会影响CPSR中的条件标志位。 <Rd>:目标寄存器,指令的运算结果保存在目标寄存器中 <shifter_operand> :第一操作数,既可以是寄存器编号,又可以是立即数 指令码: mov:将操作数直接搬移到目标寄存器中 mvn:将操作数按位取反之后搬移到目标寄存器中

1.2 示例

2. 立即数的概念

2.1 概念

定义:可以直接当作指令的一部分去执行的数据叫做立即数。立即数是通过一个0-255之间的数字循环右移偶数位获取

循环右移:低位移除,补到高位

2.2 立即数的判断

如何判断一个数据是不是立即数: 只要让这个数据或者这个数据按位取反的值循环右移偶数位,能够得到一个0-255范围内的数字就说明这个数是立即数 ex: 1. 0X104-> 0000 0000 0000 0000 0000 0001 0000 0100 0X104循环右移两位-》00 0000 0000 0000 0000 0000 0001 0000 01->0x41 0X41是一个0-255范围内的数据 0x104是0X41循环右移30位得到的数据,所以,0X104是立即数 2.0x101-> 0000 0000 0000 0000 0000 0001 0000 0001 0X101找不到一个0-255范围内的数字寻魂右移偶数位得到它,所以它不是立即数 3.0XFFFFFFFE ->1111 1111 1111 1111 1111 1111 1111 1110 0XFFFFFFFE也找不到0-255范围内的数字循环右移偶数位得到它,但是它的取反值0X1是一个立即数,所以0XFFFFFFFE也是一个立即数

2.3 如何将一个非立即数保存在寄存器中

利用伪指令ldr即可完成非立即数的操作 格式: ldr 目标寄存器名,=数据

3.移位操作指令

3.1 指令格式以及指令码

格式: <opcode> {<cond>} {s} <Rd>, <Rn>, <shifter_operand> 解释:将第一操作寄存器的数值移位第二操作数位,将结果保存在目标寄存器中 指令码: lsl:左移运算,最高位移出,最低位补0 lsr:右移运算,最低位移出,最高位补0 ror:循环右移:最低位移出,补到最高位

3.2 示例

.text .global _start _start: mov r0,#0XFF lsl r1,r0,#4 @0XFF左移四位结果保存到r1 0XFF0 lsr r2,r0,#4 @0XFF右移移四位结果保存到r2 0XF ror r3,r0,#4 @0XFF循环右移四位结果保存到r3 0XF000000F loop: b loop .end

4.位运算指令

4.1 相关指令功能以及规则

与、或、异或、按位清0

与:与0清0 与1不变

初值

运算值

结果

1

0

0

1

1

1

0

1

0

0

0

0

或:或1置1 或0不变

初值

运算值

结果

1

0

1

1

1

1

0

1

1

0

0

0

异或:相同为0,不同为1

初值

运算值

结果

1

0

1

1

1

0

0

1

1

1

1

0

按位清0:想要哪位清0,只需要和1进行运算即可

初值

运算值

结果

1

1

0

0

1

0

1

0

1

0

0

0

4.2 位运算指令码以及格式

格式: <opcode> {<cond>} {s} <Rd>, <Rn>, <shifter_operand> 指令码: and:进行按位与 orr:进行按位或 eor:按位异或 bic:按位清0

4.3 示例

.text .global _start _start: mov r0,#0XFF and r1,r0,#(~(0X1<<4)) @第四位清0 0xEF orr r2,r0,#(0X1<<9) @第9位置1 0X2FF eor r3,r0,#0XF @0xf0 bic r4,r0,#(0X1<<4)@第四位清0 0xEF loop: b loop .end

4.4 练习

LDR R0,=0X12345678 @在r1里存放0X12345678 1.将R0寄存器第4位清0,其他位不变 and r0,r0,#(~(0X1<<4))) 或者 bic r0,r0,#(0X1<<4) 2.将R0寄存器第7位置1,其他位不变 orr r0,r0,#(0X1<<7) 3.将R0寄存器第[31:28]位清0,其他位不变 and r0,r0,#(~(0Xf<<28))) 或者 bic r0,r0,#(0Xf<<28) 4.将R0寄存器第[7:4]位置1,其他位不变 orr r0,r0,#(0XF<<4) 5.将R0寄存器第[15:11]位设置为10101,其他位不变 思想:想要将一个数据的哪几位设置为不同的数值,先将这几位清0,在给上指定的位数 先将[15:11]清0:bic r0,r0,#(0X1f<<11) 在给[15:11]设置为10101:orr r0,r0,#(0X15<<11)

5.算数运算指令

5.1 指令码以及格式

格式: <opcode>{<cond>}{s} <Rd>, <Rn>, <shifter_operand> 指令码: add:加法运算 Rd=Rn+shifter_operand adc:进行加法运算时考虑CPSR的C位 Rd=Rn+shifter_operand+CPSR[c] sub:减法运算 Rd=Rn-shifter_operand sbc:进行减法运算时考虑CPSR的c位 Rd=Rn-shifter_operand-!CPSR[c] RSB :逆向减法Rd=shifter_operand-Rn RSC:带借位的逆向减法指令 Rd = shifter_operand – Rn - !CPSR[c] mul:乘法运算 Rd=Rn*shifter_operand

5.2 示例代码

加法

.text .global _start _start: mov r0,#0XFFFFFFFE mov r1,#3 adds r2,r0,r1 @0X1,运算的结果影响到条件位 adc r3,r1,r2 @r3=r1+r2+CPSR[c] loop: b loop .end

减法:

.text .global _start _start: mov r0,#0XFFFFFFFE mov r1,#3 subs r2,r1,r0 @减法不借位,c位置1,借位,c位清0 mov r3,#6 sbc r4,r3,r1 @r4=r3-r1-!CPSR[c] loop: b loop .end

5.3 进行64位算数运算

思想:让低32位和高32位进行分别运算,每一个64位的数高32位和低32位数值保存在两个寄存器中

MOV R1,#0xfffffffe @第一个数据的低32位 mov r2,#0x00000004 @第一个数据的高32位 MOV R3,#0x00000005 @第二个数据的低32位 mov r4,#0x00000004 @第二个数据的高32位 加法: 低32位: adds r5,r1,r3 高32位: adc r6,r2,r4 减法: 低32位: subs r5,r3,r1 高32位: sbc r6,r4,r2

6.数据比较指令

6.1 语法

格式: cmp <Rn>, <shifter_operand> 比较指令的本质: 拿第一操作寄存器和第二操作数进行减法运算,并且减法运算的结果会影响到CPSR的条件位 可以根据比较指令之后的条件位的数值进行不同的运算,相当于c里的选择语句 这里需要对CPSR的条件位进行判断,我们依赖条件位的助记词{cond}后缀实现

6.2 示例

.text .global _start _start: MOV R1,#4 MOV R2,#4 CMP R1,R2 addeq r3,r1,r2 @if(r1==r2) r3=r1+r2 subne r4,r1,r2 @if(r1!==r2) r4=r1-r2 loop: b loop .end

7.跳转指令

一般实现程序的跳转有两种方式:

1.直接修改PC的值 2.通过跳转指令 跳转指令:

1.b label 解释:跳转到label标签所在代码,此时跳转,lr寄存器不保存返回地址

ex:

.text .global _start

_start: MOV R1,#4

MOV R2,#4

CMP R1,R2

beq addfunc

bne subfunc

addfunc:

       add r3,r1,r2

         b loop

subfunc: sub r4,r1,r2 @if(r1!==r2) r4=r1-r2 b loop loop: b loop .end

2. bl label 解释:跳转到label标签所在代码,此时跳转,lr寄存器保存返回地址 ex: .text .global _start _start: MOV R1,#4 MOV R2,#4 CMP R1,R2 bleq addfunc blne subfunc addfunc: add r3,r1,r2 mov pc,lr @程序返回 subfunc: sub r4,r1,r2 @if(r1!==r2) r4=r1-r2 mov pc,lr @程序返回 loop: b loop .end

3. bx 地址 跳转到地址对应的的指令位置,此时跳转LR不保存返回地址 .text .global _start _start: MOV R1,#4 MOV R2,#4 MOV R3,#4 MOV R4,#4 MOV R5,#4 MOV R6,#4 bx r3 @跳转到地址为4的指令位置 loop: b loop .end 4.blx 地址 跳转到地址对应的的指令位置,此时跳转LR保存返回地址 .text .global _start _start: MOV R1,#4 MOV R2,#4 MOV R3,#4 MOV R4,#4 MOV R5,#4 blx r3 @跳转到地址为4的指令位置 MOV R6,#4 loop: b loop .end

任务

1.复习今日内容

2.实现1-100,累加

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/118390.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

淘宝婴儿用品购买情况分析报告

一.分析背景和目的 随着购物网站的发展&#xff0c;人们的网络购物行为占比也快速增加。为了能够获取更多的用户&#xff0c;提升商家的销售量&#xff0c;需要从产品和用户不同的角度进行分析&#xff0c;进而得到有价值的信息&#xff0c;指导商家进行获客和营销。本文就以淘…

NOIP2023模拟12联测33 D. 滈葕

NOIP2023模拟12联测33 D. 滈葕 文章目录 NOIP2023模拟12联测33 D. 滈葕题目大意思路code 题目大意 思路 放一段题解的材料 ABO 血型系统是血型系统的一种&#xff0c;把血液分为 A,B,AB,O 四种血型。血液由红细胞和血清等组成&#xff0c;红细胞表面 有凝集原&#xff0c;血清…

R语言环境下使用curl库做的爬虫代码示例

curl库是一个用于传输数据的工具和库&#xff0c;它支持多种协议&#xff0c;包括HTTP、FTP、SMTP等。在爬虫中&#xff0c;curl库可以用来获取网页内容&#xff0c;从而实现爬取网页的功能。通过设置curl的选项&#xff0c;可以实现对网页的请求、响应、重定向等操作。在使用c…

学习笔记三十三:准入控制

ResourceQuota准入控制器 ResourceQuota准入控制器限制cpu、内存、pod、deployment数量限制存储空间大小 LimitRanger准入控制器在limit名称空间创建pod&#xff0c;不指定资源&#xff0c;看看是否会被limitrange规则自动附加其资源限制创建pod&#xff0c;指定cpu请求是100m&…

django安装数据库

使用pip安装django pip3 install django注意我使用的是python3所以用pip3安装&#xff0c;如需安装指定版本 django ..* 检测是否安装成功,不报错&#xff0c;则安装成功 # python3 # import django下边这是报错的 django迁移数据库 再mysql中简历数据库 CREATE DATABA…

【系统集成项目管理工程师】——3.管理

主要掌握输入&#xff0c;输出内容先看他的过程域本身&#xff0c;过程域是什么输出就是什么 上一个过程域的输出是下一个过程域的输入 十大管理1432都有计划过程组&#xff0c;通常规划为首&#xff0c;控制为尾 规划阶段的万能输出是各子计划&#xff0c;即项目管理计划的…

加法运算、 || 、 赋值运算

一、加法运算 在这里插入图片描述 二、&& || 三、赋值运算 四、js类型就八种&#xff1a; 五、css权重、 六&#xff1a;布局&#xff0c;尽量使用块盒。 七、小数精度存储的问题&#xff1a;存的不精确&#xff0c;算的肯定也是有问题的。 八、找单身狗算法题…

20.7 OpenSSL 套接字SSL加密传输

OpenSSL 中的 SSL 加密是通过 SSL/TLS 协议来实现的。SSL/TLS 是一种安全通信协议&#xff0c;可以保障通信双方之间的通信安全性和数据完整性。在 SSL/TLS 协议中&#xff0c;加密算法是其中最核心的组成部分之一&#xff0c;SSL可以使用各类加密算法进行密钥协商&#xff0c;…

预处理、编译、汇编、链接

1.预处理 宏替换去注释引入头文件 #之后的语句都是预处理语句&#xff0c; #include<iostream> 将该文件的内容拷贝到现有文件中&#xff0c; 2.编译 3.汇编 4.链接 gcc 基于C/C的编译器 补充说明 gcc命令 使用GNU推出的基于C/C的编译器&#xff0c;是开放源代…

接口自动化测试分层设计与实践总结01

本文以笔者当前使用的自动化测试项目为例&#xff0c;浅谈分层设计的思路&#xff0c;不涉及到具体的代码细节和某个框架的实现原理&#xff0c;重点关注在分层前后的使用对比&#xff0c;可能会以一些伪代码为例来说明举例。 接口测试三要素&#xff1a; 参数构造 发起请求&…

5个高质量图片处理软件,抠图、特效不求人!

作为一个设计师或摄影家或者平面设计工作人员&#xff0c;又或者是普通人&#xff0c;只要你有图片处理的需求&#xff0c;就不可避免的会需要一个好用高效的图片处理网站&#xff0c;会抠素材&#xff0c;找图片&#xff0c;删除图片内容等等&#xff0c;都需要花费大量的时间…

软件开发必备神器!一文读懂10款热门看板工具推荐!

看板&#xff08;Kanban&#xff09;是一种流行的框架&#xff0c;用于实施敏捷和DevOps软件开发。它要求实时沟通每个人的能力&#xff0c;并全面透明地展示正在进行的工作。工作项目在看板上以可视化方式表示&#xff0c;使项目经理和所有团队成员可以随时查看每个工作的状态…

下载安装各种版本的Vscode以及解决VScode官网下载慢的问题

下载指定版本 在Vscode官网 Vscode官网更新子页 这里的左侧栏点击其中一个会跳转到某个版本&#xff0c;或者在官网子页 https://code.visualstudio.com/updates的后面跟上需要的版本号即可完成目标版本下载页面的跳转 选择Linux里的ARM包不会自动下载而是跳转到另一个页面 …

HTTP 协议详解-上(Fiddler 抓包演示)

文章目录 HTTP 协议HTTP 协议的工作过程HTTP 请求 (Request)认识URL关于 URL encode认识 "方法" (method)GET 方法POST 方法其他方法请求 "报头" (header)请求 "正文" (body) HTTP 响应详解状态码响应 "报头" (header) HTTP 协议 HTT…

MySQL第五讲·关于外键和连接, 如何做到关联查询?

你好&#xff0c;我是安然无虞。 文章目录 外键和连接&#xff1a;如何做关联查询&#xff1f;如何创建外键&#xff1f;连接关联查询中的误区 外键和连接&#xff1a;如何做关联查询&#xff1f; 在实际的数据库应用开发过程中&#xff0c;我们经常需要把2个或2个以上的表进…

在CentOS上安装SQL Server,并通过cpolar内网穿透实现数据库的公网访问

文章目录 前言1. 安装sql server2. 局域网测试连接3. 安装cpolar内网穿透4. 将sqlserver映射到公网5. 公网远程连接6.固定连接公网地址7.使用固定公网地址连接 前言 简单几步实现在Linux centos环境下安装部署sql server数据库&#xff0c;并结合cpolar内网穿透工具&#xff0…

【Redis】hash数据类型-常用命令

文章目录 前置知识常用命令HSETHGETHEXISTSHDELHKEYSHVALSHGETALLHMGET关于HMSETHLENHSETNXHINCRBYHINCRBYFLOAT 命令小结 前置知识 redis自身就是键值对结构了&#xff0c;哈希类型是指值本⾝⼜是⼀个键值对结构&#xff0c;形如key"key"&#xff0c;value{{field1…

学习笔记二十八:K8S控制器Daemonset入门到企业实战应用

DaemonSet控制器&#xff1a;概念、原理解读 DaemonSet概述DaemonSet工作原理&#xff1a;如何管理PodDaemonset典型的应用场景DaemonSet 与 Deployment 的区别DaemonSet资源清单文件编写技巧 DaemonSet使用案例&#xff1a;部署日志收集组件fluentdDaemonset管理pod&#xff1…

牛客网刷题-(11)

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏:PYTHON学习系列专栏&#x1f4ab;"没有罗马,那就自己创造罗马~" 目录 (1)输出1-100的所有奇数 (2)计算输入6个数字中正数的个数 (3)递增序列 (4)PUM (1)输出1-100的所有奇数 #输出1-100的所有奇数 x…

OSPF 高级特性3

目录 一、OSPF安全特性 二、加快收敛 三、缺省路由 四、路由控制 五、显示OSPF的错误统计信息 附录E&#xff08;了解&#xff09; 六、OSPF防环 七、OSPF选路原则 八、OSPF综合实验 一、OSPF安全特性 1、OSPF报文验证&#xff1a; 区域验证模式&#xff1a;在区域下配…