8086 Zgromadzenie, 23 28 25 24 bajty
8bc8 d1e9 33db 33d2 50f7 f158 85d2 7502 03d9 7204 e2f0 3bc3
Niezmontowane:
; calculate if N (1 < N <= 65535) is abundant
; input: N (mem16/r16)
; output: CF=1 -> abundant, CF=0 -> not abundant
ABUND MACRO N
LOCAL DIV_LOOP, CONT_LOOP, END_ABUND
IFDIFI <N>,<AX> ; skip if N is already AX
MOV AX, N ; AX is dividend
ENDIF
MOV CX, AX ; counter starts at N / 2
SHR CX, 1 ; divide by 2
XOR BX, BX ; clear BX (running sum of factors)
DIV_LOOP:
XOR DX, DX ; clear DX (high word for dividend)
PUSH AX ; save original dividend
DIV CX ; DX = DX:AX MOD CX, AX = DX:AX / CX
POP AX ; restore dividend (AX was changed by DIV)
TEST DX, DX ; if remainder (DX) = 0, it divides evenly so CX is a divisor
JNZ CONT_LOOP ; if not, continue loop to next
ADD BX, CX ; add number to sum
JC END_ABUND ; if CF=1, BX has unsigned overflow it is abundant (when CX < 65536)
CONT_LOOP:
LOOP DIV_LOOP
CMP AX, BX ; BX<=AX -> CF=0 (non-abund), BX>AX -> CF=1 (abund)
END_ABUND:
ENDM
Przykładowy program testowy, testujący N = [12..1000]:
MOV AX, 12 ; start tests at 12
LOOP_START:
ABUND AX ; call ABUND MACRO for N (in AX)
JNC LOOP_END ; if not abundant, display nothing
CALL OUTDECCSV ; display AX as decimal (generic decimal output routine)
LOOP_END:
INC AX ; increment loop counter
CMP AX, 1000 ; if less than 1000...
JBE LOOP_START ; continue loop
RET ; return to DOS
Wyjście [2..1000]
12, 18, 20, 24, 30, 36, 40, 42, 48, 54, 56, 60, 66, 70, 72, 78, 80, 84, 88, 90, 96, 100, 102, 104, 108, 112, 114, 120, 126, 132, 138, 140, 144, 150, 156, 160, 162, 168, 174, 176, 180, 186, 192, 196, 198, 200, 204, 208, 210, 216, 220, 222, 224, 228, 234, 240, 246, 252, 258, 260, 264, 270, 272, 276, 280, 282, 288, 294, 300, 304, 306, 308, 312, 318, 320, 324, 330, 336, 340, 342, 348, 350, 352, 354, 360, 364, 366, 368, 372, 378, 380, 384, 390, 392, 396, 400, 402, 408, 414, 416, 420, 426, 432, 438, 440, 444, 448, 450, 456, 460, 462, 464, 468, 474, 476, 480, 486, 490, 492, 498, 500, 504, 510, 516, 520, 522, 528, 532, 534, 540, 544, 546, 550, 552, 558, 560, 564, 570, 572, 576, 580, 582, 588, 594, 600, 606, 608, 612, 616, 618, 620, 624, 630, 636, 640, 642, 644, 648, 650, 654, 660, 666, 672, 678, 680, 684, 690, 696, 700, 702, 704, 708, 714, 720, 726, 728, 732, 736, 738, 740, 744, 748, 750, 756, 760, 762, 768, 770, 774, 780, 784, 786, 792, 798, 800, 804, 810, 812, 816, 820, 822, 828, 832, 834, 836, 840, 846, 852, 858, 860, 864, 868, 870, 876, 880, 882, 888, 894, 896, 900, 906, 910, 912, 918, 920, 924, 928, 930, 936, 940, 942, 945, 948, 952, 954, 960, 966, 968, 972, 978, 980, 984, 990, 992, 996, 1000
Wyjście [12500..12700]
12500, 12504, 12510, 12512, 12516, 12520, 12522, 12528, 12530, 12534, 12540, 12544, 12546, 12552, 12558, 12560, 12564, 12570, 12572, 12576, 12580, 12582, 12584, 12588, 12594, 12600, 12606, 12612, 12618, 12620, 12624, 12628, 12630, 12636, 12640, 12642, 12648, 12650, 12654, 12656, 12660, 12666, 12670, 12672, 12678, 12680, 12684, 12688, 12690, 12696, 12700
Wyjście [25100..25300]
25100, 25104, 25110, 25116, 25120, 25122, 25128, 25130, 25134, 25140, 25144, 25146, 25152, 25158, 25160, 25164, 25168, 25170, 25172, 25176, 25180, 25182, 25188, 25194, 25200, 25206, 25212, 25216, 25218, 25220, 25224, 25228, 25230, 25232, 25236, 25240, 25242, 25245, 25248, 25254, 25256, 25260, 25266, 25270, 25272, 25278, 25280, 25284, 25290, 25296, 25300
Aktualizacje:
- Naprawiono 16-bitowe przepełnienie (+5 bajtów). Dzięki @deadcode za sugestie!
- Uproszczona logika powrotu (-3 bajty). Dziękujemy za pomoc w @deadcode jeszcze raz.
- Użyj TEST zamiast CMP (-1 bajt). Dzięki za @ l4m2!