将数组 arg 的第一个值移动到 xmm0
Moving the first value of an array arg into xmm0
我在 C:
中有一个像这样减去 3D 向量的函数
inline void sub(float* a, float* b, float* r) {
r[0] = a[0] - b[0];
r[1] = a[1] - b[1];
r[2] = a[2] - b[2];
并且 Visual Studio 在第一个任务的调试反汇编中向我展示了以下内容:
r[0] = a[0] - b[0];
0078BBA8 mov eax,4
0078BBAD imul ecx,eax,0
0078BBB0 mov edx,4
0078BBB5 imul eax,edx,0
0078BBB8 mov edx,dword ptr [a] <------ i guess: reading a[0]
0078BBBB mov esi,dword ptr [b]
0078BBBE movss xmm0,dword ptr [edx+ecx] <------ i guess: write a[0] to xmm0
0078BBC3 subss xmm0,dword ptr [esi+eax]
0078BBC8 mov eax,4
0078BBCD imul ecx,eax,0
0078BBD0 mov edx,dword ptr [r]
0078BBD3 movss dword ptr [edx+ecx],xmm0
作为汇编新手,我只是不明白为什么以下行使用 [a]
而不是 a
:
0078BBB8 mov edx,dword ptr [a]
我原以为在 edx
中我们应该有指针地址本身而不是指针处的值,因为以下行似乎是从 edx
中的地址读取值:
0078BBBE movss xmm0,dword ptr [edx+ecx]
谁能告诉我为什么这有效?
这就是调试器显示函数反汇编的方式,但它有点误导:a
与 C 源代码中的不同。显示为mov edx, dword ptr [a]
的实际指令是
8B 55 08 mov edx, dword ptr [ebp+8]
a
用作 ebp+8
的名称以简化反汇编的阅读。
由于这是 32 位代码并且默认调用约定将所有参数传递到堆栈上,a
本身不能直接使用,必须先从堆栈中读取它,这就是你看到了。
我在 C:
中有一个像这样减去 3D 向量的函数inline void sub(float* a, float* b, float* r) {
r[0] = a[0] - b[0];
r[1] = a[1] - b[1];
r[2] = a[2] - b[2];
并且 Visual Studio 在第一个任务的调试反汇编中向我展示了以下内容:
r[0] = a[0] - b[0];
0078BBA8 mov eax,4
0078BBAD imul ecx,eax,0
0078BBB0 mov edx,4
0078BBB5 imul eax,edx,0
0078BBB8 mov edx,dword ptr [a] <------ i guess: reading a[0]
0078BBBB mov esi,dword ptr [b]
0078BBBE movss xmm0,dword ptr [edx+ecx] <------ i guess: write a[0] to xmm0
0078BBC3 subss xmm0,dword ptr [esi+eax]
0078BBC8 mov eax,4
0078BBCD imul ecx,eax,0
0078BBD0 mov edx,dword ptr [r]
0078BBD3 movss dword ptr [edx+ecx],xmm0
作为汇编新手,我只是不明白为什么以下行使用 [a]
而不是 a
:
0078BBB8 mov edx,dword ptr [a]
我原以为在 edx
中我们应该有指针地址本身而不是指针处的值,因为以下行似乎是从 edx
中的地址读取值:
0078BBBE movss xmm0,dword ptr [edx+ecx]
谁能告诉我为什么这有效?
这就是调试器显示函数反汇编的方式,但它有点误导:a
与 C 源代码中的不同。显示为mov edx, dword ptr [a]
的实际指令是
8B 55 08 mov edx, dword ptr [ebp+8]
a
用作 ebp+8
的名称以简化反汇编的阅读。
由于这是 32 位代码并且默认调用约定将所有参数传递到堆栈上,a
本身不能直接使用,必须先从堆栈中读取它,这就是你看到了。