我正在爲舊的8位微處理器(舊的NEC PC引擎控制檯中的Hu6280 - WDC 65C02衍生物)編寫一些代碼,內存爲32kb,最大爲2.5 mbytes數據/代碼rom。語言是小-C的變體,但僅限於以下兩種基本類型:8位微處理器上的C - 32位和16位算術
char (1 byte)
int (2 byte)
它沒有struct
支持,沒有長整型支持。
我正在寫一個FAT文件系統庫來與一個主要爲加載遊戲ROM映像而開發的SD讀卡器接口,但是一個進取的黑客已經寫了一些程序集以允許從控制檯端讀取原始扇區。他通過將32位扇區地址的4個8位值填充到4個連續的存儲器地址(char address [4];)中來實現這一點。 我的C代碼利用他的工作來讀取(目前)SD卡上的dos MBR引導扇區和分區類型信息。我有MBR校驗和驗證和FAT分區檢測工作。但是,由於我需要支持FAT32(這是SD卡設備上的FPGA支持的功能),因此查找目錄條目和文件的大部分扇區和集羣算法都將基於32位LBA扇區值。
基於上述限制,我必須做什麼簡單的機制來加/減/乘8/16/32位整數?有沒有人有任何現成的C例程來處理這個?也許沿着線的東西:
char int1[4], int2[4], int3[4];
int1[0] = 1;
int1[1] = 2;
int1[2] = 3;
int1[3] = 4;
int2[0] = 4;
int2[1] = 3;
int2[2] = 2;
int2[3] = 1;
int3 = mul_32(int1, int2);
int3 = add_32(int1, int2);
int3 = sub_32(int1, int2);`
編輯:基於上面的答覆,這是我想出迄今爲止 - 這是未經測試尚未和我需要做乘法相似,減法:
char_to_int32(int32_result, int8)
char* int32_result;
char int8;
{
/*
Takes an unsigned 8bit number
and converts to a packed 4 byte array
*/
int32_result[0] = 0x00;
int32_result[1] = 0x00;
int32_result[2] = 0x00;
int32_result[3] = int8;
return 0;
}
int_to_int32(int32_result, int16)
char* int32_result;
int int16;
{
/*
Takes an unsigned 16bit number
and converts to a packed 4 byte array
*/
int32_result[0] = 0x00;
int32_result[1] = 0x00;
int32_result[2] = (int16 >> 8);
int32_result[3] = (int16 & 0xff);
return 0;
}
int32_is_zero(int32)
char* int32;
{
/*
Is a packed 4 byte array == 0
returns 1 if true, otherwise 0
*/
if ((int32[0] == 0) & (int32[1] == 0) & (int32[2] == 0) & (int32[3] == 0)) {
return 1;
} else {
return 0;
}
}
add_32(int32_result, int32_a, int32_b)
char* int32_result;
char* int32_a;
char* int32_b;
{
/*
Takes two 32bit values, stored as 4 bytes each -
adds and stores the result.
Returns 0 on success, 1 on error or overflow.
*/
int sum;
char i;
char carry;
carry = 0x00;
/* loop over each byte of the 4byte array */
for (i = 4; i != 0; i--) {
/* sum the two 1 byte numbers as a 2 byte int */
sum = int32_a[i-1] + int32_b[i-1] + carry;
/* would integer overflow occur with this sum? */
if (sum > 0x00ff) {
/* store the most significant byte for next loop */
carry = (sum >> 8);
} else {
/* no carry needed */
carry = 0x00
}
/* store the least significant byte */
int32_result[i+1] = (sum & 0xff);
}
/* Has overflow occured (ie number > 32bit) */
if (carry != 0) {
return 1;
} else {
return 0;
}
}
編輯2:這是一個更新和測試版本的仿真32位+ 32位整數添加代碼。它適用於迄今爲止我嘗試過的所有值。 (不會被要求爲我的目的)溢出超過32位無符號整數,沒有被處理更大的價值:
add_int32(int32_result, int32_a, int32_b)
char* int32_result;
char* int32_a;
char* int32_b;
{
/*
Takes two 32bit values, stored as 4 bytes each -
adds and stores the result.
Returns 0 on success, 1 on error or overflow.
*/
int sum;
char i, pos;
char carry;
zero_int32(int32_result);
carry = 0x00;
/* loop over each byte of the 4byte array from lsb to msb */
for (i = 1; i < 5; i++) {
pos = 4 - i;
/* sum the two 1 byte numbers as a 2 byte int */
sum = int32_a[pos] + int32_b[pos] + carry;
/* would integer overflow occur with this sum? */
if (sum > 0x00ff) {
/* store the most significant byte for next loop */
carry = (sum >> 8);
} else {
/* no carry needed */
carry = 0x00;
}
/* store the least significant byte */
int32_result[pos] = (sum & 0x00ff);
}
/* Has overflow occured (ie number > 32bit) */
if (carry != 0) {
return 1;
} else {
return 0;
}
}
我也發現了一些PIC控制器32位運算提供一些參考搜索SO更後一點:
http://web.media.mit.edu/~stefanm/yano/picc_Math32.html
雖然在他們的加/減碼一些PIC彙編內聯,也有一些有用的平臺無關的基於字符-C函數有已經實施的變化,比較,遞增/遞減等,這將是非常有用。我會考慮減去並乘以下一個 - 感謝信息;我想我在看事物,並認爲他們比他們需要的更難。
8位CPU的16位算法是一個已知並且長期解決的問題,在您最喜愛的搜索引擎中進行快速搜索應該會給您足夠的結果。將其擴展到32位算術將是一樣的。 –