Título: ON a GOTO / ON a GOSUB in ASM Publicado por: theNestruo en 22 de Junio de 2012, 09:34:38 pm Hi!
This ASM code works like ON a GOTO (BASIC) or switch..case (C): Código: ld a, nn ; param a: unsigned 8bit value ld hl, @@JUMP_TABLE ; a *= 2 add a, a ; hl += a add a, l ld l, a adc a, h sub l ld h, a ; hl = [hl] ld a, [hl] inc hl ld h, [hl] ld l, a jp [hl] @@JUMP_TABLE: dw label_if_0 dw label_if_1 dw label_if_2 ; ... label_if_0: ; ... label_if_1: ; ... label_if_2: ; ... Please note that:
Suggestions and improvements are welcome :) Título: Re: ON a GOTO / ON a GOSUB in ASM Publicado por: theNestruo en 26 de Marzo de 2013, 08:33:49 pm Hi again!
I have improved this a bit, making it a subroutine. Now, it can behave like ON a GOTO (using jp) or like ON a GOSUB (using call): Código: ; ...code here... ld hl, @@JUMP_TABLE ld a, [var] call JP_TABLE ; could be jp JP_TABLE ; ...more code here... @@JUMP_TABLE: dw label_if_0 dw label_if_1 dw label_if_2 ; Uses a jump table ; param hl: address of the jump table ; param a: 0-based unsigned index to use ; modifies a, hl JP_TABLE: add a ; a *= 2 add l ; hl += a ld l, a adc h sub l ld h, a ld a, [hl] ; hl = [hl] inc hl ld h, [hl] ld l, a jp [hl] ; bytes: 13, time: 63 Another approach is to load hl from the stack. This forces the jump table to be just below the call, and limites usage to work like ON a GOTO only, but saves 3 bytes in the caller code: Código: ; ...code here... ld a, [var] call JP_TABLE ; notice is a call, but that will behave like jp dw label_if_0 dw label_if_1 dw label_if_2 ; Uses the jump table. Its direction will be pop from the stack ; param a: 0-based unsigned index to use ; modifies a, hl JP_TABLE: add a ; a *= 2 pop hl ; retrieves hl add l ; hl += a ld l, a adc h sub l ld h, a ld a, [hl] ; hl = [hl] inc hl ld h, [hl] ld l, a jp [hl] ; bytes: 14, time: 74 Another example of this technique can be found in Mr. Chin, by HAL Laboratory. Their code is 1 byte smaller but destroys the value of de register: Código: JP_TABLE: 9434: add a, a ; a *= 2 9435: ld e, a 9436: ld d, #00 ; de = a 9438: pop hl ; retrieves hl 9439: add hl, de ; hl += de 943A: ld e, (hl) 943B: inc hl 943C: ld d, (hl) ; de = (hl) 943D: ex de,hl ; hl = de 943E: jp (hl) ; bytes: 13, time: 74 Have fun! |