Autor
|
Tema: Cadenas en FASM (Leído 3,804 veces)
|
Yuki
Desconectado
Mensajes: 80
El error es una muestra de la incompetencia.
|
Hola, estoy desarrollando un compilador en Basic 6.0 y hasta ahora he logrado superar muchos obstaculos (procesamiento y traducción de ecuaciones matematicas + funciones a ensamblador, adición de APIS y otras cosas) pero tengo un problema con las cadenas. Para que se hagan una idea con lo que estoy tratando les doy el siguiente código de ejemplo de mi compilador. API MessageBox(Opcional hWnd:Entero,Texto:Cadena = "Hola soy una cadenita",Título:Cadena = "Soy un sexual título",Opcional Bandera:Entero = 48):Entero, "User32.dll" "MessageBoxA"
Var Cadenita:Cadena Var OtroParametro:Entero Var Título:Cadena Var Cuarto:Entero
Cadenita = "Soy una vulgar cadena" Título = "mnmnqmnqmnqm" Cuarto = 48
MessageBox(0,Cadenita,Título,Cuarto) El problema esta al tratar de rellenar la variable "Cadenita" con "Soy una vulgar cadena". Ya que al visualizar el MessageBox amarece "Soy un0" como texto. El código ensamblador generado es el siguiente. ; Código generado en Fractor! include 'C:\Users\DarkBlue\Desktop\Fractor\Macros.inc' format PE GUI 4.0 .datos TmpStr0 db "Hola soy una cadenita",0 TmpStr1 db "Soy un sexual título",0 cadenita db ? otroparametro dd ? título db ? cuarto dd ? TmpStr2 db "Soy una vulgar cadena",0 TmpStr3 db "mnmnqmnqmnqm",0 .código inicio: push eax ; Preservamos EAX. push TmpStr2 push cadenita ccall [strcat] add esp,8 pop eax ; Restauramos EAX push eax ; Preservamos EAX. push TmpStr3 push título ccall [strcat] ; POSIBLE ERROR. add esp,8 pop eax ; Restauramos EAX push eax ; Preservamos EAX. push TmpStr2 ; Empujamos el valor de TmpStr2. push TmpStr3 ; Empujamos el valor de TmpStr3. mov eax,48 ; Fin del calculo. mov [cuarto],eax ; Movemos a la variable el valor de EAX. pop eax ; Restauramos EAX. push eax ; Preservamos EAX. push [cuarto] ; Empujamos el valor de cuarto. push título ; Empujamos el valor de título. push cadenita ; Empujamos el valor de cadenita. push 0 call [MessageBox] pop eax ; Restauramos EAX. push 0 call [ExitProcess] entry inicio ; Procedimientos declarados. ; Fin de los procedimientos declarados.
.importar ; APIS declaradas. library \ Kernel32,'Kernel32.dll',\ msvcrt,'msvcrt.dll',\ User32,'User32.dll' import \ Kernel32,ExitProcess,'ExitProcess' import \ msvcrt,strcat,'strcat' import \ User32,MessageBox,'MessageBoxA' ; Fin APIS. Como se puede notar, para asignarle a Cadenita el texto "Soy una vulgar cadena" utilizo strcat ya que yo asumí que strcat copia el segundo parametro en el primero, ¿que estoy haciendo mal?
|
|
|
En línea
|
|
|
|
fary
|
Tienes que crear un buffer con malloc, LocalAlloc o similar y ahí concatenar las cadenas.
Saludos.
|
|
|
En línea
|
Un byte a la izquierda.
|
|
|
Yuki
Desconectado
Mensajes: 80
El error es una muestra de la incompetencia.
|
¿Me podrias dar un pequeño ejemplo? no puedo visualizar el código sin usar registros. .datos cadenita dd ? TmpStr1 db "Soy una cadenita de longitud 50 o que se yo." TmpLng = $ - TmpStr1 .código inicio: ccall [malloc],TmpLng add esp,4 ; Liberamos el stack. mov [cadenita],eax push TmpStr1 push [cadenita] ccall [strcat] add esp,8 ; Liberamos el stack. ; [cadenita] = Puntero A "Soy una cadenita de longitud 50 o que se yo."????????
entry inicio
Disculpen por el doble comentario, solucione mi problema con un procedimiento propio que hice, lo pongo acá por si alguien tiene el mismo problema que yo y requiere una solución, ademas no me gusta dejar mis posts sin el "resuelto". Utilizo el siguiente procedimiento en mi compilador para concatenar cadenas. Acepta 2 parametros (punteros a cadenas) y retorna un puntero a la cadena concatenada en EAX. proc concatenar uses ecx,Fuente2,Fuente1 ; Retorna en EAX mov EDI, [Fuente2] push EDI call [strlen] Add ESP, 4 mov ESI, EAX mov EDI, [Fuente1] push EDI call [strlen] add ESP, 4 add ESI,EAX ; ecx = len(Fuente2) + len(Fuente1) push ESI call [malloc] add ESP, 4 push EDI push EAX call [strcpy] add ESP, 8 mov EDI, [Fuente2] push EDI push EAX call [strcat] add ESP, 8 ret endp Me hubiera gustado que fuera mas chica, pero como esta escrita en ensamblador supongo que de todas maneras debe ser muy rapida.
|
|
« Última modificación: 3 Mayo 2016, 22:02 pm por Eternal Idol »
|
En línea
|
|
|
|
fary
|
Hola Yuki, Es combeniente que el buffer sea de tamaño len(Fuente2) + len(Fuente1) + 1 para el byte nulo de final de cadena. Usa mejor invoke para llamar a las API, queda un código mas corto y mas limpio y viene a ser lo mismo... para las funciones de las librerias de C usa cinvoke, que te arregla la pila. proc concatenar uses ecx,Fuente2,Fuente1 ; Retorna en EAX cinvoke strlen, [Fuente2] mov ESI, EAX cinvoke strlen, [Fuente1 add ESI,EAX ; ecx = len(Fuente2) + len(Fuente1) cinvoke malloc, esi cinvoke strcpy, eax, edi cinvoke strcat, eax, [Fuente2] ret endp
Ademas el buffer que crees con malloc limpialo con ZeroMemory o similares para que no contenga caracteres extraños, llegado el momento puedes tener lios con eso. saludos y suerte con tu proyecto.
|
|
« Última modificación: 6 Mayo 2016, 10:35 am por fary »
|
En línea
|
Un byte a la izquierda.
|
|
|
|
|