begin process at 2012 05 25 04:58:33
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Assembleur

 > 

Processeurs

 > 

X86

 > 

Inversion de chaîne


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Inversion de chaîne

lundi 18 décembre 2006 à 18:02:31 | Inversion de chaîne

Bidou

Administrateur CodeS-SourceS
Bonjour à tous,
A vrai dire je suis plutôt nouveau en asm et pas très bon lol. Mais bon, faut bien commencer un jour hein.
Pour me faire la main, j'ai écrit une petite méthode qui permet d'inverser une chaîne de caractère...

J'aimerais savoir si on peut faire mieux (sûrement que oui) et que les connaisseurs me corrigent
Merci d'avance

int

reverseStr(char str1[], char str2[])
{
  
int len = -1;

   __asm
  
{
      XOR EAX, EAX
// Current char
     
XOR EBX, EBX // Counter
     
XOR EBX, [len]
     
XOR ECX, ECX
     
XOR EDX, EDX

      MOV ESI, [EBP+8]

// Reference (1st string)
     
MOV EDI, [EBP+12] // Reference (2nd string)

   LoopStr:
      INC EBX
      MOV AL, [ESI+EBX]
      CMP AL, 0
      JNE LoopStr
     

// Save length
     
MOV len, EBX 
      MOV [EDI+EBX],
'\0'
     
MOV EDX, EBX
      DEC EDX
   LoopRev:

DEC EBX
      MOV ECX, EDX
      MOV AL, [ESI+EBX]
      SUB ECX, EBX
      MOV [EDI+ECX], AL
      CMP EBX, 0
      JNE LoopRev
   }
  

return len;
}




-Blog-
mardi 19 décembre 2006 à 20:37:22 | Re : Inversion de chaîne

BruNews

Administrateur CodeS-SourceS

Calcul de longueur est totalement inutile, une chaine doit finir par un 0, suffit de mettre un pointeur sur le dernier char.

Cette routine se fait tranquille avec les 3 registres généraux et donc rien à PUSHer POPer.
Mettre de l'asm dans une fonction en C est la pire des solutions, ça empêche toute optimisation du compilo. Si on la fait en asm alors FULL asm ou rien.

__declspec(naked) void __fastcall bnRevStr(char *psz)
{ // ECX = psz
  __asm {
    cmp     byte ptr[ecx], 0
    mov     eax, ecx
    je      short revEXIT
goOUT:
    add     ecx, 1
    cmp     byte ptr[ecx], 0
    jne     short goOUT
goREV:
    sub     ecx, 1
    cmp     eax, ecx
    jae     short revEXIT
    mov     dl, [eax]
    mov     dh, [ecx]
    mov     [eax], dh
    mov     [ecx], dl
    add     eax, 1
    jmp     short goREV
revEXIT:
    ret     0
  }
}

void __stdcall TesteReverse()
{
  char buf[28];
  strcpy(buf, "salut la foule");
  MessageBox(0, buf, "ok", 0);
}

#pragma comment(linker, "/entry:myWinMain")
__declspec(naked) void __stdcall myWinMain()
{
  __asm {
    call    TesteReverse
    push    0
    call    dword ptr ExitProcess
  }
}

ciao...
BruNews, MVP VC++

mardi 19 décembre 2006 à 20:39:08 | Re : Inversion de chaîne

BruNews

Administrateur CodeS-SourceS
OUPS, oublié d'appeler la routine:

void __stdcall TesteReverse()
{
  char buf[28];
  strcpy(buf, "salut la foule");
  bnRevStr(buf);
  MessageBox(0, buf, "ok", 0);
}


ciao...
BruNews, MVP VC++
mardi 19 décembre 2006 à 21:24:30 | Re : Inversion de chaîne

BruNews

Administrateur CodeS-SourceS
Réponse acceptée !

J'avais lu ta question comme d'hab un peu trop vite...
Tu voulais une inversion mais dans un autre buffer.
La routine retournera non pas la longueur qui risquerait fort de ne pas servir à grand chose mais plutot le terminateur null final, permettra un chainage direct si besoin et la longueur peut être sue illico aussi (fin - deb comme fait dans la routine):

