如何计算事业部提醒在SPARC大会? [英] How to calculate division reminder in SPARC Assembly?

查看:110
本文介绍了如何计算事业部提醒在SPARC大会?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是伪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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