【问题标题】:using bitwise operators to form multi-byte value from individual bytes使用按位运算符从单个字节形成多字节值
【发布时间】:2013-10-19 21:22:57
【问题描述】:

VGA 监视器编程涉及将 16 位值写入某些内存位置,以便在屏幕上打印字符。这就是这个 16 位值中的不同位如何转换为屏幕上打印的字符的方式:

我使用枚举来表示不同的背景/前景色:

typedef enum
{ 
  eBlack , 
  eBlue , 
  eGreen ,
  eCyan,
  eRed,
  eMagenta,
  eBrown,
  eLightGrey,
  eDarkGrey,
  eLightBlue,
  eLightGreen,
  eLightCyan,
  eLightRed,
  eLightMagenta,
  eLightBrown,
  eWhite

} textColor ;

我写了这个函数来创建这个 16 位的值,基于三件事,角色用户想要打印,他想要的前景色和背景色:

假设:在我的平台上,int 32 位,unsigned short 16 位,char 8 位

void printCharacterOnScreen ( char c , textColor bgColor, textColor fgColor ) 
{
    unsigned char higherByte = ( bgColor << 4 ) | (fgColor ) ;
    unsigned char lowerByte  = c  ;

    unsigned short higherByteAs16bitValue = higherByte & 0 ;
    higherByteAs16bitValue = higherByteAs16bitValue << 8 ;

    unsigned short lowerByteAs16bitValue = lowerByte & 0 ;

    unsigned short complete16bitValue = higherByteAs16bitValue & lowerByteAs16bitValue ;

    // Then write this value at the special address for VGA devices.
}

Q. 代码是否正确,是创建这样一个值的编写方式吗?有没有一些标准的方法来做这种操作?

问。我的方法会独立于平台吗?代码上还有其他 cmets 吗?

【问题讨论】:

    标签: c types bit-manipulation bitwise-operators vga


    【解决方案1】:

    它非常接近 - 但线

    unsigned short lowerByteAs16bitValue = lowerByte & 0 ;
    

    将清除低字节。你可能想要

    unsigned short lowerByteAs16bitValue = lowerByte;
    

    您实际上并不需要lowerByte,可以直接使用c - 但您的代码更具可读性。

    下一个问题:

    unsigned short complete16bitValue = higherByteAs16bitValue & lowerByteAs16bitValue ;
    

    同样,您使用的是&amp; 运算符。我想你的意思是像前面几行一样使用| (OR)。

    虽然这现在看起来“可移植”,但您在写入硬件时仍需小心,因为低端和高端平台可能会切换字节 - 因此当您的代码工作到返回正确的点时16 位字,您可能需要注意该字是如何写入 VGA 卡的。那是你注释掉的那行......但它非常重要!

    【讨论】:

    • 那些是我在兴奋中犯的更多错别字:p 但感谢您指出。关于最后一部分,您的意思是指向 little endian / big endian 吗?我只是在最后直接写了*ptr_frameBuffer = complete16bitValue ;。以后会不会有问题?如果机器是小/大端,移位运算符的输出也不取决于?
    • 有错别字,但它们很重要!移位运算符将正常工作......但您无法确定高字节是否将存储在比低字节少一个或多一个的内存位置。但是你的 CPU 会知道。因此,只要您将事物处理为 16 位整数(正如您所做的那样,有效地)而不是单独写入高字节和低字节,您就可以了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    相关资源
    最近更新 更多