Como respuesta a una pregunta de un lector del blog, voy a añadir esta entrada.
Si no me equivoco al interpretar su pregunta, el problema que se quiere es poder concatenar dos o más cadenas en una destino.
Para hacerlo de forma elegante, voy a crear una macro.
Esta macro va a concatenar las cadenas mediante llamadas consecutivas a la función strcat.
La ventaja de la macro es que podemos añadir la llamada adicional solo si se pasa como parámetro el puntero a una nueva cadena, de forma que podemos dejar definida la función para un número indeterminado de cadenas. En este caso lo haré de 2 hasta 7.
Para ello vamos a usar la función strcat para unir las dos primeras cadenas a la tercera. Luego, cuando exista el siguiente parámetro, tomaremos la dirección del destino, calcularemos su longitud y la sumaremos a su dirección de puntero. Así crearemos un puntero al final de la cadena destino. Esto lo haré en SI, para poder direccionarlo como [si] y pasarlo como parámetro a la macro strcpy. Así con esa nueva dirección puedo llamar de nuevo a strcpy y acoplar la cadena a la que ya existía.
También lo podía haber hecho mediante sucesivas llamadas a strcat destino,destino,fuente?, pero de esta segunda forma perdería tiempo en copiar muchas veces la misma cadena.
Add_str destino,fuente1,fuente2 ;copia dos cadenas en destino
Add_str destino,fuente1,fuente2,fuente3 ;copia tres cadenas en destino
etc
Add_Str macro destino,fuente1,fuente2,fuente3,fuente4,fuente5,fuente6,fuente7
strcat destino,fuente1,fuente2 ;primera llamada con el mínimo permitido
push si
ifnb <fuente3>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente3 ;primera llamada
else
ifnb <fuente4>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente4 ;segunda llamada
else
ifnb <fuente5>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente5 ;tercera llamada
else
ifnb <fuente6>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente6 ;cuarta llamada
else
ifnb <fuente7>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente7 ;quinta llamada
endif
endif
enidf
endif
endif
pop si
endm
Realmente lo he creado como una nueva función, pero podría haber ampliado simplemente las que ya tenía publicadas en la cabecera string.mac.
Por ejemplo, podríamos haberla llamado strcat directamente, pues en su modo más corto llama directamente a esa función.
Hay que tener en cuenta que el enlace está enviado a una versión inicial de las macros. En ella no usábamos el comando USE del TASM 2.0.
Para pasar al modo de programación actual, en el que si usamos ya el comando USE del TASM2.0 habrá que aplicar la conversión indicada en la entrada del blog "pasamos a integrar TASM2.0"
Con esta salvedad, colocaré ahora una versión actualizada de strcat y otra de strcpy, que podrán hacer la misma función que la anterior.
Si en vez de crear una función nueva ampliamos strcat para que tenga polimorfismo, quedará:
strcat macro destino,fuente1,fuente2,fuente3,fuente4,fuente5,fuente6,fuente7
ifndef _strcatextrn _strcat:near
endif
lea ax,destino
push ax
lea ax,fuente1
push ax
lea ax,fuente2
push ax
call _strcat ;primera llamada. Sumamos fuente1, y fuente2 en destino
; a partir de ahí todo es igual
push si
ifnb <fuente3>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente3 ;primera llamada
else
ifnb <fuente4>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente4 ;segunda llamada
else
ifnb <fuente5>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente5 ;tercera llamada
else
ifnb <fuente6>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente6 ;cuarta llamada
else
ifnb <fuente7>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente7 ;quinta llamada
endif
endif
enidf
endif
endif
pop si
endm
Pero claro, igualmente podríamos pensar con strcpy. Dado que strcat no es mas que dos llamadas a strcpy, podríamos construir strcat mediante strcpy, y si hacemos polimorfismo, nos bastará con strcpy, para realizar todas las posibilidades.
¿Que Sacrificamos?
Sacrificamos código. Si usamos macro, cada llamada consumirá más código, que si usamos la llamada a la función strcat. Es por eso que cree strcat. Sin embargo, Add_Str si interesa hacerlo en macro, ya que concatenar más de una cadena a la vez es más raro, y tener una función que no se usa, también puede aumentar el código, al incorporar librerías innecesarias.
De todas formas vamos a ver como crear un strcpy,que sirva para todo.
strcpy macro destino,fuente1,fuente2,fuente3,fuente4,fuente5,fuente6,fuente7
ifndef _strcpy
extrn _strcpy:near
endif
lea ax,destino
push ax
lea ax,fuente1 ;copia inicial
push ax
call _strcpy
; a partir de ahí todo es igual , pero con una llamada más
push si
ifnb <fuente2>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente2 ;primera llamada
else
ifnb <fuente3>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente3 ;segunda llamada
else
ifnb <fuente4>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente4 ;tercera llamada
else
ifnb <fuente5>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente5 ;cuarta llamada
else
ifnb <fuente6>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente6 ;quinta llamada
else
ifnb <fuente7>
strlen destino
lea si,destino
add si,ax
strcpy [si],fuente7 ;quinta llamada
endif
endif
endif
enidf
endif
endif
pop si
endm
Como se ve, hará lo mismo, y podrá usarse tanto para copiar una cadena, como para acoplar de 2 a 7 cadenas.
Pero claro, para sumar dos cadenas perderemos más espacio si lo usamos varias veces, frente a usar strcat.
No hay comentarios:
Publicar un comentario
Si tienes algún comentario, duda o sugerencia, o si quieres aportar algún código creado a partir de las librerías expuestas aquí, por favor, indícamelo.