寄存器相乘时汇编出现分段故障吗? [英] 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
一般情况下,调用约定主题很大,根据平台的不同还有其他调用约定,甚至在同一平台内,某些情况下也可能存在不同的调用约定。
这篇关于寄存器相乘时汇编出现分段故障吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文