C 程序集64位有效地址无效
我正在创建一个函数,它可以从asm 64位的C代码中调用 这是C等价函数:C 程序集64位有效地址无效,c,assembly,64-bit,x86-64,calling-convention,C,Assembly,64 Bit,X86 64,Calling Convention,我正在创建一个函数,它可以从asm 64位的C代码中调用 这是C等价函数: /* * x and y are two arrays of floats, this function calculates the * distance beetween those two objects */ float dist(float *x, float *y, int length) { float c = 0; int i; for (i = 0; i < len
/*
* x and y are two arrays of floats, this function calculates the
* distance beetween those two objects
*/
float dist(float *x, float *y, int length)
{
float c = 0;
int i;
for (i = 0; i < length; ++i)
{
c += (x[i] - y[i]) * (x[i] - y[i]);
}
return sqrt(c);
}
我使用nasm:nasm-f elf64 distanza.asm进行编译问题是当我尝试使用xmm0和xmm1处的地址获取x[I]和y[I]的值时:
movss xmm2, [xmm0]
subss xmm2, [xmm1]
无法编译:无效的有效地址。
如何使用xmm0中存储的地址获取内存中的值?我必须使用xmm0,因为它是存储参数float*x的寄存器。我认为地址只能使用通用寄存器,例如
rax
,加上rip
。在“取消引用”该值之前,需要将其移出到1。然而,我必须警告,我已经有一段时间没有组装了
编辑
以下是《英特尔手册》的相关部分:
3.7.5.1在64位模式下指定偏移量
64位模式下内存地址的偏移部分可以直接指定为静态值或通过地址指定
由以下一个或多个组件组成的计算:
- 位移-8位、16位或32位值
- Base—64位通用寄存器中的值
- 索引—64位通用寄存器中的值
- 比例因子-乘以索引值的2、4或8的值
- 撕裂+位移⎯ 在64位模式下,RIP相对寻址使用有符号32位位移来 通过符号计算下一条指令的有效地址扩展32位值并添加到64位 RIP中的值
这与@Jester提到的调用约定问题不同。我认为地址只能使用通用寄存器,例如
rax
,以及rip
。在“取消引用”该值之前,需要将其移出到1。然而,我必须警告,我已经有一段时间没有组装了
编辑
以下是《英特尔手册》的相关部分:
3.7.5.1在64位模式下指定偏移量
64位模式下内存地址的偏移部分可以直接指定为静态值或通过地址指定
由以下一个或多个组件组成的计算:
- 位移-8位、16位或32位值
- Base—64位通用寄存器中的值
- 索引—64位通用寄存器中的值
- 比例因子-乘以索引值的2、4或8的值
- 撕裂+位移⎯ 在64位模式下,RIP相对寻址使用有符号32位位移来 通过符号计算下一条指令的有效地址扩展32位值并添加到64位 RIP中的值
这与@Jester提到的调用约定问题不同。我认为地址只能使用通用寄存器,例如
rax
,以及rip
。在“取消引用”该值之前,需要将其移出到1。然而,我必须警告,我已经有一段时间没有组装了
编辑
以下是《英特尔手册》的相关部分:
3.7.5.1在64位模式下指定偏移量
64位模式下内存地址的偏移部分可以直接指定为静态值或通过地址指定
由以下一个或多个组件组成的计算:
- 位移-8位、16位或32位值
- Base—64位通用寄存器中的值
- 索引—64位通用寄存器中的值
- 比例因子-乘以索引值的2、4或8的值
- 撕裂+位移⎯ 在64位模式下,RIP相对寻址使用有符号32位位移来 通过符号计算下一条指令的有效地址扩展32位值并添加到64位 RIP中的值
这与@Jester提到的调用约定问题不同。我认为地址只能使用通用寄存器,例如
rax
,以及rip
。在“取消引用”该值之前,需要将其移出到1。然而,我必须警告,我已经有一段时间没有组装了
编辑
以下是《英特尔手册》的相关部分:
3.7.5.1在64位模式下指定偏移量
64位模式下内存地址的偏移部分可以直接指定为静态值或通过地址指定
由以下一个或多个组件组成的计算:
- 位移-8位、16位或32位值
- Base—64位通用寄存器中的值
- 索引-64位字符中的值
movss xmm2, [xmm0] subss xmm2, [xmm1]