Odpovídáte na názor k článku Specifika instrukční sady mikroprocesorů Intel 8086/8088 (2). Názory mohou přidávat pouze registrovaní uživatelé. Nově přidané názory se na webu objeví až po schválení redakcí.
Vymenit deleni za nasobeni neni az tak trivialni jak muze vypadat.
Vetsinou ti podminky umozni to nasobit s dvojnasobnou sirkou.
A na konci to nekdy musis posouvat o par bitu doprava.
Vse kvuli zaokrouhleni.
Nedavno jsem cetl nejaky par let stary clanek, ktery ukazoval, ze ani nejlepsi prekladace nenajdou vzdy nejlepsi reseni. A vysvetloval nejake podminky, za kterych to jde udelat lepe.
Pisi jako hobby projekt prekladac pro Z80 a deleni konstanotou je... PEKLO. Vetsina veci kde se objevi konstanta je tezka, ale deleni je extrem. I modulo je lehci i kdyz jsem dlouho nevedel ze to jde delat bez deleni.
Metod na ktere jsem prisel jak udelat deleni je nekolik a kazda ma svoje podvarianty a ty nikdy nevis, ktery kod pujde nejlepe optimalizovat a bude nakonec nejlepsi.
Nasobit 6554? 16x16=32 bit...
To je zbytecne slozite (pokud procesor neumi nasobit).
U deleni 10 me nejlepe vychazi pouzit deleni 5. Protoze delit deseti je to same co "delit"dvema a pak deseti. Nebo naopak. Ale prvni se lepe optimalizuje, protoze mas uz zadarmo nasobek 2. Ktery vyuzijes protoze to prevadis na to nasobeni.
Deleni 5 se dela pres nasobeni 13107, ale drzi se to v 16x16=24 bit protoze se pouziva trik, ze ti staci to nasobit 51.
Osetrit zaokrouhleni.
A pak to vynasobit 257! 51*257=13107
A nasobeni 257 je brnkacka... protoze v ramci toho neustale to drzet na co nejmensim poctu bitu se to dela jako
(N*257)>>8
Takze ti staci hornich 8 bitu dat do spodnich a secist s puvodni hodnotou.
A ted si vem ze najit tohle pro kazde cislo je dost prace... a stejne nevis zda to nejde lepe... i kdyz to delas rucne.
dworkin@dw-A15:~/repositories/M4_FORTH$ ./check_word.sh 'PUSH(10) UDIV' ;[32:185] 10 u/ Variant HL/10 = (HL/2)*(65536/5)/65536 = (HL/2)*51*257/65536 ld B, H ; 1:4 10 u/ ld C, L ; 1:4 10 u/ srl B ; 2:8 10 u/ rr C ; 2:8 10 u/ 1x base xor A ; 1:4 10 u/ inc BC ; 1:6 10 u/ +19 rounding constant add HL, BC ; 1:11 10 u/ adc A, A ; 1:4 10 u/ 3x AHL add HL, HL ; 1:11 10 u/ inc HL ; 1:6 10 u/ +8 rounding constant adc A, A ; 1:4 10 u/ 6x AHL add HL, HL ; 1:11 10 u/ adc A, A ; 1:4 10 u/ 12x AHL add HL, HL ; 1:11 10 u/ adc A, A ; 1:4 10 u/ 24x AHL add HL, BC ; 1:11 10 u/ adc A, 0x00 ; 2:7 10 u/ 25x AHL add HL, HL ; 1:11 10 u/ adc A, A ; 1:4 10 u/ 50x AHL add HL, BC ; 1:11 10 u/ adc A, 0x00 ; 2:7 10 u/ 51x AHL with rounding constant 26..35 ld B, A ; 1:4 10 u/ (AHL * 257) >> 16 = (AHL0 + 0AHL) >> 16 = AH.L0 + A.HL = A0 + H.L + A.H ld C, H ; 1:4 10 u/ BC = "A.H" add HL, BC ; 1:11 10 u/ HL = "H.L" + "A.H" ld L, H ; 1:4 10 u/ adc A, 0x00 ; 2:7 10 u/ + carry ld H, A ; 1:4 10 u/ HL/10 = (HL/2)*(65536/5)/65536 = (HL/2)*(1+256)*51 >> 16 ; seconds: 0 ;[32:185]
Sorry, Z80 je trosku offtopic. .)