Ayuda con funcion "Split"

Iniciado por Vaagish, 26 Marzo 2013, 23:09 PM

0 Miembros y 1 Visitante están viendo este tema.

MCKSys Argentina

Cita de: Binary_Death en 30 Marzo 2013, 04:48 AM
Ahora, si quieres hacer un split como el de VB (delimitador de más de un carácter), la cosa se complica. Lo difícil en ese caso es el algoritmo a usar, y hay que pensarlo bien para que sea óptimo.

Siempre puedes tracear el runtime de VB y ver qué hace... :)

Por supuesto, hay que tener en cuenta que VB usa UNICODE internamente.
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


Vaagish

Bueno,, gracias a la ayuda de ustedes, logre hacer funcionar el Split.. Les voy a dejar aca el codigo que me dio resultado.. Ya se que se puede mejorar montones, y lo pongo aca, justamente para que si alguien quiere lo corrija.. me serviria mucho.
No se olviden que yo no se practicamente nada de ASM, pero hacer que funcione fue bastante para mi jeje ;)

.386
.model flat, stdcall
option casemap:none

include Includes.inc

.data

Mensaje db "Mens|ajes",0
Titulo db "Resultado",0

.data?

Dato1 db 50 dup (?)
Dato2 db 50 dup (?)

.code

Inicio:

invoke Split, addr Mensaje
ret
invoke ExitProcess, 0


Split proc String:DWORD
   
    mov ecx, -1
mov ebx, -1
   
    Repite:
   
        inc ecx
        mov al, byte ptr ds:[Mensaje+ecx]
cmp al, '|'
je Salta
mov [Dato1+ecx], al
jmp Repite

Salta:

inc ecx
inc ebx
cmp byte ptr ds:[Mensaje+ecx],0
        je Salir
       
        mov al, byte ptr ds:[Mensaje+ecx]
        mov [Dato2+ebx], al
jmp Salta

Salir:
invoke MessageBox, NULL, addr Dato1, addr Titulo, MB_OK
invoke MessageBox, NULL, addr Dato2, addr Titulo, MB_OK

ret

Split endp

end Inicio


Ya se que la funcion tiene un parametro que no uso, pero en el programa que estoy haciendo si lo voy a precisar.. Aparte no se controlan algunos errores, como que si el string comienza con "|" o si no tiene ningun "|". Pero yo se que cadena deberia recibir.. y siempre es un string separado en 2 por un caracter "|". Asi que, sabiendo eso.. si la cadena llega completa.. no deberia dar errores.. ;)

cpu2

#22
A ver si esto te ayuda.

Código (asm) [Seleccionar]
.section .data

data: .ascii "ab|cdefg"

.section .text
.globl _start

_start:

movl $data, %edi
pushq %rax
movq %rsp, %rbx

_C.0:

incb %dl
scasb
jne _C.0
subl %edx, %edi
decb %dl
movb %dl, %r8b
pushq %rdi
popq %rsi

_C.1:

lodsb
cmpb $0x7c, %al
je _C.3
movb %al, (%rbx)

_C.2:

incb %bl
decb %dl
jnz _C.1
subb %r8b, %bl

pushq $0x1
popq %rdi
pushq %rbx
popq %rsi
movb %r8b, %dl
movb $0x4, %al
syscall

movb $0x1, %al
syscall

_C.3:

movb $0x0a, (%rbx)
jmp _C.2


Un saludo.

cpu2

Revivo el tema para mostrar el siguiente código, apenas 31 bytes, se podría mejorar para que eliminara más de un carácter.

Código (asm) [Seleccionar]
_split:

xorl %edx, %edx

_C.1:

incl %edx
scasb
jne _C.1

_C.2:

subl %edx, %edi
decl %edx
pushl %edx
movl %edi, %esi

_C.3:

lodsb
cmpb $0x7c, %al
je _C.4
stosb
jmp _C.5

_C.4:

movb $0x00, (%edi)
incl %edi

_C.5:

decl %edx
jnz _C.3
popl %ebx
subl %ebx, %edi
retl


Cargar la dirección en edi y la función te retorna un puntero en el mismo edi.

Un saludo.

mr.blood


mov eax, 'b'

mov edi, cadena

bucle:
scasb
jne bucle

mov byte[edi-1], 0
mov eax, edi
sub eax, cadena


No sé si eso te puede valer pero ocupa 27bytes. Lo quCreo que puede hacerse aún más cortoe hace es reemplazar el caracter por el el caracter nulo y devuelve el eax la posición donde comienza la segunda cadena.

Sa1uDoS