2010-10-26 3 views
0

J'essaye d'écrire en langage assemblé un tri par fonction. Il va trier le tableau à deux dimensions de sorte que les lignes contiendront maintenant des données dans l'ordre alphabétique. J'ai essayé beaucoup de choses mais c'est franchement au-delà de mes connaissances actuelles. voici ce que j'ai essayé jusqu'à présent ...Tri d'une chaîne de caractères dans l'assemblage

.386 
public _Sort 
.model flat 
.code 
_Sort proc 

    push ebp 
    mov ebp, esp 
    push esi 
    push edi 

    mov edi, [esp + 4] ; address of destination array 
    mov esi, [esp + 8] ; address of source array 
    mov ecx, [esp + 16] ; # of elements to mov 
    cld 
    rep movsd 
L1: 
    mov eax, [esi] 
    cmp [esi + 8], eax 
    jg L2 
    xchg eax, [esi + 8] 
    mov [esi], eax 
L2: 
    pop edi 
    pop esi 
    pop ebp 

    ret  
_Sort endp 
end 

Voici le code C++ ...

#include <iostream> 

using namespace std; 

extern "C" int Sort (char [] [20], int, int); 

void main() 
    { 
    char Strings [10] [20] 
        = { "One", 
         "Two", 
         "Three", 
         "Four", 
         "Five", 
         "Six", 
         "Seven", 
         "Eight", 
         "Nine", 
         "Ten" }; 
    int i; 
    cout << "Unsorted Strings are" << endl; 
    for (i = 0; i < 10; i++) 
     cout << '\t' << Strings [i] << endl; 
    Sort (Strings, 10, 20); 
    cout << "Sorted Strings are" << endl; 
    for (i = 0; i < 10; i++) 
     cout << '\t' << Strings [i] << endl; 
    } 

Je réalise mon assemblée n'a pas de sens, désolé.

Répondre

2

Vous voudrez construire votre code d'assemblage dans des fonctions/procédures, comme vous le feriez dans d'autres langages. Tout comme dans C, comparaison de chaînes, copie, etc., devra être fait dans les fonctions. Juste par exemple:

; compares [esi] to [edi], returns +, 0 or - to indicate order 
; inputs: esi, edi: addresses of strings 
; destroys: esi, edi, edx 
; 
strcmp_int proc 
    jmp short start 
loop_top: 
    inc esi 
    inc edi 
start: 
    movsx eax, byte ptr [esi] 
    movsx edx, byte ptr [edi] 
    test edx, edx 
    jz @f 
    sub eax, edx 
    jz loop_top 
    ret 
@@: 
    sub eax, edx 
    ret 
strcmp_int endp 

[Avertissement: ce code est pas nécessairement destiné à être utilisé tel quel - juste un exemple de l'un des types de fonctions que vous aurez normalement besoin d'écrire pour faire ce genre d'emploi en langue d'assemblage. Cela fait assez longtemps que j'ai écrit beaucoup de langage assembleur que vous pouvez sans aucun doute faire mieux sur un processeur moderne - et au moins pour les choses faites en langage assembleur, vous voulez normalement mettre des résultats dans des drapeaux, plutôt qu'un -/0/+ dans un registre comme strcmp (et cela) produire. Mais notez que ce -t retour avec des drapeaux fixés par la sub finale]

Voir aussi Why is memcmp so much faster than a for loop check? pour quelques liens vers des implémentations optimisées (SSE2/de AVX2) pour les chaînes de longueur explicite, ce qui peut être beaucoup plus rapide pour les moyennes et longues chaînes . Pour les liens d'optimisation en général, voir the x86 tag wiki.

Votre sort dépend de l'algorithme de tri que vous décidez d'implémenter. Évidemment, un Quicksort ne ressemblera pas à un tri par insertion. Le point principal, cependant, est simple: n'essayez pas de l'écrire comme un seul bloc monolithique de code — en le décomposant en morceaux qui sont individuellement faciles à écrire et à comprendre.

+0

'lodsb' incrémente déjà' esi'. Utilisez 'movzx eax, [esi]' pour plus d'efficacité ('lodsb' est de 3 uops sur les processeurs Intel, cela ne vaut pas la peine par rapport à' inc'/'movzx'). Utilisez aussi 'cmp al, [edi]' au lieu de sub, de sorte qu'il peut fusionner avec 'jz' sur plusieurs processeurs. –

+0

En outre, cela dépasse la fin des chaînes si elles sont égales à la fin '0'>. < –

+0

Évidemment, pour plus d'efficacité, vous devez comparer les mots de passe ou les mots de passe (ou mieux utiliser SSE2). Avec SSE2, il est également facile de vérifier chaque octet pour '0' en parallèle, mais pour le code entier, vous pouvez utiliser https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord. (Des charges plus larges deviennent difficiles avec deux chaînes de longueur implicite si elles sont décalées les unes par rapport aux autres. [Ce n'est pas aussi simple que de faire des charges alignées comme avec 'strlen'] (https://stackoverflow.com/questions/37800739/ est-il-sûr-de-lire-passé-la-fin-d'un tampon-dans-la-même-page-sur-x86-et-x64).) –

Questions connexes