当我命名寄存器时,为什么asm有不可能的限制?

时间:2016-01-25 23:24:39

标签: c assembly

我是C中的汇编新手,我不知道如何修复此错误。我正在创建一个意味着写一个文件的函数。我所拥有的是:

ssize_t mywrite(int fd, const void *buf, size_t count) {
//  return write(fd, buf, count);
    ssize_t var;
    __asm__("movl $4,%%eax\n\t"  // Write
        "movl %1,%%ebx\n\t"
        "movl %2,%%ecx\n\t"
        "movl %3,%%edx\n\t"
        "int  $0x80\n\t"         // System call
        "movl %%eax,%0"
        :"=r"(var)
        :"r"(fd),"r"(buf),"r"(count)
        :"%eax","%ebx","%ecx","%edx"
    );
    return var;
}

我的asm应该和write一样(fd,buf,count); 当我编译它时,我得到''asm'操作数有不可能的限制“。但是,如果不命名变量并直接从堆栈中获取值,则不会出现错误。这是代码

    __asm__("movl $4,%%eax\n\t"
        "movl 8(%%ebp),%%ebx\n\t"
        "movl 12(%%ebp),%%ecx\n\t"
        "movl 16(%%ebp),%%edx\n\t"
        "int  $0x80\n\t"
        "movl %%eax,%0"
        :"=r"(var)
        :
        :"%eax","%ebx","%ecx","%edx"
    );

我可以使用第二个代码,ofc,但是我需要用优化2编译它。然后%ebp将不会指向我需要的地方。我尝试使用“a”,“b”,“c”和“d”代替“r”,但没有成功。 有人可以帮忙吗?谢谢:D

1 个答案:

答案 0 :(得分:7)

问题是约束r意味着寄存器,但你的CPU根本没有那么多寄存器!

您可以使用内存约束m

:"m"(fd),"m"(buf),"m"(count)

这将产生如下指令:

movl 8(%ebp),%ebx

但我建议在其所有荣耀中使用x86 constraints

ssize_t mywrite(int fd, const void *buf, size_t count) {
    ssize_t var;
    __asm__(
        "int  $0x80"
        :"=a"(var)
        :"0"(4), "b"(fd),"c"(buf),"d"(count)
    );
    return var;
}

-Ofast给出:

push   %ebx
mov    $0x4,%eax
mov    0x10(%esp),%edx
mov    0xc(%esp),%ecx
mov    0x8(%esp),%ebx
int    $0x80
pop    %ebx
ret

使用-Os

push   %ebp
mov    $0x4,%eax
mov    %esp,%ebp
push   %ebx
mov    0x10(%ebp),%edx
mov    0x8(%ebp),%ebx
mov    0xc(%ebp),%ecx
int    $0x80
pop    %ebx
pop    %ebp
ret    

请注意,由于使用约束而不是名称寄存器,编译器能够进一步优化代码。