这是计算两个正整数相除的伪代码。 HR寄存器可节省余数,而LR可节省股息。(并最终保存根)
但是我认为该算法存在一些问题。 因为此算法有时无法恢复减法(除法是减法的延续)。
例如,6 / 3 (0110 / 011) 此算法再减去-3一次。(这种情况在我们手动计算时永远不会发生), 因此我认为该算法存在一些问题。 你不同意我吗?如何计算装配中的除法余数?
6 / 3 (0110 / 011)
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除法算法的示例实现:
#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; }