日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

有关字节序

發布時間:2025/3/19 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 有关字节序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

a_mao發表于: 2005/04/26 01:12am
//it seems that ssha_data is a struct,and ssha_data.millisecs is a member,so ?how to get the address is a problem??
//you can use simple variate like this:

void swapb(char *buf, short size)
{
char tmp;

switch (size) {
? case 2:
? ? tmp=buf[0]; buf[0]=buf[1]; buf[1]=tmp;
? ? break;
? case 4:
? ? tmp=buf[0]; buf[0]=buf[3]; buf[3]=tmp;
? ? tmp=buf[1]; buf[1]=buf[2]; buf[2]=tmp;
? ? break;
? case 8:
? ? tmp=buf[0]; buf[0]=buf[7]; buf[7]=tmp;
? ? tmp=buf[1]; buf[1]=buf[6]; buf[6]=tmp;
? ? tmp=buf[2]; buf[2]=buf[5]; buf[5]=tmp;
? ? tmp=buf[3]; buf[3]=buf[4]; buf[4]=tmp;
? ? break;
? default:
? ? break;
}
return;
}

#include "stdio.h"
void main()
{
int x;
x=0x00e205e8;
printf("millisecs ? ?= [%10d] %08x/n", x, x);
swapb((char *)&x,4);
printf("millisecs ? ?= [%10d] %08x/n", x, x);
}

這個標題中的Endian是什么意思呢?還是讓我們先來看看下面的情況,這是內存中一個WORD值中的內容,那么這個WORD中的值是0x1234呢,還是0x3412???

low?byte?high?byte?
0x12?0x34?

熟悉x86匯編的人立刻就知道這個值應為0x3412,很對,但在一些情況下,比如說你在SGI的機器上看到這種情況,則正好相反,0x1234才是正確答案,這與CPU內部處理數據的方式有關。這兩種處理方式都存在于不同廠商生產的CPU之中,在上例中若此WORD值為0x3412的,我們稱之為little-endian,?若為0x1234的,我們稱之為big-endian,這是兩種不同的byte?orders。MSDN中有比較精確的定義如下:

Byte?Ordering?Byte?ordering?Meaning?
big-endian?The?most?significant?byte?is?on?the?left?end?of?a?word.?
little-endian?The?most?significant?byte?is?on?the?right?end?of?a?word.?

一般來說我們不用關心byte?ordering的問題,但若要涉及跨平臺之間的通信和資源共享,則不得不考慮這個問題了。也許你會說,我永遠不會去用其它非x86的CPU,也許是這樣,你甚至可以不必知道我們最常用的Intel,AMD等生產的x86的byte?ordering是little-endian的,而且按現在的裝機數量來看,可以說世界上絕大多數CPU是little-endian的,但多了解一些沒有什么壞處,也許有用上的一天,實際若您要涉及到網絡編程,了解一些還是有所幫助的,看完本文后您就應該知道為何socket編程中為何要用到如?ntohl,?htonl,?ntohs,?htons這幾個看起來名字似乎怪怪的API了,也很容易理解這些函數名的意義了。

假設我們要在不同byte?ordering的機器之間傳輸和交換數據,那該怎么辦呢,有兩個方法,一是全部轉換成文本來傳輸(如XML使用的),另一個方法兩方都按照某一方的byte?order,這時就涉及到了不同byte?order之間相互轉換的問題(網絡傳輸標準如TCP/IP采用第二種方法并且由于歷史的原因,byte?ordering是big-endian的)。兩種之間該如何轉換呢?方法有很多,我們可以先看看MFC中在處理serialize的代碼中所用的方法(List),?雖然代碼應該是高效易讀的,?但我個人并不喜歡它,?原因是我覺得這不是一種通用優美的方法.下面列出的是我自己寫的轉換的代碼:


template
F3D_INLINE?T ConvertEndian(T??t)
{
T tResult?=?0;
for?(int??I?=?0;?I?<?sizeof(T);?++?I)
{
tResult?<<=?8;
tResult?|=?(t?&?0xFF)?;

t?>>=?8;
}

return??tResult;
}

