基于MIPS的体系结构中的C程序错误

基于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

此程序接受命令行参数并填充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],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