División 16-bits / 8-bits sin signo

Programando el Amstrad en Ensamblador.
Reglas del Foro
Debido a que hay varios temas pidiendo ayuda para programar en ensamblador máquinas distintas al Amstrad CPC, con micro distinto al Z80 y que incluso dependen del sistema operativo, nos vemos en la necesidad de poner por escrito que estos posts son bienvenidos pero que no es el lugar adecuado ya que por estos lares nos dedicamos más al ensamblador del Z80, un microprocesador de 8 bits que tuvo su gran auge en ordenadores y consolas de los años 80.

De todas formas, esto no quita que alguien que sepa del asunto pueda postear alguna respuesta pero es más fácil encontrar foros dedicados a programar en ensamblador en Windows o MS-DOS que ayudarán más que nosotros:
http://www.lawebdelprogramador.com/news ... nsamblador
Avatar de Usuario
dinoneno
Megaforero
Megaforero
Mensajes: 298
Registrado: Mié 13 Sep , 2006 7:32 am
Ubicación: Nambroca

División 16-bits / 8-bits sin signo

Mensajepor dinoneno » Mié 25 Mar , 2009 8:14 am

Tengo un problemilla con la división en ensamblador. En la página http://baze.au.com/misc/z80bits.html y también en alguna otra he encontrado unos algoritmos para la multiplicación y división de números sin signo en ensamblador. Todos los algoritmos funcionan bien, excepto el de la división entre un valor de 16 bits y otro de 8 bits, que unas veces funciona y otras no, por lo que creo que le falta algún detalle para que funciona correctamente en todos los casos.

El código para la división es este:

Código: Seleccionar todo

org #A003
ld hl,10533
ld c,139
xor a
ld b,16
bucle:
add hl,hl
rla
cp c
jr c,$+4
sub c
inc l
djnz bucle
ld (#A000),hl
ld (#A002),a
ret
Para probarlo he escrito este programa en BASIC:

Código: Seleccionar todo

10 MEMORY &9FFF
20 CALL &A003
30 PRINT PEEK(&A000)+PEEK(&A001)*256:REM imprime cociente
40 PRINT PEEK(&A002):REM imprime resto
Lo que hago es pegar el código ensamblador en la ventana Assembler del WinAPE y lo ensamblo (Ctrl+F9). Después en el emulador lanzo el programa BASIC y me da los resultados.

Con los valores que hay en HL (dividendo) y C (divisor) del código ensamblador no funciona correctamente, pero con otros muchos sí (por ejemplo 1000 y 100). ¿Sabeis alguien qué le falta o sobra al código ensamblador para que siempre divida correctamente?

Avatar de Usuario
dinoneno
Megaforero
Megaforero
Mensajes: 298
Registrado: Mié 13 Sep , 2006 7:32 am
Ubicación: Nambroca

Re: División 16-bits / 8-bits sin signo

Mensajepor dinoneno » Jue 26 Mar , 2009 9:52 pm

Creo que ya tengo la solución, para quien tenga este mismo problema, aunque es complicado explicarla aquí sin extenderme mucho. Resulta que en el proceso se usa el registro A como subcociente, HL es el dividendo y al final el cociente y C el divisor. Parece ser que en algunas divisiones al meter el bit más significativo que sale del dividendo y meterlo en el subcociente (luego se compara si es mayor o igual al divisor) si el bit más significativo del subcociente es 1, se pierde al desplazarse a la izquierda. Es es debido a que el subcociente tiene 8 bits y el dividendo 16.

No sé si quedará muy claro (supongo que no), pero el caso es que para solucionarlo he utilizado el método de divisón de 16 bits/16 bits, con el byte algo del divisor igual a cero, y así el subcociente (que en este algoritmo es HL tiene la misma longitud que el dividendo y no se pierde nunca ese bit. Este algorimo de división de 16 bits/16 bits también se encuentra en la página que mencionaba en el primer comentario.

Avatar de Usuario
Artaburu
Trasteador
Trasteador
Mensajes: 8420
Registrado: Vie 07 Oct , 2005 6:18 pm
Ubicación: En tu pantalla

Re: División 16-bits / 8-bits sin signo

Mensajepor Artaburu » Jue 26 Mar , 2009 10:49 pm

Yo lo estuve mirando ayer por la mañana pero no veía nada... y no tenía energía para ponerme a entender el algoritmo. Eso sí, sospechaba de A :D Me alegra que lo hayas solucionado... y si puedes poner el código resultante bueno sería genial porque no he encontrado la división 16bits/8bits en ningún otro sitio.
Salu2,
Arta

Avatar de Usuario
dinoneno
Megaforero
Megaforero
Mensajes: 298
Registrado: Mié 13 Sep , 2006 7:32 am
Ubicación: Nambroca

Re: División 16-bits / 8-bits sin signo

Mensajepor dinoneno » Vie 27 Mar , 2009 8:06 am

Buena idea. Yo he dejado el código así para dividir un valor de 16 bits entre uno de 8 (ambos sin signo):

Código: Seleccionar todo

ld bc,10533 ; Dividendo
ld de,139 ; Divisor
ld hl,0
ld a,b ; Dividendo es AC en lugar de BC para optimizar código y liberar B como contador
ld b,16
sll c ; Esta instrucción es indocumentada, algunos ensambladores no la reconocen, se puede sustituir por defb #CB,#31
rla
adc hl,hl
sbc hl,de
jr nc,$+4
add hl,de
dec c
djnz $-11
; Cociente queda en AC, se puede hacer ld b,a para que quede en BC
; Resto queda en HL (realmente en L, ya que H siempre será cero)

Urusergi
Forum Addict
Forum Addict
Mensajes: 381
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: División 16-bits / 8-bits sin signo

Mensajepor Urusergi » Lun 12 Oct , 2020 10:17 pm

Super-reflote, creo yo justificado, dado que es interesante puntualizar que hay mas páginas con el mismo error (presumiblemente por el copy/paste)
La primera rutina que puso dinoneno en el hilo es la óptima, pero le falta algo para que funcione bien siempre (salvo /cero). La última rutina, sin embargo, tarda más en ejecutar y utiliza una instrucción no-documentada, que es mejor evitar.

Solo hay que añadir un JR:

Código: Seleccionar todo

org #A003
ld hl,10533
ld c,139
xor a
ld b,16

bucle: add hl,hl
rla
jr c,$+5
cp c
jr c,$+4
sub c
inc l
djnz bucle
ld (#A000),hl
ld (#A002),a
ret

Avatar de Usuario
MiguelSky
Lord of Short Time
Lord of Short Time
Mensajes: 6969
Registrado: Sab 08 Oct , 2005 2:02 am
Contactar:

Re: División 16-bits / 8-bits sin signo

Mensajepor MiguelSky » Lun 12 Oct , 2020 11:52 pm

Más que justificado! Buen trabajo, Sergio, como siempre :)


¿Quién está conectado?

Usuarios navegando por este Foro: Ahrefs [Bot]


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