原理非常簡單,交換字節順序,我就不多說了,當然這個寫法并不是快速的,?只是通用的(我沒條件試,?若有不對之處請指出),?若要快速的代碼,可以在不同platform上用與platform相關的代碼,?如在PowerPC上有?"load?word?byte-reversed?indexed"?(lwbrx)?和?"load?halfword?byte-reversed?indexed"?(lhbrx)?指令,?在x86上還可用BSWAP單個匯編指令等,在類型上專為int16,?int32寫的通用的代碼也可以比這快得多.?

當然如果在byte?ordering相同的情況下,應該不必用這個轉換函數,所以我們可以定義一個宏來處理不同的byte?ordering,也可以在運行時測試byte?ordering,?下面的代碼給出了一個簡單的測試方法。?


//?Test?for?endianness.
F3D_INLINE?bool IsLittleEndian(void)
{
DWORD dwTestValue?=?0x12345678L;
return??(*((BYTE*)&dwTestValue)?==?0x78);
}

但是float比較怪,有可能所涉及到不僅僅是byte?order的問題,因為有些平臺如Alpha不使用IEEE的浮點格式,還得自己轉換。當然同上,其它的方法一是將所用的float用文本方式輸入輸出,另一個辦法是在某些情況下可將其轉換成定點數再處理,這里我不再深入。

如果是讀寫第三方已經指定byte?order的文件或數據流,比如說讀SGI的位圖文件格式,則可以直接自行按指定的byte?order拼起來,不必考慮host機是何種byte?ordering。下面我給出相應的代碼:


//?Read?a?little-endian?TYPE?from?address
template
F3D_INLINE?T GetLittleEndian(const?BYTE*??pBuf)
{
T tResult?=?0;
pBuf?+=?sizeof(T)?-?1;
for?(int??I?=?0;?I?<?sizeof(T);?++?I)
{
tResult?<<=?8;
tResult?|=?*pBuf?--;
}

return??tResult;
}

//?Read?a?big-endian?TYPE?from?address
template
F3D_INLINE?T GetBigEndian(const?BYTE*??pBuf)
{
T tResult?=?0;
for?(int??I?=?0;?I?<?sizeof(T);?++?I)
{
tResult?<<=?8;
tResult?|=?*pBuf?++;
}

return??tResult;
}

//?Set?a?little-endian?TYPE?on?a?address
template
F3D_INLINE?void SetLittleEndian(BYTE*??pBuf,?T??t)
{
for?(int??I?=?0;?I?<?sizeof(T);?++?I)
{
*pBuf?++?=?BYTE(t?&?0xFF);
t?>>=?8;
}
}

//?Set?a?big-endian?T?on?a?address
template
F3D_INLINE?void SetBigEndian(BYTE*??pBuf,?T??t)
{
pBuf?+=?sizeof(T)?-?1;
for?(int??I?=?0;?I?<?sizeof(T);?++?I)
{
*pBuf?--?=?BYTE(t?&?0xFF);
t?>>=?8;
}
}

從上文可以看出,byte?order挺簡單的,一般應用中可能也用不上,但若您對寫跨平臺的程序有興趣,則一定要了解的比較清楚才行。以上代碼都是從實際使用的源碼中取下來的。?

附:常見Processor,?OS的byte?ordering情況

Processor?OS?Order?
x86?(Intel,?AMD,?…?)?All?little-endian?
DEC?Alpha?All?little-endian?
HP-PA?NT?little-endian?
HP-PA?UNIX?big-endian?
SUN?SPARC?All??big-endian?
MIPS?NT?little-endian?
MIPS?UNIX?big-endian?
PowerPC?NT?little-endian?
PowerPC?non-NT?big-endian?
RS/6000?UNIX?big-endian?
Motorola?m68k?All?big-endian?

總結

以上是生活随笔為你收集整理的有关字节序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。