Z88DK: Ayuda con fastcall y callee, int, char...

Soporte técnico sobre los lanzamientos de MojonTwins y comentarios sobre los güegos. Ofrecemos soporte técnico con Fourspriter, te ayudamos con ZX Basic o Z88DK, te damos pistas some cómo saltarse un bicho y cosas así.

Moderador: na_th_an

Avatar de Usuario
D_Skywalk
Mensajes: 352
Registrado: Mar, 01 Oct 2013, 13:36

Z88DK: Ayuda con fastcall y callee, int, char...

Mensajepor D_Skywalk » Lun, 25 Nov 2013, 15:18

Estaba leyendo este documento:
http://www.z88dk.org/wiki/doku.php?id=optimization

Y sigo sin entender muy bien como funcionan fastcall y demás...

En C:
$this->bbcode_second_pass_code('', 'int suma(int a)
{
a += 2;
}


main()
{
suma(a);
b++;
}')

En ASM:
$this->bbcode_second_pass_code('', '._suma
pop bc
pop hl
push hl
push bc
inc hl
inc hl
pop de
pop bc
push hl
push de
ret



._main
ld hl,(_a)
push hl
call _suma
pop bc
ld hl,(_b)
inc hl
ld (_b),hl
dec hl
ret')

ASM + llamando a suma con FASTCALL:
$this->bbcode_second_pass_code('', '._suma
pop bc
pop hl
push hl
push bc
inc hl
inc hl
pop de
pop bc
push hl
push de
ret



._main
ld hl,(_a)
call _suma
ld hl,(_b)
inc hl
ld (_b),hl
dec hl
ret')

Veo que me estoy ahorrando en la llamada el PUSH HL, supongo que por que sólo va a usar un valor... pero se puede hacer lo mismo si usas dos chars como parámetros?
¿para que vale CALLEE? ¿QUE HACEN LOS POPs y PUSH iniciales intercambiar variable?
¿porque no puede hacer directamente inc hl inc hl, si ya está en HL el valor?

Luego he visto que cuando usas un char, tiene que usar mascaras para hacer las operaciones ... no le vendría bien a la churrera pasar algunas variables globales a int?
Y ya cuando usas una variable signed, se lía un pifostio XD

Si estas preguntas quedan fuera del foro, o preferís que se hagan en Speccy ... avisadme :)

Un saludo compas!
David Skywalker
Weblog: http://david.dantoine.org
antoniovillena
Mensajes: 494
Registrado: Jue, 24 Oct 2013, 15:52

Re: Z88DK: Ayuda con fastcall y callee, int, char...

Mensajepor antoniovillena » Lun, 25 Nov 2013, 15:49

A ver, los parámetros normalmente se pasan por pila, ten en cuenta que lo último que se mete en la pila es la dirección de retorno, la última instrucción que se ejecuta antes de entrar en la función es un call, y este call es el que mete (actúa como un push) la dirección de retorno en pila.

Como lo que has puesto es código en C, el compilador en teoría puede hacer lo que le de la gana. En principio hay 2 formas de acceder a los parámetros de la pila: o popeas los valores (luego lo pusheas para equilibrar la pila) directamente en registros, o usas el puntero HL y aplicas aritmética de punteros. El ejemplo que has puesto el compilador hace lo primero. De la otra forma sería:

$this->bbcode_second_pass_code('', '
ld hl, 2
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
inc de
inc de
ld (hl), d
dec hl
ld (hl), e
ret
')

Después tenemos el FASTCALL, que sólo se aplica sólo si la función tiene un parámetro (menor de 16 bits), y lo que se hace es emplear el registro HL en lugar de la pila, tanto para el parámetro de entrada como para el parámetro de salida. Esto se traduce en código más eficiente, el ejemplo de arriba sería:

$this->bbcode_second_pass_code('', '
inc hl
inc hl
ret
')

Por último tenemos los CALLEE, mediante el cual le indicamos a la función que el equilibrado de pila lo haremos dentro de la función (normalmente se hace fuera, después del call). A nivel de eficiencia es lo mismo, y no es recomendable porque el código en ensamblador de la función en más difícil de entender. La única ventaja que tiene es que si hay muchas llamadas a esa función, el tamaño del binario se reduce, puesto que en el caso de no usar CALLEE el código que equilibra la pila aparece N veces, mientras que si usamos CALLEE sólo aparece una vez (al final de la función).
antoniovillena
Mensajes: 494
Registrado: Jue, 24 Oct 2013, 15:52

Re: Z88DK: Ayuda con fastcall y callee, int, char...

Mensajepor antoniovillena » Lun, 25 Nov 2013, 15:54

Ten en cuenta que el compilador siempre es tonto, empleando el primer método (popeado de valores) sería más sencillo hacer ésto:

$this->bbcode_second_pass_code('', '
pop bc
pop hl
inc hl
inc hl
push hl
push bc
ret
')
antoniovillena
Mensajes: 494
Registrado: Jue, 24 Oct 2013, 15:52

Re: Z88DK: Ayuda con fastcall y callee, int, char...

Mensajepor antoniovillena » Lun, 25 Nov 2013, 16:23

$this->bbcode_second_pass_quote('', '
')¿para que vale CALLEE? ¿QUE HACEN LOS POPs y PUSH iniciales intercambiar variable?
¿porque no puede hacer directamente inc hl inc hl, si ya está en HL el valor?


La función que has puesto como ejemplo es un poco inútil, porque incrementa una variable local que no se retorna, si quieres prueba con esta:

$this->bbcode_second_pass_code('', '
int suma(int a)
{
retun a + 2;
}

main()
{
a= 3;
b= suma(a);
printf("%d", b);
}
')