NASM Forum > Using NASM

Creating a jump table with 32-bit instructions

(1/2) > >>

mik3ca:
I'm trying to use nasm to create a jump table so I don't have to slow down the processor as it iterates through a bunch of compares. For simplicity, we will use register AL here as the value returned from an earlier user input function.

Let's say for example I have this code to process the input:


--- Code: ---cmp AL,00h
je doitem0
cmp AL,01h
je doitem1
cmp AL,02h
je doitem2
cmp AL,03h
je doitem3
cmp AL,04h
je doitem4
.....
cmp AL,11h
je doitem17

--- End code ---

I have attempted to convert it to something like this:


--- Code: ---blk equ 8h ;code block size so jump code fits nicely
mov AH,0h
shl AL,3 ;shift 3x = multiply by block size
add AX,jt
jmp AX

;start of jump table
jt:
org jt+blk*0h
jmp doitem0
org jt+blk*1h
jmp doitem1
org jt+blk*2h
jmp doitem2
org jt+blk*3h
jmp doitem3
...
org jt+blk*11h
jmp doitem17

--- End code ---

However nasm 2.10.04 (the version I have) is fussy on the second idea. For every org statement, I get the error:


--- Code: ---      error: org value must be a critical expression

--- End code ---

So if it doesn't like the way I'm using the org statement, is there another way I can make an efficient jump table so that the program doesn't have to have the tedious task of comparing the input to up to 16 different values  to reach the user's choice?

fredericopissarra:
16, 32 or 64 bits code?
And what you'll do if AL > 0x11?

fredericopissarra:
I'll suppose you are dealing with 32 bits code here...


--- Code: ---  section .rodata

jmptbl:
  dd  doSomerhing0
  dd  doSomething1
  dd  doSomerhing2
  dd  doSomething3
  dd  doSomerhing4
  ...
  dd  doSomerhing14
  dd  doSomething15
  dd  doSomerhing16
  dd  doSomething17
  ...

  section .text
  ...
  cmp al,0x11
  ja  doNothing
  movzx eax,al
  jmp [jmptbl+eax*4]
doNothing:
  ...
--- End code ---

debs3759:
Assuming 32-bit code:


--- Code: --- cmp     AL,11h
jg      error ; if value in al is too high, go to error routine
movzx   EAX,AL
jmp     [EAX*4 + jmptable]



jmptable: dd doitem0, doitem1, .... doitem17
--- End code ---

mik3ca:
oh....
but would the idea of loading the pointer like that also work in a 16-bit environment? because I managed to isolate the code under segment CS and the offset can be anywhere from 0 to 65535 and all functions are within the same 64K. In fact they're in the same 2K since my code side when compiled is under 2K.

I wonder if I could get away with this:

I'm also looking at reducing code size as well.


--- Code: ---mov BX,AX
shl BX,2
jmp [CS:BX+table]

table:
dw option1
dw option2
dw option3
dw option4
....
dw option17

--- End code ---

Navigation

[0] Message Index

[#] Next page

Go to full version