寄存器相乘时汇编出现分段故障吗? [英] Segmentation fault in assembly when multiplying registers?

查看:30
本文介绍了寄存器相乘时汇编出现分段故障吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将以下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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