Código: Seleccionar todo

include 'win32ax.inc'
; Comparar cadenas by linkgl
.data
  cadena1 db 'Linkgl',0
  cadena2 db 'indetectables',0

.code
  comparar:
    MOV ECX,sizeof cadena1
    LEA ESI,[cadena1]
    LEA EDI,[cadena2]
    CLD
    REPE CMPSB
    JE iguales
    JMP noiguales
  .end comparar

  iguales:
    invoke MessageBoxA,0,"Las cadenas son iguales","Ejercicios",MB_OK
    invoke ExitProcess,0
  noiguales:
    invoke MessageBoxA,0,"Las cadena son diferentes","Ejercicios",MB_OK
    invoke ExitProcess,0
Recién empiezo a trabajar con cadenas, te dice si son iguales o diferentes, voy a hacer una funcion "len" o "strlen" aver que tal me va
//mHmm..
Yo estoy empezando con ASM xDD Así que me va a servir de mucho.
Muchas gracias.

Se podría hacer lo siguiente para optimizar el código:

Código: Seleccionar todo

include 'win32ax.inc'
; Comparar cadenas by linkgl
.data
  cadena1 db 'Linkgl',0
  cadena2 db 'indetectables',0

.code
  comparar:
    LEA SI,[cadena1]
    LEA DI,[cadena2]
    CMP SI,DI
    JE iguales
    invoke MessageBoxA,0,"Las cadena son diferentes","Ejercicios",MB_OK
    invoke ExitProcess,0
  .end comparar

  iguales:
    invoke MessageBoxA,0,"Las cadenas son iguales","Ejercicios",MB_OK
    invoke ExitProcess,0
Saludos!
github.com/Slek-Z
lo compile con cadenas iguales, pero en ambos codes me tira que son diferentes

Código: Seleccionar todo

include 'win32ax.inc'
; Comparar cadenas by linkgl
.data
  cadena1 db 'Linkgl',0
  cadena2 db 'Linkgl',0

.code
  comparar:
    LEA SI,[cadena1]
    LEA DI,[cadena2]
    CMP SI,DI
    JE iguales
    invoke MessageBoxA,0,"Las cadena son diferentes","Ejercicios",MB_OK
    invoke ExitProcess,0
  .end comparar

  iguales:
    invoke MessageBoxA,0,"Las cadenas son iguales","Ejercicios",MB_OK
    invoke ExitProcess,0        
Wow linkgl, también ASM? que capo mucha suerte bro, y buen trabajo

saludos!!
Soy un camaleón, en tu cama, leona ♪
por que esta mal, lo que el codigo esta haciendo es comparar las direcciones de cada cadena es decir siempre seran diferentes a menos que los ultimos 4 digitos de la direccion de las dos string sea igual es decir

0x00401000 == "String"
0x00411000 == "String2"

SI == 1000
DI == 1000

y dara como resultado que son iguales, de resto asi las cadenas sean identicas dara como resultado que son diferentes

por lo menos diria un MOV ESI,[Cadena1] donde moveria el valor hexadecimal de los 4 primeros caracteres y asi si comparar, bueno espero que se entienda y si estoy mal por favor disculpenme, no tengo nada con que probar en el momento, saludos
Imagen

Imagen
CronuX Tiene rason , el CMP no es como strcmp , en tu caso estas comparando los direcciones ejemplo 401000 y 401100
el cmp se puede usar para comparar byte word dword
puedes usar una Loop comparando los bytes
el codigo correcto =

Código: Seleccionar todo

.code
  comparar:
    mov ecx,sizeof cadena1 ; tamano del string , ecx es un contador
    mov ESI,offset cadena1 ; o LEA ESI,[cadena1]
    mov EDI,offset cadena2 ; o LEA EDI,[cadena2]
loop1:                             ; lazo
push edi
    mov dl,byte ptr edi
    CMP byte ptr ESI,dl
    JNE noiguales
    inc esi
pop edi
    inc edi
 LOOPE loop1                      ; if ( ecx !=0 ){ ecx = ecx -1; jmp loop1;} 
    JE iguales
  .end comparar


si quieres aprender esto el de loop mira [Enlace externo eliminado para invitados] slide 62
saludos

Mostrar/Ocultar

Ya veo, creí que cmp también servía para comparar cadenas, sí entiendo el código que me pasas m4rty perfectamente, por ahí encontré un source también que trabaja con cadenas y para "compararlas hace"

repe cmpsb

Alguien sabe para que sirve este comando?

Gracias por corregirme voy aprendiendo este leguaje que me es algo diferente a los demás de alto nivel x) .!
Wow linkgl, también ASM? que capo mucha suerte bro, y buen trabajo

