SDCC y ASM

Programando el Amstrad en BASIC, C, etc.
pacomix
Forum Addict
Forum Addict
Mensajes: 459
Registrado: Dom 11 Nov , 2012 8:05 pm

SDCC y ASM

Mensajepor pacomix » Lun 14 Mar , 2016 2:16 pm

¡Buenas!

Después de actualizar a la última versión de sdcc (3.5.0) me encuentro conque casi todo me ha dejado de funcionar.

Supongo que al tener el parámetro --oldralloc roto hay que hacer cambios en el inline assembler de funciones de C con parámetros y en las rutinas de ensamblador puro que reciben parámetros. ¿Sabe alguien con certeza cuáles son? Hay funciones que parece ser que no me dan problemas accediendo a los parámetros a través de IX pero otras que no.

Compilo con --fno-omit-frame-pointer

¡Ayuda!

Avatar de Usuario
ronaldo
Forum Addict
Forum Addict
Mensajes: 358
Registrado: Sab 14 Sep , 2013 9:31 pm
Ubicación: Alicante
Contactar:

Re: SDCC y ASM

Mensajepor ronaldo » Lun 14 Mar , 2016 2:40 pm

Hola pacomix,

Hace unos meses publicamos algo por aquí al respecto (no recuerdo donde está). Tuve una conversación con los desarrolladores de SDCC y nos dijeron claramente que no usemos --fomit-frame-pointer porque tiene bugs y está deprecated desde hace tiempo (no van a corregirse los bugs). Lo mismo para --old-ralloc, que seguramente ya habrán dejado de soportarlo. Es más, todo surgió porque hice unas comparativas en las que ambos parámetros se observa que afectan muy negativamente al rendimiento y al espacio ocupado por el código generado.

Las recomendaciones son las siguientes:
  • Si una función utiliza IX o IY, salvarlos siempre y restaurarlos. De lo contrario, se pueden producir efectos laterales difíciles de identificar y depurar.
  • Utilizar los nuevos modos que incorpora SDCC para obtener parámetros, adoptados de Z88DK: __z88dk_callee y __z88dk_fastcall.
  • Con __z88dk_callee, se pueden obtener los parámetros de la pila usando POP y hacer push únicamente de la dirección de retorno.
  • __z88dk_fastcall pasa parámetros de 8 bits en L, de 16 bits en HL y de 32 bits en DE:HL (esto último no lo he comprobado, pero es fácil de probar)
  • No utilices SDCC 3.5.0. Bájate la 3.5.5. Hay un bug en la SDCC 3.5.0. con optimizaciones de recursión de cola que afecta a las convenciones de llamada __z88dk.
Si quieres ver código de ejemplo, en github está todo el código de CPCtelera y el binding para llamadas desde C está por separado en casi todas las funciones, por lo que es fácil de ver. Aquí te dejo algunos enlaces: Espero que te sea de utilidad :)

pacomix
Forum Addict
Forum Addict
Mensajes: 459
Registrado: Dom 11 Nov , 2012 8:05 pm

Re: SDCC y ASM

Mensajepor pacomix » Lun 14 Mar , 2016 11:52 pm

¡Muchas gracias! Tendré que repasar el inline assembler de todas mis funciones de C. Funcionan muchas cosas pero otras no. Sorprendentemente las funciones de assembler puro que uso de la cpcrslib y las rutinas de acceso a disco que escribí en asm puro me funcionan sin problemas... eso sin siquiera restaurar registros que modifico. Hablo desde la ignorancia... seguramente esto sea así para funciones escritas en ensamblador directamente (ficheros .s).
Os iré contando!

Avatar de Usuario
ronaldo
Forum Addict
Forum Addict
Mensajes: 358
Registrado: Sab 14 Sep , 2013 9:31 pm
Ubicación: Alicante
Contactar:

Re: SDCC y ASM

Mensajepor ronaldo » Mar 15 Mar , 2016 2:07 pm

Eso que dices es lógico. Tienes que tener en cuenta que SDCC genera automáticamente código para recoger los parámetros de las funciones definidas en C. Si quieres incluir una función completa, programada con ASM inline, deberías declararla como __naked. Un ejemplo:

Código: Seleccionar todo

void mifuncion(int a, int b) __naked __z88dk_callee {
__asm
pop af ;; Dirección de retorno
pop hl ;; HL = parámetro A
pop de ;; DE = parámetro B
push af ;; Dejamos la dirección de retorno en la pila otra vez

;;; Aquí el código de la función

ret ;; Retorno
__endasm;
}
Al declarar una función como __naked, SDCC no genera ningún código para la recogida de parámetros, dejándonos a nosotros todo el control, exactamente igual que si hubieramos definido la función en ensamblador completo (en un .s, por ejemplo).

