在运行时检测endian的好处是什么? [英] what is the benefit of detecting endian at runtime?

查看:202
本文介绍了在运行时检测endian的好处是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我搜索了宏以确定机器上的字节序,并没有找到任何标准的处理器宏,为此,但很多解决方案在运行时。 为什么我应该在运行时检测到endianess?



如果我这样做:


b $ b

  #ifdef LITTLE_ENDIAN 
inline int swap(int& x){
// do swap anyhow
return swapped;
}
#elif BIG_ENDIAN
inline int& swap(int& x){return x; }
#else
#errorsome blabla
#endif

int main(){
int x = 0x1234;
int y = swap(x);

return 0;
}

编译器只会生成一个函数。



但如果我这样做(请参阅 predef.endian ):

 枚举{
ENDIAN_UNKNOWN,
ENDIAN_BIG,
ENDIAN_LITTLE,
ENDIAN_BIG_WORD,/ * Middle-endian,Honeywell 316风格* /
ENDIAN_LITTLE_WORD / *中端,PDP-11风格* /
};

int endianness(void)
{
uint8_t buffer [4];

buffer [0] = 0x00;
buffer [1] = 0x01;
buffer [2] = 0x02;
buffer [3] = 0x03;

switch(*((uint32_t *)buffer)){
case 0x00010203:return ENDIAN_BIG;
case 0x03020100:return ENDIAN_LITTLE;
case 0x02030001:return ENDIAN_BIG_WORD;
case 0x01000302:return ENDIAN_LITTLE_WORD;
默认值:return ENDIAN_UNKNOWN;
}


int swap(int& x){
switch(endianess()){
case ENDIAN_BIG:
return x;
break;
case LITTLE_ENDIAN:
// do swap
return swapped;
break;
默认值:
//错误blabla
}
// do swap anyhow
}

编译器生成用于检测的代码。



我不知道为什么要这样做? p>

如果我有代码,为小端机器编译,整个代码是为小端序生成的,如果我试图在大端机器上运行这样的代码在双端机器上,像臂 wiki:bi-endian )的整个代码是为小端机器编译的。因此所有其他声明。 int也是le。

  //在little endian上编译
uint32_t 0x1234; // 0x1234常数文字
//应该在BE
上结果34120000


解决方案

实际上系统中软件可以设置系统是(当前正在运行)小端模式还是大端模式。大多数系统仅支持在特殊情况下切换,而不是(幸运地是对于系统程序员等)任意地来回切换。但是可以想到支持可执行文件定义该特定可执行文件是以LE还是BE模式运行。在这种情况下,你不能依赖选择什么操作系统和处理器模型...



另一方面,如果硬件只支持一个字节序(例如x86在其不同的形式),然后我看不到需要在运行时检查。你知道这是小端,这就是它。使系统包含代码以检查哪个字节序是浪费(在性能和代码大小方面),并且执行将大字节序转换为小字节序的转换方法。


i've searched for macro's to determine endianess on a machine and didn't found any standard proprocessor macros for this, but a lot of solutions doing that on runtime. why should i detect endianess at runtime?

if i do somthing like that:

#ifdef LITTLE_ENDIAN
  inline int swap(int& x) {
    // do swap anyhow
    return swapped;
  }
#elif BIG_ENDIAN
  inline int& swap(int& x) { return x; }
#else
  #error "some blabla"
#endif

int main() {
  int x = 0x1234;
  int y = swap(x);

  return 0;
}

the compiler will generate only one function.

but if i do it like (see predef.endian):

enum {
  ENDIAN_UNKNOWN,
  ENDIAN_BIG,
  ENDIAN_LITTLE,
  ENDIAN_BIG_WORD,   /* Middle-endian, Honeywell 316 style */
  ENDIAN_LITTLE_WORD /* Middle-endian, PDP-11 style */
};

int endianness(void)
{
  uint8_t buffer[4];

  buffer[0] = 0x00;
  buffer[1] = 0x01;
  buffer[2] = 0x02;
  buffer[3] = 0x03;

  switch (*((uint32_t *)buffer)) {
  case 0x00010203: return ENDIAN_BIG;
  case 0x03020100: return ENDIAN_LITTLE;
  case 0x02030001: return ENDIAN_BIG_WORD;
  case 0x01000302: return ENDIAN_LITTLE_WORD;
  default:         return ENDIAN_UNKNOWN;
}


int swap(int& x) {
  switch(endianess()) {
    case ENDIAN_BIG:
      return x;
    break;
    case LITTLE_ENDIAN:
      // do swap
      return swapped;
    break;
    default:
      // error blabla
  }
  // do swap anyhow
}

the compiler generates code for the detection.

i don't get it, why should i do this?

if i have code, compiled for a little-endian machine, the whole code is generated for little endian, and if i try to run such code on a big-endian machine (on a bi-endian machine like arm wiki:bi-endian) the whole code is compiled for a little-endian machine. so all other declarations of e.g. int are also le.

// compiled on little endian
uint32_t 0x1234;  // 0x1234 constant literal
// should result 34120000 on BE

解决方案

There are actually systems where SOFTWARE can set whether the system is (currently running in) little or big endian mode. Most systems only support switching that under special circumstances, and not (fortunately for system programmers and such) switching back and forth arbitrarily. But it would be conceivable to support that an executable file defines whether that particular executable runs in LE or BE mode. In that case, you can't rely on picking out what OS and processor model it is...

On the other hand, if the hardware only EVER supports one endianness (e.g. x86 in its different forms), then I don't see a need to check at runtime. You know it's little endian, and that's it. It is wasteful (in terms of performance and code-size) to have the system contain code to check which endianness it is, and carry around conversion methods to convert from big endian to little endian.

这篇关于在运行时检测endian的好处是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