[英]C - 32bit & 16bit arithmetic on 8bit microprocessor
我正在为旧的8位微处理器(Hu6280-旧的NEC PC-Engine控制台中的WDC 65C02衍生物)编写一些代码,该文件具有32kb的ram和高达2.5mbytes的数据/代码rom。 该语言是Small-C的一种变体,但仅限于以下两种基本类型:
char (1 byte)
int (2 byte)
它没有struct
支持,也没有长期的int支持。
我正在编写一个FAT文件系统库,以便与主要用于加载游戏ROM映像的SD卡读卡器接口,但是,一个进取的黑客编写了一些程序集,以允许从控制台端读取原始扇区。 他通过将32位扇区地址的4个8位值填充到4个连续的内存地址(字符地址[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位算术的引用:
http://web.media.mit.edu/~stefanm/yano/picc_Math32.html
尽管在它们的加/减代码中有一些PIC汇编内联函数,但是那里有一些有用的基于平台不可知论的基于C的C函数,这些函数已经实现了移位,比较,递增/递减等功能,这将非常有用。 我将研究减法和乘以下一步-感谢您提供的信息; 我想我正在看事物并认为它们比所需的要难得多。
我知道你知道该怎么做。 回到你的小学数学...
乘以数字时,以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位数字运算还是2百万位数字用2百万位数字运算,基本数学运算都是有效的。
上面使用的是一个十进制数字,但是如果它是单个基数16个数字或单个位或八进制或字节等,则该数学运算有效。
您的C编译器应该已经为您处理了这些事情,但是如果您需要对其进行合成,则数字的最简单形式就是使用位。
使用汇编使用字节进行加法比较容易,因为进位就在那儿,C没有进位,因此您必须使用8位数学运算(可以确定)来练习执行进位,而无需第9位。 或者您可以做少于8位数学,7或4或其他任何事情。
正如约阿希姆(Joachim)所指出的那样,这个主题在几十个世纪之前就被打死了。 同时,它是如此简单,以至于经常不引起很多讨论。 当然,StackOverflow已经多次讨论了该主题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.