stm32汇编FMULS、FNMULS区别
时间: 2023-08-03 08:09:30 浏览: 147
在STM32汇编中,FMULS和FNMULS都是浮点数乘法指令,但它们有一些区别。
FMULS指令用于执行两个浮点数的乘法操作,结果存储在一个单精度浮点寄存器中。该指令的语法为:
```
FMULS Sd, Sn, Sm
```
其中Sd是目标寄存器,Sn和Sm是源寄存器。指令执行后,结果存储在Sd寄存器中。
而FNMULS指令也执行两个浮点数的乘法操作,但是在计算结果之前,它会将其中一个操作数取反。结果存储在一个单精度浮点寄存器中。该指令的语法为:
```
FNMULS Sd, Sn, Sm
```
其中Sd是目标寄存器,Sn和Sm是源寄存器。指令执行后,结果存储在Sd寄存器中。
因此,FMULS和FNMULS的区别在于是否对其中一个操作数进行了取反操作。
相关问题
stm32汇编FMULS
在STM32的汇编指令集中,FMULS是用于浮点数乘法的指令。它的语法格式如下:
```
FMULS S<opA>, S<opB>
```
其中,opA和opB是两个操作数,都是单精度浮点数。该指令将这两个操作数相乘,并将结果存储在指定的寄存器中。
例如,要将寄存器S0和S1中的两个浮点数相乘,并将结果存储在S2中,可以使用以下指令:
```
FMULS S2, S0, S1
```
1、利用C语言模拟对信号的采样,得到采样值数组,使用如下采样波 采样波1:2+40*sin(2*pi*i/16+0.5)+5*sin(2*pi*3*i/16) 采样波2:4+127*sin(2*pi*i/16+1.0)+5*sin(2*pi*3*i/16) 采样波3:10+500*sin(2*pi*i/16+1.5)+5*sin(2*pi*3*i/16) 2、利用C语言计算旋转因子,分别得到其实部与虚部数组 3、C语言调用汇编函数,进行DFT运算,得到DFT结果 汇编实现:两层嵌套都要在汇编里边实现。最后的幅度和相位可以在外边实现。 4、通过参数传递和全局变量的使用将结果传回主函数 5、主函数通过调用C语言数学库中的函数得到基波的幅度与相位
好的,我会根据您的需求,给出一个简单的示例代码,帮助您了解如何利用C语言实现DFT运算。
先定义采样波:
```c
#define SAMPLE_SIZE 16
float sample1[SAMPLE_SIZE];
float sample2[SAMPLE_SIZE];
float sample3[SAMPLE_SIZE];
void generate_samples() {
int i;
for (i = 0; i < SAMPLE_SIZE; i++) {
sample1[i] = 2 + 40 * sin(2 * PI * i / SAMPLE_SIZE + 0.5) + 5 * sin(2 * PI * 3 * i / SAMPLE_SIZE);
sample2[i] = 4 + 127 * sin(2 * PI * i / SAMPLE_SIZE + 1.0) + 5 * sin(2 * PI * 3 * i / SAMPLE_SIZE);
sample3[i] = 10 + 500 * sin(2 * PI * i / SAMPLE_SIZE + 1.5) + 5 * sin(2 * PI * 3 * i / SAMPLE_SIZE);
}
}
```
然后定义一个函数来计算旋转因子:
```c
void calc_twiddle_factors(float *twiddle_real, float *twiddle_imag, int size) {
int i;
for (i = 0; i < size; i++) {
twiddle_real[i] = cos(2 * PI * i / size);
twiddle_imag[i] = -sin(2 * PI * i / size);
}
}
```
接下来是DFT运算的核心代码,利用汇编嵌入实现:
```c
#define DFT_SIZE SAMPLE_SIZE
float dft_real[DFT_SIZE];
float dft_imag[DFT_SIZE];
void dft() {
int i, j;
float twiddle_real[DFT_SIZE];
float twiddle_imag[DFT_SIZE];
calc_twiddle_factors(twiddle_real, twiddle_imag, DFT_SIZE);
for (i = 0; i < DFT_SIZE; i++) {
dft_real[i] = 0;
dft_imag[i] = 0;
for (j = 0; j < DFT_SIZE; j++) {
__asm__ __volatile__ (
"flds %1\n\t"
"fmuls %2\n\t"
"flds %3\n\t"
"fmuls %4\n\t"
"flds %5\n\t"
"fmuls %6\n\t"
"flds %7\n\t"
"fmuls %8\n\t"
"faddp %%st, %%st(1)\n\t"
"faddp %%st, %%st(1)\n\t"
"mov %%st, %0\n\t"
: "=&t" (dft_real[i]), "+m" (dft_real[i]), "+t" (sample1[j]), "+t" (twiddle_real[(i * j) % DFT_SIZE]), "+t" (sample2[j]), "+t" (twiddle_real[(2 * i * j) % DFT_SIZE]), "+t" (sample3[j]), "+t" (twiddle_real[(3 * i * j) % DFT_SIZE])
:
: "st", "st(1)"
);
__asm__ __volatile__ (
"flds %1\n\t"
"fmuls %2\n\t"
"flds %3\n\t"
"fmuls %4\n\t"
"flds %5\n\t"
"fmuls %6\n\t"
"flds %7\n\t"
"fmuls %8\n\t"
"faddp %%st, %%st(1)\n\t"
"faddp %%st, %%st(1)\n\t"
"mov %%st, %0\n\t"
: "=&t" (dft_imag[i]), "+m" (dft_imag[i]), "+t" (sample1[j]), "+t" (twiddle_imag[(i * j) % DFT_SIZE]), "+t" (sample2[j]), "+t" (twiddle_imag[(2 * i * j) % DFT_SIZE]), "+t" (sample3[j]), "+t" (twiddle_imag[(3 * i * j) % DFT_SIZE])
:
: "st", "st(1)"
);
}
}
}
```
最后,通过参数传递和全局变量的使用将结果传回主函数:
```c
float dft_magnitude[DFT_SIZE];
float dft_phase[DFT_SIZE];
void calculate_magnitude_and_phase() {
int i;
for (i = 0; i < DFT_SIZE; i++) {
dft_magnitude[i] = sqrt(dft_real[i] * dft_real[i] + dft_imag[i] * dft_imag[i]);
dft_phase[i] = atan2(dft_imag[i], dft_real[i]);
}
}
int main() {
generate_samples();
dft();
calculate_magnitude_and_phase();
float fundamental_magnitude = dft_magnitude[1];
float fundamental_phase = dft_phase[1];
printf("Fundamental magnitude: %f\n", fundamental_magnitude);
printf("Fundamental phase: %f\n", fundamental_phase);
return 0;
}
```
这里使用了C语言的数学库函数`sqrt()`和`atan2()`来计算幅度和相位。
请注意,这只是一个简单的示例代码,实际的DFT运算可能涉及更复杂的算法和数据结构。
阅读全文