深入分析存储器的位宽及与C的关系
?一、硬件參數
1、CPU:s3c44b0x
字長32位;以字節為單位編址;數據處理支持三種數據類型:字節(8位)、半字(16位)、字(32位);存儲方式有大小端之分;25根地址線。
?
?
2、存儲器
Ⅰ?? Flash ROM: ?SST39VF1601
數據位寬為16位(16根數據線);20根地址線;2M(1M*16bit)。
?
Ⅱ?? SDRAM:? HY57V641620HG
數據位寬為16位(16根數據線);12根地址線(行地址選擇線有12根,列地址選擇線有8根(12根的低8根)),2根bank選擇線,總共有22根有效地址線;8M(4bank*1M*16bit)。
?
?
3、
CPU編址:以字節(8bit)為單位
存儲器編址:以其位寬為單位,也就是說每個存儲器地址下的數據位數為位寬。如
8K*12bit的存儲器中的12就是存儲器的位寬,指每個存儲器地址下數據的位數。
這個12與地址線的多少無關,8K就是指有8K個不同的地址8K=8*1024=2^??? 2的多少次方等于8*1024就有多少根地址線,8=2^3,? 1024=2^10, 那么8K=2^13 ,存儲器地址線就為13根。
?
?
?
二、存儲器容量、位寬及其地址線根數三者之間的關系
1、存儲容量計量單位的換算
1M(MB,mbyte)=2^10K(KB,kbyte)=2^20B(byte);
1Mb(Mbit)=2^10Kb(kbit)=2^20b(bit);
1字(Word)=2半字(half word)=4字節(B,byte)=4×8位(b,bit)。
?
?
2、關系的確立
以上面的SST39VF1601為例,
存儲容量2M=16Mbit=16*2^20bit,
地址線尋址范圍:2^20*16bit(地址線根數20,位寬16)。
?
?
以上面的HY57V641620HG為例,
存儲容量8M=8*8Mbit=64*2^20bit,
地址線尋址范圍:2^22*16bit=64*2^20bit(地址線根數22,位寬16)。
?
?
總結:
存儲器位寬表示每個地址下有多少位數據,與它的數據線根數相等;
存儲器的地址線根數(N)決定了它的地址編號范圍(2^N);
存儲器的位寬與它的地址線根數是沒有聯系的;
而存儲器容量是位寬與2^N的乘積,此處單位為bit。
?
?
?
三、CPU的尋址
CPU編址:每個cpu地址編碼中存放一個8位數據
CPU的字長為N
最大尋址范圍為2^N
?
?
四、存儲器位寬與CPU和存儲器地址線連接方式之間的聯系
1、詳情可參見文章《外設位寬為8、16、32時,CPU與外設之間地址線的連接方法》。
| CPU地址編號(每個地址存放8位數據) | 存儲器地址編號(每個地址存放16位數據) | |
| 00000(8位數據) | 00001(8位數據) | 00000(16位數據) |
| 00010 | 00011 | 00001 |
| 00100 | 00101 | 00010 |
| 00110 | 00111 | 00011 |
| 01000 | 01001 | 00100 |
上表是CPU地址與存儲器地址對應關系。
2、此步是在硬件層面實現的,軟件層面不必再做考慮。
?
?
?
五、數據類型及其在內存中的存儲形式
1、整型數據
| 類型 | 符號表示 | 內存中占用的位數 | 數值范圍 |
| 無符號 基本整型 | unsigned [int] | 16(2字節) | -2^15 – (2^15-1) |
| 有符號 基本整型 | [signed] int | 16(2字節) | 0 – (2^16-1) |
| 無符號 短整型 | unsigned short [int] | 16(2字節) | -2^15 – (2^15-1) |
| 有符號 短整型 | [signed] short [int] | 16(2字節) | 0 – (2^16-1) |
| 無符號 長整型 | unsigned long [int] | 32(4字節) | -2^31 – (2^31-1) |
| 有符號 長整型 | [signed] long [int] | 32(4字節) | 0 – (2^32-1) |
注:有符號整型數據的最高位為符號位。[]內的是可要可不要的
?
2、實型數據
| 類型 | 符號表示 | 內存中占用位數 | 有效位數 | 數值范圍 |
| 單精度型 | float | 32(4字節) | 6-7 | -3.4*10^(-38)-3.4*10^38 |
| 雙精度型 | double | 64(8字節) | 15-16 | -1.7*10^(-308)-1.7*10^308 |
| 長雙精度型 | long double | 64(8字節) | 18-19 | -1.2*10^(-4932)-1.2*10^4932 |
3、字符型數據
| 類型 | 符號表示 | 內存中占用位數 | 數值范圍 |
| 無符號字符型 | unsigned char | 8(1字節) | 0 - 255 |
| 有符號字符型 | signed char | 8(1字節) | -128 - 127 |
注:字符型數據和整型數據是通用的,但是應注意字符型數據只占用一個字節,它只能存放0 – 255范圍內的整型數據。
?
六、底層編程實現CPU對存儲器進行不同類型數據的讀寫操作
?
#define INT32U unsigned int // 16位無符號基本整型
#define INT16U unsigned short //16位無符號短整型
#define S32 int // 16位有符號基本整型
#define S16 short int // 16位無符號短整型
#define U8? unsigned char //8位無符號字符型
#define?? S8? char //8位有符號字符型,
?
1、接下來的這兩個宏是對SST39VF1601 進行16位無符號短整型讀寫操作:
?
#define? Writeflash(addr,dat)??? *((volatile INT16U *)(addr<<1))=(INT16U)dat
#define? Readflash(addr)????????? (*((volatile INT16U *)(addr<<1)))
?
解析:
addr<<1的主要目的就是使cpu的地址編號變化能跟上每存儲一個單元數據地址編號的變化的步伐。這里的addr是CPU的地址編號,與存儲器的地址編號無關。
第一個16位數據占據了CPU的兩個地址編號00000和00001,因為CPU的每個地址編號只能存放8位的數據。第二個16位數據占據00010和00011兩個CPU地址編號。
CPU地址編號左移1位目的是同步每存儲一個單元數據所引起的CPU地址編號變化和CPU地址編號實際的變化,使CPU地址編號跨越1個編號正常進入下一個16位數據。
若不左移1位,當addr是00001時將取出00001和00010這兩個CPU地址編號處的16位數據,這與前面數據所占得CPU的地址編號是不一致的。
?
?
2、接下來這兩個宏是對HY57V641620HG進行8位字符型數據的讀寫操作:
?
#define? WriteSdram(address,data) ????? *((volatile U8 *)(address))=(U8)data
#define? ReadSdram(address)???????? ??? *((volatile U8 *)(address))
?
解析:
第一個8位數據占據了CPU地址編號00000, 第二個8位數據占據了CPU地址編號00001。因此這里每8位數據占據的地址編號只有一個,CPU地址編號就不必如前面讀寫操作對address左移1位以適應每存儲一個單元數據地址編號變化的步伐。
?
3、總結:
這里的左移與存儲器和CPU地址線的錯開一位接法方式是沒有聯系的,千萬不要將兩者混淆了。前者是在軟件層面上實現的,后者是在硬件層面地址自動實現轉換的。左移操作的起因:CPU每個地址編號只能存放8位數據,而對存儲器存取數據類型占用字節數超過一個字節(8位數據)。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的深入分析存储器的位宽及与C的关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 外设位宽为8、16、32时,CPU与外设
- 下一篇: C语言中无符号数和有符号数相加问题