在我的机器语言课中,我们必须将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;
答案 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是保存移位数值的寄存器。值得理解的是,这个移位从左边引入了零,并且会改变带符号的有符号整数的值,但是由于应用了一个掩码,它将零应用于除了最不重要的字节以外的所有字节,它可以保存一些指令。