当前位置: 首页 > news >正文

用ARM进行汇编语言编程(4)带有分支的循环和条件指令执行

ARM 编程模拟器

ARM 编程模拟器网站地址:

https://cpulator.01xz.net/?sys=arm-de1soc

在arm里也有和高级语言一样的for和while循环,可以根据条件来判断是否执行

带有分支的循环

首先我们创建一个data标签,然后在里面写一个分支,存放一些数值,然后使这些存放的数值依次相加

.global _start
_start:
	
.data   //data段,用于存放数据
list:   //定义的变量名
	.word 1,2,3,4,5,6,7,8,9,10  //.word:告诉程序每一个值都是word类型,大小为32位,用于存放数据

在这里插入图片描述

然后我们要将list加载到内存里

.global _start
_start:
	ldr r0,=list  //ldr:将data段里list中的数据加载到r0寄存器中
	 
.data
list:
	.word 1,2,3,4,5,6,7,8,9,10

然后使用直接寻址,将r0寄存器里的值放到r1寄存器里

.global _start
_start:
	ldr r0,=list
	ldr r1,[r0]   //汇编程序寻找r0寄存器地址中的值,移动到r1寄存器里
	
.data
list:
	.word 1,2,3,4,5,6,7,8,9,10

然后我们可以使用加法,将第一个值添加到r2寄存器里

.global _start
_start:
	ldr r0,=list
	ldr r1,[r0]   
	add r2,r2,r1  //r2 = r2 + r1 
	
.data
list:
	.word 1,2,3,4,5,6,7,8,9,10

在这里插入图片描述

现在按f5执行程序,看看内存里是什么样子的

在这里插入图片描述

存放的都是list里的值,1-10,之后就都是aaaaaaaa,aaaaaaaa的意思是内存中空闲的位置,我们可以利用这个aaaaaaaa,使遍历列表的时候告诉程序这就是列表的末尾了

我们可以将aaaaaaaa存放到某个变量里,但是在arm里,存放的值只能是特定大小,大小为两个十六进制值,明显aaaaaaaa大于了两个十六进制,这里我们就要使用常量了

常量很简单,在程序顶端输入.equ就可以定义了,我们可以给他一个名称和值,这和高级语言中定义常量的方法相同

.global _start
.equ endlist,0xaaaaaaaa   //定义一个常量,名称为endlist,内容为0xaaaaaaaa
_start:
	ldr r0,=list
	ldr r1,[r0]   
	add r2,r2,r1
	
	
.data
list:
	.word 1,2,3,4,5,6,7,8,9,10

在这里插入图片描述

然后可以使用ldr将其加载到内存中

.global _start
.equ endlist,0xaaaaaaaa
_start:
	ldr r0,=list
	ldr r3,=endlist   //加载到r3寄存器中,之后写循环时方便利用
	ldr r1,[r0]   
	add r2,r2,r1
	
.data
list:
	.word 1,2,3,4,5,6,7,8,9,10

在这里插入图片描述

之后我们就可以开始写循环了,首先创建一个loop标签,加载list里的值

.global _start
.equ endlist,0xaaaaaaaa
_start:
	ldr r0,=list
	ldr r3,=endlist
	ldr r1,[r0]   
	add r2,r2,r1