__declspec(naked) char* __fastcall bnCpyRevStr(char *pdst, char *psrc)
{ // ECX = pdst, EDX = psrc
  __asm {
    mov     eax, ecx
    cmp     byte ptr[edx], 0
    je      short cpyrevEXIT
    mov     ecx, edx
    mov     [esp-4], ebx
goOUT:
    add     edx, 1
    cmp     byte ptr[edx], 0
    jne     short goOUT
    mov     ebx, edx
    sub     edx, ecx  ;// len = c - psrc
    sub     ebx, 1
fromSRC:
    mov     cl, [ebx]
    mov     [eax], cl
    sub     ebx, 1
    add     eax, 1
    sub     edx, 1
    jnz     short fromSRC
    mov     ebx, [esp-4]
cpyrevEXIT:
    mov     byte ptr[eax], 0
    ret     0
  }
}

void __stdcall TesteReverse()
{
  char buf[28];
  bnCpyRevStr(buf, "salut la foule");
  MessageBox(0, buf, "ok", 0);
}

#pragma comment(linker, "/entry:myWinMain")
__declspec(naked) void __stdcall myWinMain()
{
  __asm {
    call    TesteReverse
    push    0
    call    dword ptr ExitProcess
  }
}


ciao...
BruNews, MVP VC++

mardi 19 décembre 2006 à 21:29:44 | Re : Inversion de chaîne

Bidou

Administrateur CodeS-SourceS
Merci bien Brunews...
A vrai dire, cette synthaxe ne m'est pas encore tout à fait familière, va falloir que je regarde en détail 




-Blog-


Cette discussion est classée dans : mov, xor, edx, ecx, ebx


Répondre à ce message

Sujets en rapport avec ce message

j'ai un prob avec mon buffer ; ya pas d'amuses gueules (masm32) [ par papiboff ] bj si je mets le buffer "somme " en dd avec charge eax et que j'ajoute deux 'dec ebx ' , ben , marche pas correctement ; (pêrqué ???? = en french) sv Aligner des données pour le SSE [ par epineurien ] Bonjour à tous !J'ai un petit problème avec du code dont je mesure la vitesse: suivant la compilation, la vitesse varie du simple au double .J'expliqu nombre premier en nasm [ par YAWLY ] MED.MERZOUG salut tout le monde vous pouvez m'aider si j le compile sa affiche chaque fois le nbr est non premeir > le code est : Section .date ch aide pour code [ par marooh ] Bonjour, j'ai un code assembleur qui permet de trouver le maximum d'un tableau.En le compilant, la premiere phase passe avec succès mais en créant l fatal error LNK1190 [ par WildChild54 ] Bonjour à tous!Eh bien voilà, je voudrais créer un petit programme affichant l'heure (je sais il y en a déjà plusieurs qui en ont parlé ici) mais j'ai [ASM] Strcmp, prob evec la valeur de retour. [ par Ilsundal ] Bonjour a tous, j'ai réaliser la fonction strlen en ASM x86. tout fonctionne parfaitement sauf pour la valeur de retour, je souhaiterait qu'elle corre mon code ne marche pas [ par mohoguess ] Bonjour a tous,je suis débutant en asembleur, et j'ai écrit un code qui sert a additionner le chiffre 1 jusqu'à 999999 fois (mon code ne sert à rien j un énorme travail de votre part [ par mana ] bonjour, voici un programme écrit en c++ (il permet de passer d'une image en couleur 24bits(ARGB) a une image en 256 niveaux de gris(toujours sur 24bi Resultat de la vitesse des : Registre, instruction, calcul, et mémoire ! ! ! [ par rebixav ] Voici la liste que j'ai créé : asm : ( inc ) = 0.065 asm : ( and ) = 0.08 asm : ( or ) = 0.08 asm : ( xor ) = 0.08 asm : ( not ) Pb registre DL [ par AlexMAN ] Bonjour, J'ai un ptit pb avec le code qui suit, au nivo du mov dl, [ecx] ://Renvoie pointeur sur fin de chaine (permet d'eviter l'utilisation de strca


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,671 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales