- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在为旧的 8 位微处理器(Hu6280 - 旧 NEC PC-Engine 控制台中的 WDC 65C02 衍生产品)编写一些代码,该微处理器具有 32kb 的 RAM 和高达 2.5MB 的数据/代码 ROM。该语言是 Small-C 的变体,但仅限于以下两种基本类型:
char (1 byte)
int (2 byte)
它没有struct
支持,也没有long int支持。
我正在编写一个 FAT 文件系统库来与 SD 卡读卡器交互,该读卡器主要是为加载游戏 ROM 镜像而开发的,但是一位有进取心的黑客编写了一些程序集以允许从控制台端读取原始扇区。他通过将 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 Controller 上对 32 位算术的引用:
http://web.media.mit.edu/~stefanm/yano/picc_Math32.html
虽然它们的加/减代码中有一些内联的 PIC 汇编,但那里有一些有用的与平台无关的基于字符的 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 位数字进行运算,还是用 200 万位数字对 200 万位数字进行运算,基本数学都是有效的。
上面使用单个十进制数字,但如果它是单个基数 16 数字或单个位或八进制或字节等,则数学有效。
您的 C 编译器应该已经为您处理这些事情,但如果您需要综合它们,您可以,最简单的数字乘法形式是使用位。
使用汇编的字节加法更容易,因为进位就在那里,C 没有进位,所以你必须使用 8 位数学(可以确定)来完成计算进位的练习,而不需要第 9 位。或者你可以做一些少于 8 位数学、7 位或 4 位或其他的数学运算。
正如 Joachim 指出的那样,这个话题在几十年/几个世纪前就已经被击败了。同时,它又是如此简单,以至于通常不需要进行太多讨论。 StackOverflow 确实多次讨论过这个主题。
关于c - 8 位微处理器上的 32 位和 16 位算术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20969808/
这段代码有什么问题?我是 c 的新手,但我无法通过在 if 语句中使用宏来理解我做错了什么。它给了我一个意外的 token 错误。 #define PBrun PORTBbits.RB10 #defi
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 8 年前。 Improve
我想在两个设备之间创建一个简单而强大的通信协议(protocol):主设备和从设备。主机可以是 pc 或 arm iMX6 bard 或具有 QT 或 Visual Studio 应用程序的等效板,而
我是一名优秀的程序员,十分优秀!