loop:
	ldr r1,[r0,#4]!   //r0寄存器里的值偏移4字节,移动到r1寄存器里,然后他会查看内存中的那个位置是否是空的,之后将值存放在这里

.data
list:
	.word 1,2,3,4,5,6,7,8,9,10

在这里插入图片描述

然后我们比较两个r1,r3,如果他们相等,我们就离开循环

.global _start
.equ endlist,0xaaaaaaaa
_start:
	ldr r0,=list
	ldr r3,=endlist
	ldr r1,[r0]   
	add r2,r2,r1
loop:
	ldr r1,[r0,#4]!
	cmp r1,r3   //比较这两个寄存器
	beq exit   //小于等于则调用exit标签
	
.data
list:
	.word 1,2,3,4,5,6,7,8,9,10

然后创建一个exit标签,不用写内容,他的作用就是程序的出口点

.global _start
.equ endlist,0xaaaaaaaa
_start:
	ldr r0,=list
	ldr r3,=endlist
	ldr r1,[r0]   
	add r2,r2,r1
loop:
	ldr r1,[r0,#4]!
	cmp r1,r3
	beq exit
	
exit:  //exit标签

.data
list:
	.word 1,2,3,4,5,6,7,8,9,10

在这里插入图片描述

如果我们还没达到list的末尾,我们可以添加值到r2寄存器里,然后再次循环直到到达末尾

.global _start
.equ endlist,0xaaaaaaaa
_start:
	ldr r0,=list
	ldr r3,=endlist
	ldr r1,[r0]   
	add r2,r2,r1
loop:
	ldr r1,[r0,#4]!
	cmp r1,r3
	beq exit
	add r2,r2,r1  // //r2 = r2 + r1 
	bal loop  //然后通过跳转指令建立一个无限循环,直到r1和r3相等,到达list末尾
exit:

.data
list:
	.word 1,2,3,4,5,6,7,8,9,10

这就是一个完整的循环,作用是遍历list,使里面的值依此相加
之后运行程序

在这里插入图片描述

然后进入循环,在循环10次后退出程序

在这里插入图片描述
在这里插入图片描述

1到10相加就等于55

条件指令执行

条件指令可以根据运算结果更新的条件标志,来判断指令的条件码是否符合条件,符合条件就执行,不符合条件则不执行

现在我们随便在寄存器里放一些值,然后比较

.global _start
_start:
	mov r0,#2
	mov r1,#4
	cmp r0,r1

在这里插入图片描述

如果r0小于r1,就在r2寄存器里放入一个值

.global _start
_start:
	mov r0,#2
	mov r1,#4
	cmp r0,r1
	blt addr2   //如果r0小于r1,就调用addr2标签

addr2:
	add r2,#1  //r2+1

然后设置一个退出程序的出口

.global _start
_start:
	mov r0,#2
	mov r1,#4
	cmp r0,r1
	blt addr2
	bal exit  //跳转到exit标签里

addr2:
	add r2,#1
	
exit:

在这里插入图片描述

仅仅实现这么简单的一个功能,需要的代码也太多了,有没有其他方法呢,我们可以使用条件指令来少写一些代码

还是随便在寄存器里放一些值然后比较

.global _start
_start:
	mov r0,#2
	mov r1,#4
	cmp r0,r1

之后可以使用addlt指令

addlt:意思是加小于(+<),这个指令只会触发比较结果小于的情况
.global _start
_start:
	mov r0,#2
	mov r1,#4
	cmp r0,r1
	addlt r2,#1

在这里插入图片描述

只用四行代码就实现了上面的功能,我们执行看看

在这里插入图片描述

可以看到,确实实现了我们想要的功能

比如还有movge……很多组合,这样可以使程序更加简洁

movge:比较结果是大于等于之后进行移动操作

总结

这是我学习的笔记,有什么错误和不懂的地方欢迎来私信我,或者加我qq

相关文章:

  • Postgresql源码(77)plpgsql中参数传递和赋值
  • CSAPP datalab
  • Github爆火,阿里最新发布的《高并发核心编程笔记》PDF文档
  • ntohl()、htonl()、ntohs()、htons()函数
  • 基于ssm+vue的师生防疫登记管理系统 elementui
  • trustZone学习
  • USB转多串口设备固定串口号
  • 七牛云 OSS 文件上传demo
  • 我的VS2013版本
  • .NET DataGridView数据绑定说明
  • 商业化广告--体系学习--1
  • apk反编译和重新打包流程
  • Spring Security -- 前后端分离时的安全处理方案
  • 使用HttpServlet和@WebServlet注解
  • Arthas使用指北——命令、原理及案例
  • #Java异常处理
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • Effective Java 笔记(一)
  • JavaScript HTML DOM
  • opencv python Meanshift 和 Camshift
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • supervisor 永不挂掉的进程 安装以及使用
  • vue-router 实现分析
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 闭包--闭包之tab栏切换(四)
  • 不上全站https的网站你们就等着被恶心死吧
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 目录与文件属性:编写ls
  • 前端自动化解决方案
  • 入口文件开始,分析Vue源码实现
  • 设计模式(12)迭代器模式(讲解+应用)
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (C语言)球球大作战
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (过滤器)Filter和(监听器)listener
  • (原創) 未来三学期想要修的课 (日記)
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转) ns2/nam与nam实现相关的文件
  • .gitignore
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .NET构架之我见
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc
  • .net生成的类,跨工程调用显示注释
  • .NET委托:一个关于C#的睡前故事
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • @开发者,一文搞懂什么是 C# 计时器!
  • [ SNOI 2013 ] Quare
  • []指针
  • [AutoSar NVM] 存储架构