乘法寄存器时汇编中的分段错误?
Segmentation fault in assembly when multiplying registers?
我试图将以下 C 代码转换为汇编代码。这是 C 代码:
typedef struct {
int x;
int y;
} point;
int square_distance( point * p ) {
return p->x * p->x + p->y * p->y;
}
我的汇编代码如下:
square_distance:
.LFB23:
.cfi_startproc
movl (%edi), %edx
imull %edx, %edx
movl 4(%edi), %eax
imull %eax, %eax
addl %edx, %eax
ret
.cfi_endproc
当我尝试 运行 这个程序时出现分段错误。有人可以解释为什么吗?谢谢!我将不胜感激!
您的代码是 32 位代码 (x86),但您应用了与 64 位代码 (x64) 一起使用的调用约定。这显然行不通。
x86 调用约定在堆栈上传递所有参数。
x64 调用约定在 rdi
中传递第一个参数,在 rsi
中传递第二个参数,在 rdx
中传递第三个参数,等等(我不确定哪些寄存器是如果参数超过 3 个则使用,这也可能取决于您的平台)。
你的代码大概对 x64 代码是正确的,就像这样:
square_distance:
movl (%rdi), %edx
imull %edx, %edx
movl 4(%rdi), %eax
imull %eax, %eax
addl %edx, %eax
ret
对于 x86 代码,参数在堆栈上传递,相应的正确代码如下所示:
square_distance:
movl 4(%esp), edx
movl (%edx), eax
imull eax, eax
movl 4(%edx), edx
imull edx, edx
addl edx, eax
ret
总的来说,调用约定 主题非常广泛,根据平台还有其他调用约定,甚至在同一平台内,在某些情况下也可能存在不同的调用约定。
只是想补充一下。因为我的声望不够评论。
调用函数时传递参数的方式(也称为调用约定)与体系结构和操作系统不同(OS)。你可以从这个wiki
中找出许多常见的调用约定
从wiki上我们知道*nix上的x64调用约定是前六个参数通过RDI、RSI、RDX、RCX、R8、R9寄存器传递,其他的通过栈传递。
我试图将以下 C 代码转换为汇编代码。这是 C 代码:
typedef struct {
int x;
int y;
} point;
int square_distance( point * p ) {
return p->x * p->x + p->y * p->y;
}
我的汇编代码如下:
square_distance:
.LFB23:
.cfi_startproc
movl (%edi), %edx
imull %edx, %edx
movl 4(%edi), %eax
imull %eax, %eax
addl %edx, %eax
ret
.cfi_endproc
当我尝试 运行 这个程序时出现分段错误。有人可以解释为什么吗?谢谢!我将不胜感激!
您的代码是 32 位代码 (x86),但您应用了与 64 位代码 (x64) 一起使用的调用约定。这显然行不通。
x86 调用约定在堆栈上传递所有参数。
x64 调用约定在 rdi
中传递第一个参数,在 rsi
中传递第二个参数,在 rdx
中传递第三个参数,等等(我不确定哪些寄存器是如果参数超过 3 个则使用,这也可能取决于您的平台)。
你的代码大概对 x64 代码是正确的,就像这样:
square_distance:
movl (%rdi), %edx
imull %edx, %edx
movl 4(%rdi), %eax
imull %eax, %eax
addl %edx, %eax
ret
对于 x86 代码,参数在堆栈上传递,相应的正确代码如下所示:
square_distance:
movl 4(%esp), edx
movl (%edx), eax
imull eax, eax
movl 4(%edx), edx
imull edx, edx
addl edx, eax
ret
总的来说,调用约定 主题非常广泛,根据平台还有其他调用约定,甚至在同一平台内,在某些情况下也可能存在不同的调用约定。
只是想补充一下
调用函数时传递参数的方式(也称为调用约定)与体系结构和操作系统不同(OS)。你可以从这个wiki
中找出许多常见的调用约定从wiki上我们知道*nix上的x64调用约定是前六个参数通过RDI、RSI、RDX、RCX、R8、R9寄存器传递,其他的通过栈传递。