如何计算SPARC Assembly中的除法余数? [英] How to calculate division remainder in SPARC Assembly?

查看:121
本文介绍了如何计算SPARC Assembly中的除法余数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是计算两个正整数除法的伪代码。

HR寄存器节省了余数,LR节省了红利。 (并最终保存了根)

Here is the pseudo code which computes division of two positive integers.
HR register saves remainder, and LR saves dividend. (and eventually saves root)

但是我认为该算法存在一些问题。

因为此算法有时无法恢复减法。(除法为

However I think this algorithm has some problem.
Because this algorithm sometimes don't recover subtraction.(Division is a continuation of subtraction.)

例如 6/3(0110/011)

此算法再减去-3。 (这种情况在我们手工计算时永远不会发生)。

所以我认为该算法存在一些问题。
如何计算装配中的除法余数?

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 remainder 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


推荐答案

我不会说SPARC asm,但是我会说C。这是16/8 = 8,8除法算法的示例实现:

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 Assembly中的除法余数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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