Bonjour
Pour faire des additions avec plus de 20 chiffres significatifs sans être pénalisé par des lenteurs je souhaite faire en Asm une fonction à laquelle je donne en entrée deux chaînes-numériques de longueur non limitée et qui renvoie le résultat de l’addition sous forme d’une autre chaîne dont les caractères numériques sont obtenus comme on apprend à l’école dans le style « 8 + 9 = JePose 7 et JeRetiens 1 ». A cet effet les chaînes envoyées en entrée sont des chaînes calibrées de même longueur et commençant par au moins un ‘0’ (ou davantage s’il faut ajuster l’une à l’autre).
Bien que je sois nul en Asm j’ai réussi à bidouiller une fonction qui réalise ce résultat très très maladroitement avec un fonction que j’aimerais donc optimiser sous plusieurs aspects :
- extension aux calculs sur des chaines-numériques du type String ou Pchar (au lieu des ShortString’s)
- soulagement des calculs par des précalculs résumés dans les deux tableaux suivants :
La fonction Asm à optimiser :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 type TTabPoseRetiens = array['0'..'9','0'..'9'] of Char; const AdditionJePose : TTabPR = (('0','1','2','3','4','5','6','7','8','9'), ('1','2','3','4','5','6','7','8','9','0'), ('2','3','4','5','6','7','8','9','0','1'), ('3','4','5','6','7','8','9','0','1','2'), ('4','5','6','7','8','9','0','1','2','3'), ('5','6','7','8','9','0','1','2','3','4'), ('6','7','8','9','0','1','2','3','4','5'), ('7','8','9','0','1','2','3','4','5','6'), ('8','9','0','1','2','3','4','5','6','7'), ('9','0','1','2','3','4','5','6','7','8')) const AdditionJeRetiens : TTabPR = (('0','0','0','0','0','0','0','0','0','0'), ('0','0','0','0','0','0','0','0','0','1'), ('0','0','0','0','0','0','0','0','1','1'), ('0','0','0','0','0','0','0','1','1','1'), ('0','0','0','0','0','0','1','1','1','1'), ('0','0','0','0','0','1','1','1','1','1'), ('0','0','0','0','1','1','1','1','1','1'), ('0','0','0','1','1','1','1','1','1','1'), ('0','0','1','1','1','1','1','1','1','1'), ('0','1','1','1','1','1','1','1','1','1'))Ayant testé les performances de rapidité des fonctions utilisées par la calculatrice-pour-grands-nombres proposée dans les codes-source il s’avère que celles-ci sont fortement sanctionnées dans le cas d’appels répétitifs dans des boucles du fait de la lenteur des conversions des chaînes-numériques vers des Array Of Int64 et réciproquement, inutile donc de me proposer ce type de solution (qui reste néanmoins valable pour une calculatrice utilisée hors boucle)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 function AdditionAsm(str1,str2 : shortString; Len : Integer) : shortString; // str1 et str2 en entrée : de même longueur avec mini un 0 au début // str1 = '09123457891235469785743258714586027895' // str2 = '01234568524563759158521739582461397461' // Resultat = '10358026415799228944264998297047425356' var Pose,Retiens : byte; Res : shortString; begin Retiens:=0; Res:=StringOfChar(' ',Len); asm PUSHFD PUSHAD PUSH ESI PUSH EDX PUSH EDI PUSH ECX LEA ESI, str1 // source LEA EDX, str2 // 2ème source LEA EDI, res // destination STD // incrémenter de la fin vers le début ADD ESI, Len // Initialisation à l'offset de ADD EDI, Len // début des chaînes + Len ADD EDX, Len // idem MOV ECX, Len @Boucle: LODSB // Calcul de Pose:="s1[i] + s2[i] + retenue" MOV Pose,AL // caractère de str1 MOV AH,Retiens ADD Pose,Ah MOV AH, Byte ptr[EDX] // caractère de str2 ADD Pose,AH SUB Pose,96 CMP Pose,10 JB @Inf SUB Pose,10 MOV AL,Pose MOV Retiens,1 //retenue = 1 JMP @Suite @Inf: MOV AL,Pose MOV Retiens,0 //retenue = 0 @Suite: ADD AL,48 DEC EDX //caractère précédent de str2 STOSB LOOP @Boucle @Sors: POP ECX POP EDI POP EDX POP ESI POPAD POPFD end; //asm //res:=trim(res); Result:=res; end; // AdditionAsm
Par contre si quelqu’un a de bonnes idées pour rectifier le code de la fonction ci-dessus en Asm cela m’enlèverait une épine du pied et peut-être que d’autres seraient également intéressés par la fonction rectifiée.
Merci par avance.
A+
Partager