Karoshi MSX Community

Desarrollo MSX => Desarrollo (Español/Spanish) => Mensaje iniciado por: samsaga2 en 15 de Mayo de 2012, 01:52:21 pm



Título: Comparar números de 16 bits con signo en asm
Publicado por: samsaga2 en 15 de Mayo de 2012, 01:52:21 pm
Estoy intentando comprar dos números de 16 bits con signo en ensamblador y me estoy haciendo un lío.

Primero he intentado tirar de la BIOS (http://map.grauw.nl/resources/msxbios.php#DCOMPR). Pero la documentación no indica si es una comparación de números con o sin signo y no dice más flag que el de si son iguales. He probado intentando usar los mismos flags que con la instrucción CP (http://z80-heaven.wikidot.com/instructions-set:cp) pero me ha salido un churro.

Luego he intentado SBC HL,DE pero no he conseguido salirme con la mía.

¿Resumiendo como puedo averiguar si HL>DE siendo HL y DE dos números de 16 bits con signo?

Beso de tornillo para el que me ayude.


Título: Re: Comparar números de 16 bits con signo en asm
Publicado por: theNestruo en 15 de Mayo de 2012, 02:59:49 pm
Ahora no estoy en casa, pero juraría que con sbc se puede hacer...
    xor a
    sbc hl, de
    jp  z, @@HL_IGUAL_DE
    jp  c, @@HL_MENOR_DE
@@HL_MAYOR_DE:
    ...
@@HL_IGUAL_DE:
@@HL_MAYOR_DE:
    ...

Si estoy equivocado, por favor corregidme.

He encontrado en esta página (http://www.otakunozoku.com/nintendo-gameboy-cribsheet/) un cheatsheet en el que viene un algoritmo de comparación de 16 bit con signo y no parece ser tan sencillo...
Código:
; BC contains 16-bit signed value X
; DE contains 16-bit signed value Y
; X < Y
    LD A,B ; get MSB of value X
    ADD $80 ; flip sign bit of MSB
    LD L,A ; save signed MSB value for later
    LD A,D ; get MSB of value Y
    ADD $80 ; flip sign bit of MSB
    CP L ; compare LSB of value X & value Y
    JR NZ,.different ; equal? no, so test for less than
    LD A,E ; get LSB of value Y
    CP C ; compare LSB of value X & value Y
.different:
    JP NC,.greater ; less than? no, so value X >= value Y
    CALL condition_true ; X < Y, condition is true
.greater:
; X == Y
    LD A,C ; get LSB of value X
    CP E ; compare with LSB of value Y
    JP NZ,.different ; equal? No, so test is false
    LD A,B ; get MSB of value X
    CP D ; compare with MSB of value Y
    JP NZ,.different ; equal? no, so test is false
    CALL condition_true ; X == Y, condition is true
.different:
; X <= Y
    LD A,D ; get MSB of value Y
    ADD $80 ; flip sign bit of MSB
    LD L,A ; save signed MSB value for later
    LD A,B ; get MSB of value X
    ADD $80 ; flip sign bit of MSB
    CP L ; compare MSB of value X & value Y
    JR NZ,.different ; equal? no, so test for greater than
    LD A,C ; get LSB of value X
    CP E ; compare with LSB of value Y
.different:
    JP C,.greater ; greater? yes, so value X > value Y
    CALL condition_true ; X <= Y, condition is true
.greater:


Título: Re: Comparar números de 16 bits con signo en asm
Publicado por: nenefranz en 15 de Mayo de 2012, 07:53:59 pm
En esta web también comentan algo sobre comparaciones de 16bits con y sin signo (ir a Z80 IF-ELSE) ...
las comparaciones sin signo funcionan, pero las con signo no las he utilizado, no puedo asegurar que funcionen bien en todos los casos :P 

http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html (http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html)

bueno espero que te sea de utilidad el enlace.

Saludos,




Título: Re: Comparar números de 16 bits con signo en asm
Publicado por: nanochess en 16 de Mayo de 2012, 12:52:59 am
Si los números están en el rango -16834 a 16383 se puede usar esto:
Código:
or a
sbc hl,de
jp m,aa1   ; Salta si HL < DE
jp p,aa1   ; Salta si HL >= DE
Si los números usan el rango completo de -32768 a 32767 se puede usar esto:
Código:
ld a,h
xor $80
ld h,a
ld a,d
xor $80
ld d,a
sbc hl,de
jp c,aa1    ; Salta si HL < DE
jp nc,aa1   ; Salta si HL >= DE
Espero que te sea de utilidad


Título: Re: Comparar números de 16 bits con signo en asm
Publicado por: samsaga2 en 16 de Mayo de 2012, 10:35:30 am
Perfecto gracias   :D

Si los números están en el rango -16834 a 16383 se puede usar esto:
Código:
or a
sbc hl,de
jp m,aa1   ; Salta si HL < DE
jp p,aa1   ; Salta si HL >= DE
Si los números usan el rango completo de -32768 a 32767 se puede usar esto:
Código:
ld a,h
xor $80
ld h,a
ld a,d
xor $80
ld d,a
sbc hl,de
jp c,aa1    ; Salta si HL < DE
jp nc,aa1   ; Salta si HL >= DE
Espero que te sea de utilidad