saludos!!
Ahí vamos poco a poquito, andaba manejando puros valores enteros pero ya me voy metiendo a las cadenas y eso para hacer algo mas útil
//mHmm..
encontré un source también que trabaja con cadenas y para "compararlas hace"

repe cmpsb

Alguien sabe para que sirve este comando?
Aqui te dejo un pdf, en la ultima parte puedes ver algunas funciones para el manejo de cadenas en asm

[Enlace externo eliminado para invitados]

Saludos
Imagen
repe cmpsb
segnifiqua while rep = repeat el e signifiqua while(Z=1) el Zero Flag Z que solo es de un byte y se pone uno cuando
por ejemplo tenemos
mov al,1
cmp al,1
el cmp hace esto 1-1=0 if (result ==0) then Z=1; else Z=0;

otro ejemplo si tenemos
.data
cadena1 db 'Linkgl',0
cadena2 db 'Linkgl',0
.code
mov esi , offset cadena1
mov edi , offset cadena2
cld
REPE CMPSB
JE iguales
jmp noiguales

que hace REPE , el REPE coje dos 4 parametros o prerequisitos
el esi y edi que tiene el direccion de la cadenas
el ecx que le dice quanto bytes hay que comparar
y el D FLAG , si el D=0 compara de menos asta mas si D=1 compara de mas asta menos
o puedes decir que el D es la direccion del CMP , para ponerlo D=1 usas STD y D=0 usas CLD

el REP = repeat , y el E signifiqua = REP ;while(ecx!=0)cmp && ecx--;
el CMPSB ,CMP = CMP , el SB = byte , SW = word , SD =DWORD

el resultado del REPE CMPSB , si el Z=1 signifiqua que son iguales
y si Z=0 signifiqua nose jaja (no son iguales :P)

espero que fue entendido , alguna duda dicen

Mostrar/Ocultar

m4rtyr escribió:repe cmpsb
segnifiqua while rep = repeat el e signifiqua while(Z=1) el Zero Flag Z que solo es de un byte y se pone uno cuando
por ejemplo tenemos
mov al,1
cmp al,1
el cmp hace esto 1-1=0 if (result ==0) then Z=1; else Z=0;

otro ejemplo si tenemos
.data
cadena1 db 'Linkgl',0
cadena2 db 'Linkgl',0
.code
mov esi , offset cadena1
mov edi , offset cadena2
cld
REPE CMPSB
JE iguales
jmp noiguales

que hace REPE , el REPE coje dos 4 parametros o prerequisitos
el esi y edi que tiene el direccion de la cadenas
el ecx que le dice quanto bytes hay que comparar
y el D FLAG , si el D=0 compara de menos asta mas si D=1 compara de mas asta menos
o puedes decir que el D es la direccion del CMP , para ponerlo D=1 usas STD y D=0 usas CLD

el REP = repeat , y el E signifiqua = REP ;while(ecx!=0)cmp && ecx--;
el CMPSB ,CMP = CMP , el SB = byte , SW = word , SD =DWORD

el resultado del REPE CMPS , si el Z=1 signifiqua que son iguales
y si Z=0 signifiqua nose jaja (no son iguales :P)

espero que fue entendido , alguna duda dicen
Sí había leído que cmp resta dos valores y activa un flag(un byte) dependiendo el resultado pero en los manuales que leí no venía esa parte de que podia hacer CMPSD o CMPSW, como dicen cada día se aprende algo nuevo, muy buena la explicación que haces m4rty te das a entender perfectamente, pues nada mas que decir mas que pegarle al estudio de ASM, es bueno saber un poco de todo Gracias

-->Edito
@3mp3z@ndo: Gracias por el pdf esta bueno ya estoy mirando la parte de cadenas esta bien explicada

@M4rty: Checando el primer código que pusiste al incrementar SI y DI, no estas incrementando su valor total y no un byte para seguir en el loop?

Código: Seleccionar todo

    inc esi
    inc edi
Porque segun veo pues haces un bucle para ir comparando byte por byte y al primero que sea diferente mandas el salto a "noiguales", y veo que almacenas en DL el byte de DI y luego lo comparas con el de SI, pero alfinal incrementas SI y DI haciendo no le estas aumentando 1 a los valores totales y no al byte? Claro tomando en cuenta que estoy usando "lea EDI,[cadena]" para almacenarla igual con ESI
No se si me entendiste, solo me surgió esa duda
//mHmm..
ah si tengo un error el dl del edi se esta aumentando con el string y el inc edi
usamos push y pop para conserver el edi original (direccion de la cadena)

codigo correcto

Código: Seleccionar todo

.code
  comparar:
    mov ecx,sizeof cadena1 ; tamano del string , ecx es un contador
    mov ESI,offset cadena1 ; o LEA ESI,[cadena1]
    mov EDI,offset cadena2 ; o LEA EDI,[cadena2]