Una cosa muy importante: mucho código de versiones anteriores de SDCC modifica los registros IX e IY sin salvarlos. Este tipo de modificación genera efectos laterales que pueden no ser perceptibles dependiendo de cómo programes en C. Aparentemente, las funciones van, pero en realidad tienen un problema grave que hace que el programa falle conforme continúas el desarrollo. He visto a muchos programadores frustrarse y culpar a SDCC de tener bugs, siendo en muchos casos un efecto lateral de haber modificado IX e IY. SDCC utiliza estos registros para apuntar a la pila y obtener/modificar las variables locales de las funciones. SDCC asume que no los vas a modificar. Si lo haces, los valores de las variables locales pueden cambiar aleatoriamente al volver de las funciones que hagan esto.

Por tanto, si tienes código que obtiene los parámetros de la pila usando IX o funciones que lo modifican, mejor revísalas y cámbia el código por algo como el ejemplo. Además, con __z88dk_callee y push/pops el código es más compacto y rápido que usando IX.

pacomix
Forum Addict
Forum Addict
Mensajes: 459
Registrado: Dom 11 Nov , 2012 8:05 pm

Re: SDCC y ASM

Mensajepor pacomix » Mié 16 Mar , 2016 12:04 am

Muchas gracias Ronaldo por tu aportación. ¡N¡ google oiga!
Seguramente tengo por ahí una función que modifica o hace uso de IX y no lo restauro al final. Por cierto vaya jugada lo de la dirección de retorno; ya podrían dejarla como último parámetro y así se ahorra el pop af push af...
A ver si saco algo de tiempo a final de semana para dejar la update del cpc bros a la 3.5.5 listo.
¡Saludos!

corpiano
Me voy lanzando
Me voy lanzando
Mensajes: 88
Registrado: Dom 26 Oct , 2014 10:38 am

Re: SDCC y ASM

Mensajepor corpiano » Dom 07 Jul , 2019 11:17 am

Durante la compilación de la función propuesta, SDCC indica el siguiente warning respecto a los parámetros a y b: "unreferenced function argument". Entiendo que no detecta el uso de los mismos dentro del código ASM. ¿Hay alguna forma de que no salgan estos avisos?

Avatar de Usuario
ronaldo
Forum Addict
Forum Addict
Mensajes: 358
Registrado: Sab 14 Sep , 2013 9:31 pm
Ubicación: Alicante
Contactar:

Re: SDCC y ASM

Mensajepor ronaldo » Dom 07 Jul , 2019 12:04 pm

No lo detecta porque no puede detectarlo. En el código ensamblador Z80 no hay forma de hacer referencia a las variables de C. Estás usando la pila, que no es exactamente lo mismo que usar las variables, así que no puede detectarlo.

Personalmente, cuando se va a introducir ensamblador en un programa para Amstrad con SDCC, recomiendo crear las funciones en ficheros aparte, que sean sólo ensamblador. Después en C se puede declarar la cabecera de la función y usarse, que el linker ya hará su trabajo. Es mucho mejor, ya que el código inline en SDCC es sucio y no es igual de funcional que el código directo en ensamblador. Mejor esta vía, que la de andar sorteando al compilador. Además, si usas CPCtelera, basta con que crees ficheros con extensión .s en tu carpeta src/ y automáticamente serán ensamblados al compilar el programa con make.

De todas formas, si quieres eliminar el warning, hay una forma fácil de hacerlo: usando la variable en una expresión vacía (sin asignación). Aquí tienes un ejemplo:

Código: Seleccionar todo

void mifuncion(int a, int b) __naked __z88dk_callee {

a; // Expresión vacía que usa a sin hacer nada
b; // Lo mismo para b

__asm
pop af
pop bc
pop de
push af
;;
;; Más cosas que hacer aquí
;;
ret
__endasm;
}
C permite crear expresiones sin asignación, lo que es como decirle que haga una operación sin guardar el resultado. La gracia es que eso no genera ningún código pero, a efectos del compilador, ya cuenta como que has hecho uso de la variable. Con esto, los warnings desaparecen.

corpiano
Me voy lanzando
Me voy lanzando
Mensajes: 88
Registrado: Dom 26 Oct , 2014 10:38 am

Re: SDCC y ASM

Mensajepor corpiano » Dom 07 Jul , 2019 12:29 pm

Olé!
Solucionado. Gracias por la respuesta. Ambas opciones me parecen buenas soluciones para este caso.


¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro


La Comunidad Española
ESP Soft, juegos para tu CPC Foro de Amstrad CPC Todos los juegos para CPC en un CD Web dedicada al Amstrad CPC (utilidades) Información útil para el CPC (talleres) Selección de juegos de Amstrad CPC Mundo CPC Pree Play then any Key CPC Basic