内联汇编分段故障

时间:2012-10-24 15:21:42

标签: c assembly rot13

所有,

我试图用内联汇编函数编写一个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;
}

1 个答案:

答案 0 :(得分:3)

我敢打赌你的分段错误是因为你有一条leave指令。内联汇编被调用为普通函数,所以你不需要它,它会破坏堆栈。

另一个问题是,您已将所有程序集硬编码为%eax,但您没有告诉编译器。它认为它可以将输入粘贴在它想要的任何寄存器中,并从它想要的任何其他寄存器读回输出。通过一直使用%0%1而不是%%eax来调整代码是可能的,但是将输入和输出约束更改为

可能更容易
asm ( <your code here> : "=a" (a) : "0" (a) )

表示“此内联汇编的输出必须在%eax中,并且输入必须与输出在同一寄存器中”。 (如果你再次在输入约束上加上“a”,它将正常工作.GCC的注册分配器是一个28岁的黑客攻击,你必须按照规则进行游戏。可以在Extended Asm的“Constraints for Asm Operands”和“GCC manual”部分找到规则;仔细阅读 ,包括第二部分的所有子部分,并且请记住,这实际上是内部“机器描述”语言的改变用途的功能,并针对此进行了优化。)

这仍然没有为rot13('z')提供正确的回答,但我认为剩下的问题是你的rot13算法中的错误,而不是与其余的程序