作者简介:大家好我是IM汤姆凯特,大家可以叫我汤姆
个人主页:IM汤姆凯特的CSDN博客
系列专栏:【ARM嵌入式基础】
如果觉得博主的文章还不错的话,请👍三连支持一下博主哦🤞
学完ARM汇编语言的所有指令,发现有个指令很有意思——RSB(RSB称为逆向减法指令)
当我们接触到一个新知识的时候,不妨想一下,这个概念为什么会出现,它能帮助我们解决什么问题呢?
带着这个疑问,我想到了绝对值的运算
思考:
RSB是逆向减,如果后面一个数为“0”,然后让它逆向减前面的一个数,那不就是他的绝对值吗嘛!
- 那如果是非负数呢,还需要让它逆向减吗?
- 因此,我们需要做一个判断,如果为正数则直接输出,如果为负数则进行逆向减。
- 那在ARM汇编中如何进行判断呢?
- CMP语句可以进行判断,然后我们让这个数与“0”进行判断,然后将两个语句组合到一起,当比较完小于的时候进行逆向减。
哦,可以用RSB来求绝对值运算!
思路清晰了,我们就可以直接开始写代码
之前我们都是先写C语言转换成汇编之后然后进行学习,但学了汇编框架之后,我们可以直接来试着写一下——ARM汇编语言框架可以详见这篇文章【ARM汇编框架】
1)先上框架
.data
……
.text
.globl main
main:
stmfd sp!,{lr}
……
mov r0,#0
ldmfd sp!,{lr}
mov pc,lr
.end
2)然后定义两个全局变量(打印的格式、常量)
.data
fmt:.asciz "\n abs(%d)=%d\n"
a:.word -100
3)之前我们说过,从内存中取值需要两步走,先取地址,再读值。
ldr r0,=a
ldr r4,[r0]
4)然后就是核心代码部分,判断是否大于“0”,如果小于零进行逆向减,然后将值存到一个寄存器中
cmp r4,#0
rsblt r5,r4,#0
ldr r0,=fmt
mov r1,r4 //将原本值传给r1
mov r2,r5 //将取绝对值后的值传给r2
这里就用到了RSB,后面加上判断标识LT(带符号数的小于)
很多小伙伴不太明白为什么最后用printf语句输出时必须要放到r1~r3中,后面我会专门写一篇给大家讲清楚。
那么让我们来看一下源代码和运行效果吧:
本期ARM汇编求绝对值就结束了,我们下期再见!
如有疑问或错误,欢迎大家评论区留言指出,谢谢支持!!
下期预告:ARM汇编中MOV和LDR的区别