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

【ASMbits--常用算术运算指令】

ASMbits--常用算术运算指令

  • 1 基本运算算术指令--最基础
    • 1.1 加法和减法
    • 1.2 移位操作
    • 1.3 乘法
  • 2 practice
    • 2.1 编写invert(int n)
    • 2.2 编写judge_odd(int n)
    • 2.3 计算绝对值abs(int n)
    • 2.4 add(int n1, int n2)函数
    • 2.4 shift寄存器
    • 2.5 sihft ath right
    • 2.6 shift left

在ARMv7汇编中,代码片段:

1: b 1b	//Done

作用是创建一个无限循环,使程序永远停留在当前位置,不在执行后续命令;

语法解释:

  • 1::这是一个局部标签(local label)。在 ARM 汇编中,以数字开头的标签(如 1:)是局部标签,可以通过 b 1b 或 b 1f 引用。
    1b:表示向后查找最近的 1: 标签(Backward)。
    1f:表示向前查找最近的 1: 标签(Forward)。

  • b 1b:这是一个分支指令(Branch),跳转到最近的 1: 标签(向后查找)。由于标签 1: 就在当前行,这条指令会无限循环跳转到自身。

代码 1: b 1b 的作用是让程序在当前位置无限循环,防止后续未定义代码的执行。这是裸机编程或嵌入式系统中常见的“安全终止”方法。
具体在裸机程序(无操作系统)或嵌入式系统中,这种无限循环常用于:

  • 防止程序执行到未定义的内存区域(例如代码结束后未初始化的内存)。
  • 保持程序在完成所有任务后“挂起”(例如在调试时观察结果);

1 基本运算算术指令–最基础

1.1 加法和减法

  • ADD 加法
    语法:ADD{条件}{S} 目标寄存器, 操作数1, 操作数2
    功能:将操作数1和操作数2相加,结果存入目标寄存器。
ADD R0, R1, R2     @ R0 = R1 + R2
ADD R3, R4, #10    @ R3 = R4 + 10
  • SUB减法
    语法:SUB{条件}{S} 目标寄存器, 操作数1, 操作数2
    功能:从操作数1中减去操作数2,结果存入目标寄存器。
SUB R0, R1, R2     @ R0 = R1 - R2
SUB R3, R4, #5      @ R3 = R4 - 5

1.2 移位操作

  • LSL逻辑左移
    语法:LSL{条件}{S} 目标寄存器, 操作数, 移位位数
    功能:将操作数左移指定位数,低位补零。
LSL R0, R1, #4      @ R0 = R1 << 4
  • LSR逻辑右移
    语法:LSR{条件}{S} 目标寄存器, 操作数, 移位位数
    功能:将操作数右移指定位数,高位补零。
LSR R0, R1, #3      @ R0 = R1 >> 3(无符号)
  • ASR(算术右移)
    语法:ASR{条件}{S} 目标寄存器, 操作数, 移位位数
    功能:将操作数右移指定位数,高位补符号位(用于有符号数)
ASR R0, R1, #2      @ R0 = R1 >> 2(保留符号)
  • ROR循环右移
    语法:ROR{条件}{S} 目标寄存器, 操作数, 移位位数
    功能:将操作数循环右移指定位数,移出的位补到高位。
ROR R0, R1, #8      @ R0 = R1 循环右移8位

1.3 乘法

  • MUL无符号乘法
    语法:MUL{条件}{S} 目标寄存器, 操作数1, 操作数2
    功能:操作数1 × 操作数2,结果低32位存入目标寄存器。
MUL R0, R1, R2     @ R0 = (R1 × R2) 的低32位
  • MIL乘加
    语法:MLA{条件}{S} 目标寄存器, 操作数1, 操作数2, 操作数3
    功能:操作数1 × 操作数2 + 操作数3。
MLA R0, R1, R2, R3  @ R0 = (R1 × R2) + R3

2 practice

2.1 编写invert(int n)

Write a function that returns the bitwise inversion of its parameter.
int invert (int n);

.global _start
_start:
    mov r0, #1
    bl invert
    1: b 1b    // Done

.global invert
invert:
    MVN r0,r0  // MVN把R0里面的数取反然后再进行存储
    BX lr	//return caller

