0 转换为 128

0 is converted to 128

我正在尝试从主机 Linux 到目标系统执行 SNMP 设置。但是,设置的不是正确的值,而是错误的值。经过一番研究,我做了这个 table:

Linuxsnmp

中十进制值的十六进制表示
0 - 0x80 - 1000 0000 - 0 is converted to 128
1 - 0x40 - 0100 0000 - 1 is converted to 64
2   0x20 - 0010 0000 - 2 is converted to 32
3   0x10 - 0001 0000 - 3 is converted to 16
4   0x08 - 0000 1000 - 4 is converted to 8
5   0x04 - 0000 0100 - 5 is converted to 4
6   0x02 - 0000 0010 - 6 is converted to 2
7   0x01 - 0000 0001 - is converted to 1

目标系统中十进制值的十六进制表示

0 - 0x00 - 0000 0000
1 - 0x01 - 0000 0001
2   0x02 - 0000 0010
3   0x03 - 0000 0011
4   0x04 - 0000 0100
5   0x05 - 0000 0101
6   0x06 - 0000 0110
7   0x07 - 0000 0111

我有两个问题:

  1. 这个问题背后的原因可能是什么?
  2. 有人知道如何在 C 程序中将这些 Linux 值转换为正确的目标值吗?

如果我正确理解你的问题,你会收到一个使用单热编码对 8 个值(0 到 7)进行编码的字节。请参阅 https://en.wikipedia.org/wiki/One-hot(注意:您的位顺序似乎颠倒了)。

如果您只是将单热编码位模式放入目标系统上的字节变量中,您将不会获得原始值,因为您的目标系统使用另一种编码(可能是 2 的补码)。换句话说 - 给定的位模式在单热编码和 2 的补码编码中具有不同的含义。

所以任务是将单热编码值转换为目标系统上的等效值。

你可以选择一个简单的 switch 语句——比如:

int main(void)
{
  unsigned char linux_snmp_value = 0x20;
  unsigned char target_value = 255;
  switch(linux_snmp_value)
  {
    case 0x80:
        target_value = 0;
        break;
    case 0x40:
        target_value = 1;
        break;
    case 0x20:
        target_value = 2;
        break;

    // Add the remaining cases here

    default:
        // Illegal value
        // Add some error handling
        break;
  }
  printf("Target value %d\n", target_value);
  return 0;
}

如果你更喜欢循环,它可能是这样的:

int main(void)
{
  unsigned char linux_snmp_value = 0x01;
  unsigned char target_value = 0;
  unsigned char mask = 0x80;
  while (mask)
  {
    if (mask == linux_snmp_value) break;
    ++target_value;
    mask = mask >> 1;
  }
  if (mask == 0)
  {
    // Illegal value
    // Add some error handling
    printf("ERROR\n");
    return -1;
  }
  printf("Target value %d\n", target_value);
  return 0;
}

如果可移植性不是问题(例如你不在 VAX 或 AVR8 机器上编译)你可以使用机器指令

asm (“bsrl %1, %0” : “=r” (position) : “r” (number));

你也可以把它包装成漂亮的内联函数。 类似的指令在 ARM、MIPS、PIC 和许多其他指令上可用。