0

我尝试生成这样的 32 位代码: gcc -S -m32 BMPTransformer.c -o BMPTransformer.s

我正在使用 Ubuntu 13.04。有类似问题的人似乎通过安装 libc6-dev-i386 克服了困难。不过,它对我没有用。

编译器抱怨:

BMPTransformer.c:243:6:错误:在重新加载“asm”时找不到类“GENERAL_REGS”中的寄存器 BMPTransformer.c:243:6:错误:“asm”操作数具有不可能的约束

代码原样:

216 static void ASM_reverse_image(BMPImage *image)
217 {
218      asm (
219             "movl $0, %%eax\n"
220 
221             "cmpl %%eax, %1\n"
222             "jl end\n"
223 
224             "row:\n"
225                  "movl (%0, %%eax, 4), %%edx\n"
226                  "decl %1\n"
227                  "movl (%0, %1, 4), %%esi\n"
228                  "movl %%esi, (%0,%%eax, 4)\n"
229                  "incl %%eax\n"
230                  "movl %%edx, (%0, %1, 4)\n"
231                  "cmpl %%eax, %1\n"
232                  "jg row\n"
233 
234             "end:\n"
235 
236             : : "r"(image->pixel_data), "r"(image->header.height): "%eax", "%edx", "%esi"
237       );
238 }

使用 64 位 a、b、c 寄存器的代码运行良好。但我需要一个 32 位版本。

4

2 回答 2

2

该错误通常表明编译器已用完寄存器。从您发布的小片段来看,情况并非如此,而且确实对我来说编译得很好。你可能没有告诉一些重要的细节。

无论如何,绝对没有理由以当前形式将其写成内联汇编。编译器可以轻松生成更好(和工作)的代码。最初的比较当然应该在 C 中。

旁注:当使用 gcc 内联汇编时,一般的想法是为编译器留下尽可能多的可能性。例如,您不需要任何寄存器,您可以使用通用约束。

于 2013-10-22T22:36:55.190 回答
0

将其编码为纯 C:

static void ASM_reverse_image(BMPImage *image)
{
    int *pixel_data = image->pixel_data;
    int tmp;
    size_t idx = 0, height = image->header.height;

    for (idx = 0; idx < height; idx++) {
        tmp = pixel_data[idx];
        pixel_data[idx] = pixel_data[height - idx];
        pixel_data[height - idx] = tmp;
    }
}

或者,如果您使用的是 C++,只需:

    for (idx = 0; idx < height; idx++)
        std::swap(pixel_data[idx], pixel_data[height - idx]);

编辑:对于装配练习,这会做:

int tmp;

asm("row:
     mov (%0), %2
     xchg %2, (%0, %1, 4)
     lea 4(%0), %0
     dec %1
     jns row"
    : : "r"(image->pixel_data), "r"(image->header.height), "r"(tmp)
    : "memory", "cc");

但这不是好的代码——主要是因为这是一种“流”类型的处理,应该通过向量单元来完成。

在 gcc 内联汇编中避免请求特定的寄存器总是一个好主意。让编译器来选择。这可能意味着您必须将一个或多个“伪变量”声明为汇编寄存器操作数(以获得“注册保留”)。

于 2013-10-23T16:51:23.057 回答