难以理解c ++程序,转移和&

时间:2013-10-10 19:09:34

标签: c++ shift

在我的机器语言课中,我们必须将c ++翻译成mips,问题是我不太了解c ++,只是基本的东西,所以我无法理解这个函数:

void IPtoDD(int arg0, char *arg1)
{
  int temp, numChar, shift = 24;

  for (int i=0; i<4; i++) {
    temp = arg0 >> shift;
    temp = temp & 0x000000ff;
    numChar = byteToDec(temp,arg1);
    arg1 += numChar;
    *arg1++ = '.';
    shift -= 8;
  }

特别是

    temp = arg0 >> shift;
    temp = temp & 0x000000ff;

4 个答案:

答案 0 :(得分:2)

>>运算符是“右移运算符”。它会将左侧值的二进制表示向右移位x位,其中x是右侧的数字。这看起来像什么?以下是一些例子:

decimal: 128                   >> 1 == 64
binary:  0b0000 0000 1000 0000 >> 1 == 0b0000 0000 0100 0000

decimal: 64                    >> 1 == 32
binary:  0b0000 0000 0100 0000 >> 1 == 0b0000 0000 0010 0000

注意大二进制数中的1如何向右移动1.在代码中,您将arg0移到shift,其中arg0是一些输入,{{1因为你正在循环,所以是24,16,8,然后是0。这意味着第一个循环,你将shift向下移动24位,然后将其存储到temp。

第二个语句是按位AND,它将左侧的每个位与右侧的每个相应位进行比较。如果两个位都是1,则相同位置的结果位为1,否则为0.以下是一些示例:

arg0

在表达式中,AND的右侧值为decimal: 7 & 15 == 7 binary: 0b0111 & 0b1111 == 0b0111 decimal: 5 & 12 == 4 binary: 0b0101 & 0b1100 == 0b0100 ,十六进制当量为255,十进制。

您感兴趣的两个陈述是从输入0x000000FF中提取每个“字节”或“8位块”:

arg0

关于转移权利的补充:

您正在此处移动签名的整数,但幸运的是,您使用以下AND掩码屏蔽了这些位。为了完整起见,在有符号整数上右移可以做两件事之一(假设这里有16位数,对于32位或64位数字的结果会有所不同):

算术右移:

temp = arg0 >> shift;
temp = temp & 0x000000ff;

Input:  arg0 = 0x12345678, shift = 24
Output: temp = 0x12

Input:  arg0 = 0x12345678, shift = 0
Output: temp = 0x78

逻辑右移:

decimal: -128                  >> 1 == -64
binary:  0b1111 1111 1000 0000 >> 1 == 0b1111 1111 1100 0000

注意算术右移如何“复制”顶部位,其中“逻辑右移”带来零。关于如何实际解释它是 platform ,所以如果可能的话尽量远离它,并坚持使用无符号整数移位。

答案 1 :(得分:0)

temp = arg0 >> shift

这是arg0内容的二进制右移。它实现了shift次转换shift = 24次。因此,自arg0起,它会将temp = temp & 0x000000ff; 向右移动24次。

temp

这掩盖了&中包含的最重要字节。最后一个字节仍然存在,因为f与{{1}}的任何内容只反映了原始值。

答案 2 :(得分:0)

在这一行

temp = arg0 >> shift;

arg0的值从最高有效位移位到最低位(小心它可以是从左到右或从右到左依赖于CPU的字节顺序)的移位值(第一次24然后是16然后是8) )

temp = temp & 0x000000ff;

二进制AND应用于temp,即除了不太重要的8位复位为0之外,不重要的8位不会改变。如果你需要在汇编中实现它,你可能不需要做二进制AND,而是获得正确的字节。

答案 3 :(得分:0)

temp = arg0 >> shift

这有点转变。整数值arg0将向右移动shift位数。

例如,如果shift = 8且arg0 = 0x1234,则temp将被分配0x12。

在你的代码中,如果arg0 = 0x12345678,shift = 24,则temp变为0x123456。

temp = temp & 0x000000ff;

这是一个按位and操作。十六进制数0x0000000ff用于在将最低有效字节传递到byteToDec()之前对其进行屏蔽。

所以在arg0 = 0x12345678的最后一个例子中,temp被移位24到= 0x123456然后被屏蔽为0x00000056。

就MIPS而言 - Shift右逻辑变量(SRLV)指令将用于移位

SRLV $d, $t, $s

其中$ d是目标寄存器,$ t是源寄存器,$ s是保存移位数值的寄存器。值得理解的是,这个移位从左边引入了零,并且会改变带符号的有符号整数的值,但是由于应用了一个掩码,它将零应用于除了最不重要的字节以外的所有字节,它可以保存一些指令。

相关问题