繁体   English   中英

内联装配分割错误

[英]inline assembly segmentation fault

所有,

我试图用内联汇编函数编写rot13 ...

以下代码与'a'一起使用,但是当c转到'z'时不再起作用...

并且...它总是显示“分段错误” ...请给我一些建议以解决

这个问题。

#include <stdio.h>

#define add(a,b)\
asm volatile(\
    "add %%ebx,%%eax" \
    :"=a"(a) \
    :"a"(a),"b"(b) \
)

#define rot13(a)\
asm (\
"rot:\n\t"\
    "add $13,%%eax\n\t"\
    "cmpl $64,%%eax\n\t"\
    "jle L5f\n\t"\
    "cmpl $90, %%eax\n\t"\
    "jg L5f\n\t"\
    "cmpl $90,%%eax\n\t"\
    "jle L5f\n\t"\
    "subl $26,%%eax\n\t"\
"L5f:\n\t"\
    "cmpl $96,%%eax\n\t"\
    "jle L6f\n\t"\
    "cmpl $122,%%eax\n\t"\
    "jg L6f\n\t"\
    "cmpl $122,%%eax\n\t"\
    "jle L6f\n\t"\
    "subl $26,%%eax\n\t" \
"L6f:\n\t"\
    "leave\n\t"\
    :"=r"(a)\
    :"r"(a)\
)

int main()
{
    int a=13, b=12,c='z';
    rot13(c);
    printf("c-> rot13= %c\n",c);

    return 0;
}

我敢打赌,您的细分错误是因为您那里有leave说明。 内联汇编不会像普通函数那样被调用,因此您不需要它,它将破坏堆栈。

另一个问题是您已对所有程序集进行了硬编码以对%eax进行操作,但是您没有告诉编译器。 它认为它可以将输入粘贴在所需的任何寄存器中,并从所需的其他任何寄存器读回输出。 可以始终使用%0%1而不是%%eax来使代码适应该代码,但是将输入和输出约束更改为

asm ( <your code here> : "=a" (a) : "0" (a) )

这意味着“此内联汇编的输出必须在%eax ,并且输入必须与输出在同一寄存器中”。 (如果您再次在输入约束条件上加上“ a”,它将无法正常工作。GCC的寄存器分配器是一堆28岁的黑客,您必须遵守其规则。规则可在“ GCC手册的扩展Asm ”和“ Asm操作数约束 ”部分;请仔细阅读它们,包括第二部分的所有小节,并记住这实际上是内部“机器描述”语言的重新设计功能,为此进行了优化。)

对于rot13('z'),这仍然没有给我正确的答案 ,但是我认为剩下的问题是rot13算法中的错误,而不是它与程序其余部分的接口中的错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM