繁体   English   中英

在没有 btsl 指令的情况下使用内联 asm 设置位

[英]set a bit with inline asm without btsl instruction

我想在 position p 处设置一点,而不使用带有内联 asm gcc c 代码的 btsl 指令。 使用 btsl 指令很简单:

int n,p;
scanf("%d%d",&n,&p);
asm("btsl %1, %0"
:"=m"(n)
:"Ir"(p)
:"cc");

我知道设置位可以完成:

n|=1<<p;

现在,我正在使用内联 asm 这样做:

  asm("movl %1, %%eax;"
      "movl %2, %%ebx;" 
      "shl $1, %%ebx;"
      "orl %%ebx, %%eax;"
      "movl %%eax, %0;"
      
  :"=b"(n)
  :"a"(n), "b"(p)
  :"cc");
  printf("%d\n",n);

在我看来 shl 指令不起作用。 例如 n=20=10100。 当我尝试设置第一个位 p=1 时,结果是 22=10110 而不是 21=10101

按照迈克尔的例子,我已经完成了清除和切换以及设置:

unsigned long bitset(unsigned long value, uint8_t shift)
{
    unsigned long tmp;

    asm ("mov $0x1, %[tempreg]\n\t"
         "shl %[shift], %[tempreg]\n\t"
         "or %[tempreg], %[val]"
    : [val]"+r"(value),
      [tempreg]"=&r"(tmp)
    : [shift]"cN"(shift));

    return value;
}


unsigned long bitclear(unsigned long value, uint8_t shift)
{
    unsigned long tmp;

    asm ("mov $0x1, %[tempreg]\n\t"
         "shl %[shift], %[tempreg]\n\t"
         "not %[tempreg]\n\t"
         "and %[tempreg], %[val]\n\t"
    : [val]"+r"(value),
      [tempreg]"=&r"(tmp)
    : [shift]"cN"(shift));

    return value;
}
unsigned long toggle(unsigned long value, uint8_t shift)
{
    unsigned long tmp;

    asm ("mov $0x1, %[tempreg]\n\t"
         "shl %[shift], %[tempreg]\n\t"
         "xor %[tempreg], %[val]"
    : [val]"+r"(value),
      [tempreg]"=&r"(tmp)
    : [shift]"cN"(shift));

    return value;
}

暂无
暂无

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

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