2014-01-07 92 views
0

我正在爲舊的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函數有已經實施的變化,比較,遞增/遞減等,這將是非常有用。我會考慮減去並乘以下一個 - 感謝信息;我想我在看事物,並認爲他們比他們需要的更難。

+2

8位CPU的16位算法是一個已知並且長期解決的問題,在您最喜愛的搜索引擎中進行快速搜索應該會給您足夠的結果。將其擴展到32位算術將是一樣的。 –

回答

1

我知道你知道如何做到這一點。回到你的小學數學...

當你乘到數字,10個基本

12 
x34 
==== 

你正確的四次乘法,然後相加右四個數字?

4x2 = 8 
4x1 = 4 
3x2 = 6 
3x1 = 3 

然後

12 
    x34 
==== 
0008 
0040 
0060 
+0300 
====== 

現在來談談另外

12 
+34 
=== 

我們學會了打破下來到兩個加法

2+4 = 6 carry a zero 
1+3+carryin of 0 = 4 

有了這些知識,你已經從有兒童引擎蓋,然後你只需申請。請記住,基本的數學運算是否可以在2位數字上操作2位數字或在200萬位數字上操作200萬位數字。

以上使用單十進制數,但數學的作品,如果它是單個鹼基的16號或單位或八進制或字節等

你的C編譯器應該已經在處理這些事情對你,但如果你需要將它們綜合起來,最簡單的數字乘法就是使用位。

使用程序集的字節更容易,因爲執行是正確的,C沒有執行,因此您必須使用8位數學(可以確定)進行計算需要9位。或者你可以做少於8位數學,7或4或其他任何事情。作爲Joachim指出,這個話題幾十年前就被擊敗了。同時它非常簡單,它通常不會對很多討論提出警告。 StackOverflow當然有幾次覆蓋了這個話題。