在解码 x87 FPU 指令方面,我面临着一个模棱两可的情况。看看下面的指令取自第 2A 卷英特尔指令集手册 [1] 的第 3-380 页。
D9 /0 --> FLD m32fp --> Push m32fp onto the FPU register stack.
D9 C0+i --> FLD ST(i) --> Push ST(i) onto the FPU register stack.
Run Code Online (Sandbox Code Playgroud)
这两条指令都具有相同的单字节基本操作码0xD9。第一条指令的扩展操作码为0x00. 扩展操作码将在 ModR/M 字节的“reg”字段中指定。但第二条指令是一个 2 字节的操作码,具有“添加到获取寄存器”功能。这意味着:
D9 C0 --> FLD ST0
D9 C1 --> FLD ST1
(and so on)
Run Code Online (Sandbox Code Playgroud)
关于区分这两个指令,我有一个小问题。一个小例子是:
现在,假设我得到操作码序列"D9 C1"。如果我需要检查它是否是指令"FLD m32fp",那么我必须检查 ModR/M 字节的“reg”字段是否为 0x00。如果是这样,那么它确实是"FLD m32fp"正在使用的指令。
的二进制表示C1是"1100 0001"。假设bit0是LSB,那么bit3-bit5(含)构成ModR/M字节的'reg'字段"C1" …
我有一个很大的问题fdiv!!!! 我试图划分1/3所以这就是我所做的
.model small
.stack 100h
.data
var1 dd 1
var2 dd 3
var3 dd 2
resultado dt 0.0
.code
mov ax,@data
mov ds,ax
finit
fild var1
fild var2
fdiv
fstp resultado
ffree
.exit
Run Code Online (Sandbox Code Playgroud)
你可以看到我将结果移动到resultado因为我看不到结果st(0)(我正在使用tasm所以我只能在调试器中看到变量)结果应该是3EAAAA3A但我得到了40400000...那就是3!!! 这怎么可能??我试过交换变量而没有!你能帮助我吗??=(
一般来说,我对装配很新,尤其是对FPU的使用.
我正在为学校编写一个计算随机数组标准偏差的作业.
加载数组,平均计算工作正常.整个过程适用于7个或更小值的数组,但返回-1.#IND(这意味着NaN?),数组大小为8或更多元素.
在循环内发生的事情是(均值 - 元素)^ 2值的总和.我不确定发生了什么,但我假设FPU堆栈在某种程度上破坏了.
如果有人能指出我正确的方向,我会非常高兴.
fla = REAL8
; STD DEVIATION
stdDev:
call meanCalcFunc ; fmean = loaded
mov ebx, offset array1 ; Location of Element into EBX
mov ecx, [esp+4] ; ECX = num of elements in array
mov mem1, 0 ; Mem1 = 0
fld mem1 ; ST = 0
fstp fla ; fla = ST = 0
mainFunc:
mov eax, [ebx] ; Array Element into EAX
mov mem1, eax ; Array Element into mem1 …Run Code Online (Sandbox Code Playgroud) 我有一对存储在eax和ecx中的32位浮点数.我可以直接将它们加载到FPU中对它们进行操作,而无需先存储到内存中吗?这将显着简化一些编译器代码,但fld似乎只能在内存上运行.
我在StackOverflow中搜索了很多其他问题,但没有一个真正解决了我的问题.
我正在编写一个linux内核模块,我需要通过将整数除以另一个整数来计算百分比值,以获得介于0和100之间的浮点值:
int v1 = 5;
int v2 = 25;
float perc = v1 / v2;
Run Code Online (Sandbox Code Playgroud)
由于我们已经知道的所有原因,当我尝试编译它时,我得到" SSE寄存器返回并禁用SSE "错误.
是否有解决方案来计算Linux内核模块中的这种划分?
非常感谢.安东尼奥
根据 http://cs.smith.edu/~thiebaut/ArtOfAssembly/CH14/CH14-4.html#HEADING4-5
14.4.4.1 FLD指令
fld mem_32
fld mem_64 [bx]
我的目标是将常数10存储到我的fPU堆栈中。为什么我不能这样做?
__asm
{
move bx, 0x0004;
fld dword ptr[bx] or fld bx;
//-------
fld 0x004; //Since it is 32 bits?
fild 0x004;
}
Run Code Online (Sandbox Code Playgroud) 我注意到,使用我的内联汇编代码要么非常慢,要么停止与我的C++代码相比很快完成.当我在一个不同的函数中调用内联汇编程序而不是让函数被调用的汇编程序时,我很好奇为什么会发生这种情况.我测试了两种方法,发现我的程序在省略该功能时没有冻结.
__asm {
push dword ptr[rw] //rw is a C++ floating-point variable
fld[esp] // Using the stack as temporary storage in order to insert it into the FPU
add esp, 4 //preserving the memory
push dword ptr[lwB]
fld[esp]
add esp, 4
fsubp ST(1), ST(0) // Subtracting rw - lwB
push dword ptr[sp]
fld[esp]
add esp, 4
fdivp ST(1), ST(0) // Dividing previous resultant by span -> (rw - lwB) / sp
push dword ptr[dimen]
fld[esp]
add esp, 4
fmulp ST(1), …Run Code Online (Sandbox Code Playgroud) 我从一个众所周知的基准测试中得到了以下函数,我正在使用它进行编译gcc-arm-none-eabi-10-2020-q4-major:
#include <unistd.h>
double b[1000], c[1000];
void tuned_STREAM_Scale(double scalar)
{
ssize_t j;
for (j = 0; j < 1000; j++)
b[j] = scalar* c[j];
}
Run Code Online (Sandbox Code Playgroud)
我正在使用以下编译器选项:
arm-none-eabi-gcc -O3 -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 -c test.c
但是,如果我检查编译后的代码,编译器似乎无法使用基本的 FPU 乘法指令,而仅使用以下函数__aeabi_dmul(但是我们可以看到使用了libgccFPU ):vmov
00000000 <tuned_STREAM_Scale>:
0: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr}
4: 4c08 ldr r4, [pc, #32] ; (28 <tuned_STREAM_Scale+0x28>)
6: 4d09 ldr r5, [pc, #36] ; (2c <tuned_STREAM_Scale+0x2c>)
8: f504 58fa add.w …Run Code Online (Sandbox Code Playgroud)