Data Storage Formats數(shù)據(jù)存儲格式
這一部說明可用的數(shù)據(jù)類型的存儲格式。Cx51提供了幾種數(shù)據(jù)存儲格式如下:
Data Type Bits Bytes Value Range
bit 1 — 0 to 1
signed char 8 1 -128 to +127
unsigned char 8 1 0 to 255
enum 8 / 16 1 or 2 -128 to +127 or -32768 to +32767
signed short 16 2 -32768 to +32767
unsigned short 16 2 0 to 65535
signed int 16 2 -32768 to +32767
unsigned int 16 2 0 to 65535
signed long 32 4 -2147483648 to 2147483647
unsigned long 32 4 0 to 4294967295
float 32 4 ±1.175494E-38 to ±3.402823E+38
data *, idata *, pdata * 8 1 0x00 to 0xFF
code*, xdata * 16 2 0x0000 to 0xFFFF
generic pointer 24 3 Memory type (1 byte); Offset (2 bytes) 0 to 0xFFFF
其他數(shù)據(jù)類型如結(jié)構(gòu)體和聯(lián)合,可以包含上表中類型。所有的元素都按順序分配,并且按8051家簇的8bit字節(jié)對齊。
Bit Variables位變量
Bit類型的數(shù)量以使用單個位存放。位指針和位數(shù)組是不允許使用的。Bit對象總是放在8051CPU內(nèi)部數(shù)據(jù)存儲器的位可尋址區(qū)。如果可能的話,BL51 連接器/定位器會覆蓋位對象
Signed and Unsigned Characters,
Pointers to data, idata, and pdata
Char類型的變量存入在一個字節(jié)內(nèi)部。特定存儲區(qū)域的指針(指向data, idata, pdata)也存放在一個字節(jié)內(nèi)部。如果枚舉類型可以用一個8bit的值代替,枚舉類型也放在一個字節(jié)內(nèi)部。
Signed and Unsigned Integers,
Enumerations, Pointers to xdata and code
Int類型,short類型enum類型和特定存儲區(qū)域指針(指向xdata和code)使用2個字節(jié)(16bits)。高位字節(jié)放在前面,低位字節(jié)在后面。如:整型的0x1234在存儲器的存放方式為:
Address +0 +1
Contents 0x12 0x34
Signed and Unsigned Long Integers
Long類型占用4個字節(jié)。字節(jié)的存放也是從高位字節(jié)到低位字節(jié)。如0x12345678在存儲器的存放方式為:
Address +0 +1 +2 +3
Contents 0x12 0x34 0x56 0x78
Generic and Far Pointers
一般指針沒的明確聲明的類型,它可以指向8051的任一存儲區(qū)域。這些指針的存入使用3個字節(jié)。第一字節(jié)存放一個表明存儲器區(qū)域或存儲器類型的值。其他的兩個字節(jié)存放地址的偏移量,偏移量的高位在前,低位在后。格式如下:
Address +0 +1 +2
Contents Memory Type Offset; High-Order Byte Offset; Low-Order Byte
根據(jù)編譯器的版本,存儲器類型有以下值:
Memory Type idata / data / bdata xdata pdata code
C51 Compiler (8051 devices) 0x00 0x01 0xFE 0xFF
CX51 Compiler (Philips 80C51MX) 0x7F 0x00 0x00 0x80
Philips 80C51MX構(gòu)架支持新的工作在通用指針上的CPU指令。通用指針等同于Cx51的通用指針
一般指針的格式與far針的格式相同。因此,任何其他類型的存儲器類型值都可以用作尋址far存儲器空間
以下是一般指針的存儲格式,地址為0x1234
Address +0 +1 +2
Contents 0x01 0x12 0x34
Floating-point Numbers
Float類型的存放使用4個字節(jié)。格式的存放符合IEEE-754標(biāo)準(zhǔn)
一個浮點(diǎn)數(shù)由兩部分組成:尾數(shù)和指數(shù)。尾數(shù)存放數(shù)據(jù)值的實(shí)際的小數(shù)點(diǎn)。指數(shù)存放尾數(shù)的權(quán)值。指數(shù)是一個8bit的0-255的值,相對于127存放。實(shí)際的值是存放的值減去127。值域的范圍為+128到-127。尾數(shù)是一個24bit的數(shù),它的最高位總是1。因此不存儲。還有一符號位用以表明此浮點(diǎn)數(shù)是正數(shù)還是負(fù)數(shù)。
浮點(diǎn)數(shù)用以下方式存儲在8051存儲器中:
Address +0 +1 +2 +3
Contents SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
S: 符號位,0代表正,1代表負(fù)
E: 指數(shù),2的補(bǔ)碼,偏移量為127
M: 23位尾數(shù),最高位總是為1,因此不存儲
使用上述格式,浮點(diǎn)數(shù)-12.5就應(yīng)該存放為0xc1480000。在存儲器以下方式出現(xiàn):
Address +0 +1 +2 +3
Contents 0xC1 0x48 0x00 0x00
從浮點(diǎn)數(shù)到它的十六進(jìn)制表示相當(dāng)容易。以下示例其過程:
浮點(diǎn)數(shù)的存放不是一個直接的格式。要轉(zhuǎn)換必須把浮點(diǎn)數(shù)據(jù)的幾部分分開,如:
Address +0 +1 +2 +3
Format SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM
Binary 11000001 01001000 00000000 00000000
Hex C1 48 00 00
從而可以分離以下信息:
符號位為1,說明是一個負(fù)數(shù)。指數(shù)10000010B或130DEC,減去127等于3,尾數(shù)的二進(jìn)制表示為:10010000000000000000000
加上前面總是一個1,尾數(shù)為:
1.10010000000000000000000
現(xiàn)在,根據(jù)指數(shù)據(jù)調(diào)整尾數(shù):左移3位,即:
1100.10000000000000000000
這就是這個浮點(diǎn)數(shù):轉(zhuǎn)換為十進(jìn)制數(shù)為1*2^+1*2^2+0*2^1+0*2^0+1*2^(-1)=12.5
Floating-point Errors
8051沒有獲取浮點(diǎn)錯誤的中斷向量。因此,用戶程序必須正確處理這些錯誤狀態(tài)。浮點(diǎn)數(shù)可能包含錯誤的二進(jìn)制值。這個值被表示為IEEE標(biāo)準(zhǔn)的一部分,并且用來表示浮點(diǎn)處理出現(xiàn)錯誤。用戶代碼應(yīng)該在每一個浮點(diǎn)運(yùn)算過后檢查可能存在的算述運(yùn)算錯誤。
名字 值 意義
NaN 0xFFFFFFF 不是一個數(shù)
+INF 0x7F80000 正向溢出
-INF 0xFF80000 負(fù)向溢出
注:在Cx51中可以使用_chkfloat_可以快速地檢查浮點(diǎn)數(shù)標(biāo)志
可以使用以下聯(lián)合方式存儲浮點(diǎn)數(shù):
union f {
float f; /* Floating-point value */
unsigned long ul; /* Unsigned long value */
};
這個聯(lián)合包括一個浮點(diǎn)數(shù)和一個無符號整形來進(jìn)行浮點(diǎn)數(shù)學(xué)運(yùn)算和響應(yīng)IEEE錯誤狀態(tài)。例如:
#define NaN 0xFFFFFFFF /* Not a number (error) */
#define plusINF 0x7F800000 /* Positive overflow */
#define minusINF 0xFF800000 /* Negative overflow */
union f {
float f; /* Floating-point value */
unsigned long ul; /* Unsigned long value */
};
void main (void) {
float a, b;
union f x;
x.f = a * b;
if (x.ul == NaN || x.ul == plusINF || x.ul == minusINF) {
/* handle the error */
}
else {
/* result is correct */
}
}
Accessing Absolute Memory Locations
評論
查看更多