2.2 编写judge_odd(int n)

算法:最低位是0还是1,若是1则odd为1,若是为0,则odd为0;如何获得最低位呢,直接使用n & 1;
Steps:

  1. 将r0与1进行AND操作,结果存在某个寄存器,比如r0本身。
  2. 然后比较这个结果是否为0,如果不为0,则返回1,否则返回0。
.global _start
_start:
    mov r0, #1
    bl odd
    1: b 1b    // Done

.global odd
odd:
	AND r0,r0,#1
    BX lr
	

2.3 计算绝对值abs(int n)

算法:进制补码中,负数的符号位是1,正数或零是0。所以,如果我能得到符号位的掩码,可能可以用异或和减法来计算绝对值。比如,对于n,如果符号位是0,那么绝对值是n本身;如果符号位是1,绝对值是~n + 1。或者用另一种方法:将n与符号位的掩码异或,然后减去掩码。这可能更高效。
步骤:

  1. 将n算术右移31位,得到mask(0或-1)。
  2. 异或n和mask,得到n ^ mask。
  3. 减去mask,即(n ^ mask) - mask。因为mask是0或-1,当mask是-1时,减法相当于加1。
.global _start
_start:
    mov r0, #10
    bl abs
    1: b 1b    // Done

.global abs
abs:
    ASR r1, r0, #31	// r1 = n>>31 to generate mask
    EOR r0, r0, r1		// r0 = n ^ mask
    SUB r0, r0, r1		// r0 = r0 - mask
    BX lr
	

2.4 add(int n1, int n2)函数

即第一个参数传递给R0,第二个参数传递给R1;

.global _start
_start:
    mov r0, #1  // First function parameter is always passed through r0.
    mov r1, #1  // Second function parameter is always passed through r1.
    bl add      // Return value is always in r0.
    1: b 1b     // Done

.global add
add:
    ADD R0,R0,R1
    BX LR
	

2.4 shift寄存器

即将该参数移位到24位,低8位;

.global _start
_start:
    ldr r0, =0x12345678
    bl shift
    b _start        // End of testing code

// Convert one U32 sample to U8 format
shift:
    LSR r0,r0,#24	//将输入参数 r0 右移24位,保留高8位到低8位
    BX lr

2.5 sihft ath right

// A test case to test your function with

.global _start
_start:
    ldr r0, =0x40000
    bl shift
    b _start        // End of testing code

// Return 1/4 amplitude for a S32 sample
shift:
	ASR r0,r0,#2	//算数右移
    BX lr

2.6 shift left

// A test case to test your function with

.global _start
_start:
    ldr r0, =0x1234
    bl shift
    b _start        // End of testing code

// Convert one S16 to S32 format
shift:
	LSL R0,R0,#16	// left shift 16
    BX lr

以上是ARMv7汇编语言的常见算术指令运算;


http://www.kler.cn/a/588529.html

相关文章:

  • 深入解析 FID:深度学习生成模型评价指标
  • pyQT学习笔记——Qt常用组件与绘图类的使用指南
  • 【商城实战(36)】UniApp性能飞升秘籍:从渲染到编译的深度优化
  • 使用memmove优化插入排序
  • 软件架构设计习题及复习
  • 计算机网络——NAT
  • 【Linux】Socket 编程 TCP
  • 《Python深度学习》第四讲:计算机视觉中的深度学习
  • 在Simulink中将Excel数据导入可变负载模块的方法介绍
  • 工程化与框架系列(30)--前端日志系统实现
  • cursor全栈网页开发最合适的技术架构和开发语言
  • JVM系统变量的妙用
  • 树莓派 连接 PlutoSDR 教程
  • Typedef 与enum的使用
  • 【人工智能基础2】人工神经网络、卷积神经网络基础、循环神经网络、长短时记忆网络
  • [蓝桥杯]花束搭配【算法赛】
  • python+MySQL+HTML实现产品管理系统
  • Ollama+DeepSeek+NatCross内网穿透本地部署外网访问教程
  • Flutter:竖向步骤条,类似查看物流组件
  • 一周学会Flask3 Python Web开发-SQLAlchemy更新数据操作-班级模块