如何计算事业部提醒在SPARC大会? [英] How to calculate division reminder in SPARC Assembly?
问题描述
下面是伪code的计算两个正整数除法。
HR寄存器保存的提醒,和LR可以节省股息。 (并最终节省了根)
不过,我认为这个算法有一定的问题。
因为这种算法有时不恢复subtracion。(司是一个延续减法。)
例如 6/3(0110/011)
该算法减-3一次。 (当我们计算这个师的手,这种情况永远不会发生)
因此,我认为这个算法有一定的问题。
难道你不同意我的观点?
如何计算事业部提醒在大会?
对于i = 1到num_of_bits做
(HR LR)<< 1
如果(HR> = 0),则
HR = HR - DIVISOR
其他
HR = HR + DIVISOR
ENDIF
如果(HR大于0),那么LR(LSB)= 1 ENDIF
ENDFOR
我不说话SPARC ASM,但我不说话C.下面是一个简单的实现算法的16/8 = 8,8师:
的#include< stdio.h中>
的typedef unsigned char型UINT8;
的typedef无符号整型单元;
INT u8div(UINT8 * dividendh,UINT8 * dividendl,UINT8除数)
{
INT I;
如果(* dividendh> =除数)
返回0; // 溢出
对于(i = 0; I< 8;我++)
{
如果(* dividendh> = 0x80的)
{
* dividendh =(* dividendh<< 1)| (* dividendl>>(8 - 1));
* dividendl&其中;&其中; = 1;
* dividendh - =除数;
* dividendl | = 1;
}
其他
{
* dividendh =(* dividendh<< 1)| (* dividendl>>(8 - 1));
* dividendl&其中;&其中; = 1;
如果(* dividendh> =除数)
{
* dividendh - =除数;
* dividendl | = 1;
}
}
}
返回1;
}
INT u8div2(UINT8 * dividendh,UINT8 * dividendl,UINT8除数)
{
UINT分红=(* dividendh<< 8)| * dividendl;
如果(* dividendh> =除数)
返回0; // 溢出
* dividendl =股息/除数;
* dividendh =股息%除数;
返回1;
}
INT主要(无效)
{
UINT dividendh,dividendl,除数;
为(dividendh = 0; dividendh&其中; = 0xFF的; dividendh ++)
为(dividendl = 0; dividendl&其中; = 0xFF的; dividendl ++)
对于(除数= 0;除数< = 0xFF的;除数++)
{
UINT8 DIVH = dividendh,DIVL = dividendl,divr =除数;
UINT8 divh2 = dividendh,divl2 = dividendl;
的printf(为0x%04X /为0x%02X =,(DIVH<< 8)| DIVL,divr);
如果(u8div(安培; DIVH,和放大器; DIVL,divr))
的printf(0X%02X.0x%02X,DIVL,DIVH);
其他
的printf(OVF);
的printf();
如果(u8div2(安培; divh2,和放大器; divl2,divr))
的printf(0X%02X.0x%02X,divl2,divh2);
其他
的printf(OVF);
如果((DIVL!= divl2)||(DIVH!= divh2))
的printf(犯错);如果u8div()计算结果不正确//错误将被打印
的printf(\ N);
}
返回0;
}
Here is the pseudo code which computes division of two positive integers.
HR register saves reminder, and LR saves dividend. (and eventually saves root)
However I think this algorithm has some problem.
Because this algorithm sometimes don't recover subtracion.(Division is a continuation of subtraction.)
For example 6 / 3 (0110 / 011)
This algorithm subtract -3 one more time. (This situation never occur when we calculate this division by hand)
So I think this algorithm has some problem.
Don't you agree with me?
How to calculate division reminder in Assembly?
for i = 1 to num_of_bits do
(HR LR) << 1
if (HR >= 0) then
HR = HR - DIVISOR
else
HR = HR + DIVISOR
endif
if (HR > 0) then LR(lsb) = 1 endif
endfor
I don't speak SPARC asm, but I do speak C. Here's a sample implementation of the algorithm for 16/8=8,8 division:
#include <stdio.h>
typedef unsigned char uint8;
typedef unsigned int uint;
int u8div(uint8* dividendh, uint8* dividendl, uint8 divisor)
{
int i;
if (*dividendh >= divisor)
return 0; // overflow
for (i = 0; i < 8; i++)
{
if (*dividendh >= 0x80)
{
*dividendh = (*dividendh << 1) | (*dividendl >> (8 - 1));
*dividendl <<= 1;
*dividendh -= divisor;
*dividendl |= 1;
}
else
{
*dividendh = (*dividendh << 1) | (*dividendl >> (8 - 1));
*dividendl <<= 1;
if (*dividendh >= divisor)
{
*dividendh -= divisor;
*dividendl |= 1;
}
}
}
return 1;
}
int u8div2(uint8* dividendh, uint8* dividendl, uint8 divisor)
{
uint dividend = (*dividendh << 8) | *dividendl;
if (*dividendh >= divisor)
return 0; // overflow
*dividendl = dividend / divisor;
*dividendh = dividend % divisor;
return 1;
}
int main(void)
{
uint dividendh, dividendl, divisor;
for (dividendh = 0; dividendh <= 0xFF; dividendh++)
for (dividendl = 0; dividendl <= 0xFF; dividendl++)
for (divisor = 0; divisor <= 0xFF; divisor++)
{
uint8 divh = dividendh, divl = dividendl, divr = divisor;
uint8 divh2 = dividendh, divl2 = dividendl;
printf("0x%04X/0x%02X=", (divh << 8) | divl, divr);
if (u8div(&divh, &divl, divr))
printf("0x%02X.0x%02X", divl, divh);
else
printf("ovf");
printf(" ");
if (u8div2(&divh2, &divl2, divr))
printf("0x%02X.0x%02X", divl2, divh2);
else
printf("ovf");
if ((divl != divl2) || (divh != divh2))
printf(" err"); // "err" will be printed if u8div() computes incorrect result
printf("\n");
}
return 0;
}
这篇关于如何计算事业部提醒在SPARC大会?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!