2

以下は、2 つの正の整数の除算を計算する疑似コードです。
HR レジスタは余りを保存し、LR レジスタは被除数を保存します。(そして最終的にルートを保存します)

しかし、このアルゴリズムには問題があると思います。
このアルゴリズムでは引き算が元に戻らないことがあります(割り算は引き算の続きです)。

たとえば、6 / 3 (0110 / 011)
このアルゴリズムはもう一度 -3 を減算します。(この割り算を手で計算する場合、このような状況は発生しません)
したがって、このアルゴリズムには問題があると思います。
あなたは私に同意しませんか?アセンブリで除算剰余を計算する方法は?

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
4

2 に答える 2

3

除算アルゴリズム (剰余も計算する) のいくつかの実装は、SPARC アーキテクチャ マニュアルの付録 E に記載されています。

新しいバージョンの SPARC アーキテクチャには、除算演算子 UDIV および SDIV が含まれています。

さらなる実装については、こちらを参照してください。

于 2011-10-10T06:24:13.770 に答える
1

私は SPARC asm は話せませんが、C は話せます。16/8=8,8 除算のアルゴリズムの実装例を次に示します。

#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;
}
于 2011-10-10T05:57:18.917 に答える