我如何在c中使用64位内联汇编?

时间:2014-11-11 00:13:00

标签: c gcc assembly 64-bit

int main(void) {
unsigned long long a = 0x0ab0000000234432;
unsigned long long b = 0x0000000000000001;
unsigned long long c = 0x0000000032123001;
unsigned long long r1;

__asm__ __volatile__(
    "mov    %1, %%eax   \n\t"
    "xor    %2, %%eax   \n\t"
    "xor    %3, %%eax   "
    : "=&a" (r1)
    : "g" (a), "g" (b), "g"(c));

for(i=63; i>=0; i--) {
    printf("%d ", (r1 >> i) & 1 );
    if (i%8 == 0) printf(" ");
}
printf("\n");
return 0;
}

二进制值是那个 a = 00001010 10110000 00000000 00000000 00000000 00100011 01000100 00110010
b = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
c = 00000000 00000000 00000000 00000000 00110010 00010010 00110000 00000001

我想得到00001010 10110000 00000000 00000000 00110010 00110001 01110100 00110010的结果。
但是,结果是00000000 00000000 00000000 00000000 00110010 00110001 01110100 00110010

我认为代码是由32位模式编译的。
我使用MAC OS X,intel CPU和GCC。

我如何使用64位内联汇编

2 个答案:

答案 0 :(得分:4)

您正在使用eax注册。它只有32位。使用rax

答案 1 :(得分:3)

继续Greg的回答,保证提升,你试图使用32-bit个注册eax,并希望将64-bits填入其中。你不能。 X86_x64汇编程序是32位程序集的扩展(但是很多插件)。出于此目的,寄存器大小从32-bit增加到64-bit,寄存器也重命名。就像16-bit寄存器增加到32-bit并将ax重命名为eax一样,增加到64-bit时,寄存器再次重命名为eaxrax。这些是唯一需要的改变。例如:

#include <stdio.h>

int main ()
{

    unsigned long long a = 0x0ab0000000234432;
    unsigned long long b = 0x0000000000000001;
    unsigned long long c = 0x0000000032123001;
    unsigned long long r1;
    int i = 0;

    __asm__ __volatile__(
        "mov    %1, %%rax   \n\t"
        "xor    %2, %%rax   \n\t"
        "xor    %3, %%rax   "
        : "=&a" (r1)
        : "g" (a), "g" (b), "g"(c));

    for(i=63; i>=0; i--){

        printf("%d", (int)(r1 >> i) & 1 );

        if(i%8 == 0 ) printf(" ");
    }

    printf("\n");

    return 0;
}

<强>输出:

00001010 10110000 00000000 00000000 00110010 00110001 01110100 00110010