loop1:                             ; lazo
push edi
    mov dl,byte ptr edi
    CMP byte ptr ESI,dl
    JNE noiguales
    inc esi
pop edi
    inc edi
LOOPE loop1                      ; if ( ecx !=0 ){ ecx = ecx -1; jmp loop1;}
    JE iguales
  .end comparar
Porque segun veo pues haces un bucle para ir comparando byte por byte y al primero que sea diferente mandas el salto a "noiguales"
si

el inc esi y inc edi , icrementa la direccion de las cadenas por ejemplo si el direccion del esi original tenia 401000 "Linkgl", el inc esi resulta en 401001 "inkgl"

saludos

Mostrar/Ocultar

Bonita conversación hacía mucho que no tenía una así. Pues el código correcto para los que quieran comparar cadenas es el último que puso m4rty ya lo he testeado con lea y mov!

PD:
O bien pueden usar "COMPS" para comparar las cadenas ese sería el código correcto
//mHmm..
Marty dijo : codigo correcto

Código: Seleccionar todo

.code
  comparar:
    mov ecx,sizeof cadena1 ; tamano del string , ecx es un contador
    mov ESI,offset cadena1 ; o LEA ESI,[cadena1]
    mov EDI,offset cadena2 ; o LEA EDI,[cadena2]
loop1:                             ; lazo
push edi
    mov dl,byte ptr edi
    CMP byte ptr ESI,dl
    JNE noiguales
    inc esi
pop edi
    inc edi
LOOPE loop1                      ; if ( ecx !=0 ){ ecx = ecx -1; jmp loop1;}
    JE iguales
  .end comparar
Es bueno el codigo marty pero ... ninguna instrucción entre PUSH y POP modifica EDI, entonces no los necesita en este caso no es necesario el push/pop edi :

Código: Seleccionar todo

.code
  comparar:
    mov ecx,sizeof cadena1 ; tamano del string , ecx es un contador
    mov ESI,offset cadena1 ; o LEA ESI,[cadena1]
    mov EDI,offset cadena2 ; o LEA EDI,[cadena2]
    
    repe cmpsb          
    jz iguales           
  jmp noiguales        
    
  .end comparar
Bueno mas o menos para que lo entiendan !!

repe cmpsb : compara "esi" con "EDI", mientras que son iguales en la mayoría de "ecx" veces (es decir, termina si diferente o se "ecx" llega a cero)

jz iguales si "ecx" llega a cero, o registrador "zero" es activado (jz = jump if zero) si "ecx" es cero salta para "iguales"

jmp noiguales : o son diferentes

Saludos !
<Josh> y bueno hermano,tu hermana q me dijo q estaba cansada de tenerle el orto como la bandera de japon y bueno la pobre me quizo hacer un masaje prostatico nada mas pero era tanto su recelo y venganza acumulada q se esmero un poco mas de lo normal,pero bue,estuivo bien amorizado por la de dias horas años y lagrimas q echo la pobre de tanto culearla
ps1c0s1s escribió:Marty dijo : codigo correcto

Código: Seleccionar todo

.code
  comparar:
    mov ecx,sizeof cadena1 ; tamano del string , ecx es un contador
    mov ESI,offset cadena1 ; o LEA ESI,[cadena1]
    mov EDI,offset cadena2 ; o LEA EDI,[cadena2]
loop1:                             ; lazo
push edi
    mov dl,byte ptr edi
    CMP byte ptr ESI,dl
    JNE noiguales
    inc esi
pop edi
    inc edi
LOOPE loop1                      ; if ( ecx !=0 ){ ecx = ecx -1; jmp loop1;}
    JE iguales
  .end comparar
Es bueno el codigo marty pero ... ninguna instrucción entre PUSH y POP modifica EDI, entonces no los necesita en este caso no es necesario el push/pop edi
el push y pop si tienen funcion
si te das cuenta del mov dl,byte ptr edi
por ejemplo si tienes un codigo correcto como

.data
[offset=401000] cadena byte "psycosis"
mov edi,offset cadena ; esi=401000
loop1:
push edi ; stack=401000 , edi =401000
mov dl,byte ptr edi ; dl = 70 , edi=401070 <<la cadena se cambia
pop edi; edi =401000
inc edi ; edi =401001 <<conserva la cadena
loope loop1

codigo malo :
mov edi,offset cadena ; esi=401000
loop1:
mov dl,byte ptr edi ; dl = 70 , edi=401070
inc edi ; edi =401071 << esto es el error , el edi tiene el byte 70 que es el quaraqter "p" y estas aumentado el countador de la cadena , el edi correcto es 401001 "sycosis"
loope loop1

nota = el JE es JZ y JNE es JNZ , son lo mismo
espero que estoy entendido
saludos

Mostrar/Ocultar

Responder

Volver a “Otros lenguajes”