C嵌入汇编之vld1.f32和vst1.f32指令理解

news/2025/3/5 9:45:13/

想完成类似与memcpy,使用arm的neon指令完成,第一次代码

关键点

第一点:

add %0,%0,#32,表示每次移动32/4=8个float

第二点:

subs r0,r0,#1才能改变状态标志位,sub不行

第三点:

vld1.f32 {d16-d17},[%0:128]

add %0,%0,#16   //16=128/32*4,移动%0到第四个位置

vld1.f32 {d16-d17},[%0:128]!

是一个意思,这里加个!表示做完vld,并将%0更新(加上其传送的字节数)!

以下代码是为了验证当内嵌汇编程序传入参数过多时,可以通过连续内存来传参,具体规则可以参考https://www.cnblogs.com/crmn/articles/6580139.html

主要几点:

1、子程序间通过寄存器r0-r3传参,寄存器r4-r11来保存局部变量,如果在子程序中用到了r4-r11,需要保存这些寄存器的值;

2、对于参数个数可变的子程序,当参数不超过4个时,可以使用寄存器R0~R3来进行参数传递,当参数超过4个时,还可以使用数据栈来传递参数,在参数传递时,将所有参数看做是存放在连续的内存单元中的字数据。然后,依次将各名字数据传送到寄存器R0,R1,R2,R3;

3、 对于参数个数固定的子程序,参数传递与参数个数可变的子程序参数传递规则不同,如果系统包含浮点运算的硬件部件。      浮点参数将按照下面的规则传递:   (1)各个浮点参数按顺序处理;      (2)为每个浮点参数分配FP寄存器;        分配的方法是,满足该浮点参数需要的且编号最小的一组连续的FP寄存器.第一个整数参数通过寄存器R0~R3来传递,其他参数通过数据栈传递.

4、子程序结果返回规则:1.结果为一个32位的整数时,可以通过寄存器R0返回.2.结果为一个64位整数时,可以通过R0和R1返回,依此类推. 3.结果为一个浮点数时,可以通过浮点运算部件的寄存器f0,d0或者s0来返回.  4.结果为一个复合的浮点数时,可以通过寄存器f0-fN或者d0~dN来返回.5.对于位数更多的结果,需要通过调用内存来传递.

看完这篇博客后,我感觉还是很晕,于是采用了下面的方法:

int za1[8] = { 0,1,2,3,4,5,6,7 };
int za2[8] = { 10,11,12,13,14,15,16,17 };
int za3[8] = { 30,31,32,33,34,35,36,37 };
int za4[8] = { 40,41,42,43,44,45,46,47};
int za5[8] = { 50,51,52,53,54,55,56,57 };
int za6[8] = { 60,61,62,63,64,65,66,67};
int za7[8] = { 70,71,72,73,74,75,76,77};
int* test_data = (int*)malloc(4*sizeof(int));
int* tmp[] = { za1,za2,za3,za4,za5,za6,za7};	//
int** tmp_addr = tmp;
__asm__ volatile(
//"ld1  {v0.16b}, [%0],#16  \n"
//"vld1.f32 {d0-d1},[%0:128] \n"
"ldr r0,[%0,#20] \n"				//za6
"add r0, r0,#4 \n"                      //r0偏移4个字节,即加载61 62 63 64
"vld1.f32 {d0-d1},[r0] \n"		//:128表示字节对齐
"vst1.f32 {d0-d1},[%1]  \n":"=r"(tmp_addr),
"=r"(test_data):"0"(tmp_addr),
"1"(test_data)
);
printf("res\n");
for (int zz = 0; zz < 4; zz++)
{printf("%8d",test_data[zz]);
}
printf("\n");

通过tmp_addr指向的连续内存,能够获取所需的参数。

写的时候还是需要注意下:

1、数组名不能当参数传入嵌入汇编中,不然会报错。。。(坑了好久)

2、vld.f32 {d0-d1},[r0:128]中的128表示对齐规则,如果不是对齐的,也会有bus error;


http://www.ppmy.cn/news/520359.html

相关文章

%.2f

% .2f 是一个格式化字符串&#xff0c;用于在 Python 程序中格式化浮点数。 其中&#xff0c;% 表示这是一个格式化字符串&#xff0c;.2 表示保留两位小数&#xff0c;f 表示这是一个浮点数。 例如&#xff0c;在 Python 中可以使用如下代码将一个浮点数格式化为字符串&#x…

NEON 常用函数讲解

目录 一、基本的加载存储操作 1. vld1q_f32 2.vst1q_f32 3.vld2q_f32 4.vst2q_f32 5.vld3q_f32 6.vst3q_f32 7.vld4q_f32, vst4q_f32 二、特殊操作 1.vdupq_n_f32 2.vzipq_f32 3.vuzpq_f32 4.vcombine_f32 5. vget_low_f32 6. vget_high_f32 7. vtrnq_f32 8. v…

【电赛仪器仪表】基于MATLAB的数字滤波器设计与ARM官方DSP库的结合

主要内容 Ⅰ. 数字滤波器基础知识1.数字滤波器的概念2.数字滤波器的分类3.数字滤波器的技术指标 Ⅱ.使用MATLAB软件设计两类数字滤波器1.FIR滤波器1)窗函数简介2)filterDesigner使用 2.IIR滤波器 Ⅲ.数字滤波器与官方DSP库结合使用1.DSP库的安装使用2.DSP库滤波器函数介绍1)FIR…

TMS320F28335调用官方库进行FFT频谱分析

移植 首先进入TI官网下载软件支持包&#xff0c;我们需要的FFT官方包就在这里边。 TMS320F28335 data sheet, product information and support | TI.com 下载完成后&#xff0c;解压。进入以下目录 C2000Ware_4_01_00_00_Software__all\C2000Ware_4_01_00_00\libraries\dsp…

【STM32】STM32F4调用DSP库实现FFT运算

写在前面 最近在整理之前的stm32笔记&#xff0c;打算把一些有价值的笔记发到CSDN分享一下。 奎斯特定理 在进行模拟/数字信号的转换过程中&#xff0c;当采样频率F大于信号中最高频率 fmax 的 2 倍时(F>2*fmax)&#xff0c;采样之后的数字信号完整地保留了原始信号中的信…

【STM32】 DSP库函数的一些基本使用

对于一些刚接触STM32的童靴来说&#xff0c;DSP库一定是一个陌生的东西。通俗来说&#xff0c;DSP库就是为了让MCU能够使用像DSP&#xff08;数字信号处理的芯片&#xff09;功能弄的一些官方库函数&#xff0c;它是基于MCU的FPU&#xff08;浮点运算功能&#xff09;的&#x…

STM32_arm_sin_f32和sin的区别

FOC控制中会用到三角函数 调试通信的时候&#xff0c;也会用三角函数产生一个测试波形 优化三角函数的运行时间是一个不可避免的事情&#xff0c;而幸运的是&#xff0c;前人已经把树种上了。 用专用的浮点运算单元FPU来做浮点运算&#xff0c;比用STM32本身来做浮点运算要快…

STM32F1 FFT初试

1、STM32有dsp库&#xff0c;百度一堆的文章&#xff0c;注意有f4有硬件fft可以使用arm_rfft_fast_init_f32&#xff0c;F1不能使用&#xff0c;F1可以使用arm_cfft_radix4_init_f32&#xff0c;256长度1024长度&#xff0c;arm_cfft_radix2_init_f32 512长度。 2、采样率FFT_S…