基于MIPS的体系结构中的C程序错误
此程序接受命令行参数并填充write_键数组基于MIPS的体系结构中的C程序错误,c,mips,C,Mips,此程序接受命令行参数并填充write_键数组 #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int i,j; unsigned char write_key[16]; for(j=0;j<4;j++){ for(i=0;i<4;i++){ write_key[j*4 + i] = (strtol(argv[1+j
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int i,j;
unsigned char write_key[16];
for(j=0;j<4;j++){
for(i=0;i<4;i++){
write_key[j*4 + i] = (strtol(argv[1+j],NULL,16)>>(8*(4-1-i))) & 0xff;
}
}
for(i=0;i<16;i++){
printf("write_key[%d] :: 0x%x \n", i, writekey[i]);
}
printf("\n");
}
用于以下输入
我的linux pc上的输出是
write_key[0] :: 0xff
write_key[1] :: 0xff
write_key[2] :: 0xff
write_key[3] :: 0xff
write_key[4] :: 0xff
write_key[5] :: 0xff
write_key[6] :: 0xff
write_key[7] :: 0xff
write_key[8] :: 0xff
write_key[9] :: 0xff
write_key[10] :: 0xff
write_key[11] :: 0xff
write_key[12] :: 0xff
write_key[13] :: 0xff
write_key[14] :: 0xff
write_key[15] :: 0xff
这是意料之中的。
但当我为基于Mips的嵌入式板交叉编译这个程序并在那里运行时,我的输出是
write_key[0] :: 0x7f
write_key[1] :: 0xff
write_key[2] :: 0xff
write_key[3] :: 0xff
write_key[4] :: 0x7f
write_key[5] :: 0xff
write_key[6] :: 0xff
write_key[7] :: 0xff
write_key[8] :: 0x7f
write_key[9] :: 0xff
write_key[10] :: 0xff
write_key[11] :: 0xff
write_key[12] :: 0x7f
write_key[13] :: 0xff
write_key[14] :: 0xff
write_key[15] :: 0xff
为什么不同体系结构的输出不同?
strtol
返回一个长的、可能是32位的带符号整数。它的范围从-1(0xFFFFFFFF
)到0x7ffffff
根据所述的编译器和(右移负数调用C中实现定义的行为)的不同,移位在负数上的行为可能有所不同
这可能就是您遇到问题的原因:EDIT:I关于maybly:)的说法是对的,在melponeme注释之后,我刚刚在32位编译器上测试了strtol(“0xffffffff)
的结果,它返回0x7FFFFFFF
,因此问题不是移位
我确信将解决您的问题的是,切换到strtoul
以返回无符号long将实现以下目的:它将返回一个无符号long(解决的第一个问题),并且它将确保移位将按您想要的方式工作
最后,我建议您在Linux机器上使用32位编译器(即使机器是64位的),这样您就更接近目标体系结构,并且可以更早地检测到类似的问题。
strtol
返回一个长的、可能是32位的带符号整数。它的范围为-1(0xffffff
)至0x7FFFFFFF
根据所述的编译器和(右移负数调用C中实现定义的行为)的不同,移位在负数上的行为可能有所不同
这可能就是您遇到问题的原因:EDIT:I关于maybly:)的说法是对的,在melponeme注释之后,我刚刚在32位编译器上测试了strtol(“0xffffffff)
的结果,它返回0x7FFFFFFF
,因此问题不是移位
我确信将解决您的问题的是,切换到strtoul
以返回无符号long将实现以下目的:它将返回一个无符号long(解决的第一个问题),并且它将确保移位将按您想要的方式工作
最后,我建议您在Linux机器上使用32位编译器(即使机器是64位的),这样您就更接近您的目标体系结构,并且可以更早地检测到类似的问题。
strtol
返回长int
。如果平台上的long int
是32位宽,那么它不能表示0xffffffff
(大约40亿)
:
函数返回转换的结果,除非
该值将下溢或溢出。如果发生下溢,
strtol()
返回LONG\u MIN
。如果发生溢出,strtol()
返回
LONG_MAX
因此它返回LONG_MAX
,32位中的0x7fffffff
(约20亿),因为这是最大的32位正数
您的Linux PC可能使用64位long int
s,因此不会出现此问题
要解决此问题,请将代码更改为使用
strtoul
,因为0xffffffff
正好适合无符号长整型
strtol
返回长整型
。如果平台上的long int
是32位宽,那么它不能表示0xffffffff
(大约40亿)
:
函数返回转换的结果,除非
该值将下溢或溢出。如果发生下溢,
strtol()
返回LONG\u MIN
。如果发生溢出,strtol()
返回
LONG_MAX
因此它返回LONG_MAX
,32位中的0x7fffffff
(约20亿),因为这是最大的32位正数
您的Linux PC可能使用64位long int
s,因此不会出现此问题
要解决此问题,请将代码更改为使用
strtoul
,因为0xffffffff
正好适合无符号长整型
您进行过任何调试吗?例如,strtol(“ffffffff”,NULL,16)
在这两个平台上返回什么?您进行过任何调试吗?例如,strtol(“ffffffffff”,NULL,16)
在这两个平台上返回什么?这是您正在寻找的参考资料耶,也得到了那一个::“右移负数取决于实现”耶,但它没有标准参考的答案,我觉得这更能说明问题。我不认为这与转移负数有关strtol
为正输入返回正结果。@melpomene:你说得对。刚刚在32位编译器上测试过。为了正确起见,我修改了我的答案。但在那之后,你可以让UB来轮班。所以strtoul解决方案是有效的。这是你要找的参考资料耶,我也找到了::“右移负数取决于实现”是的,但它没有标准参考的答案,我觉得这更能说明问题。我不认为这与转移负数有任何关系strtol
为正输入返回正结果。@melpomene:你说得对。刚刚在32位编译器上测试过。为了正确起见,我修改了我的答案。但在那之后,你可以让UB来轮班。所以strtoul解决方案是有效的。
write_key[0] :: 0x7f
write_key[1] :: 0xff
write_key[2] :: 0xff
write_key[3] :: 0xff
write_key[4] :: 0x7f
write_key[5] :: 0xff
write_key[6] :: 0xff
write_key[7] :: 0xff
write_key[8] :: 0x7f
write_key[9] :: 0xff
write_key[10] :: 0xff
write_key[11] :: 0xff
write_key[12] :: 0x7f
write_key[13] :: 0xff
write_key[14] :: 0xff
write_key[15] :: 0xff