flat assembler
Message board for the users of flat assembler.

Index > Main > Solved: Putting label addresses in a table?

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
daniel.lewis



Joined: 28 Jan 2008
Posts: 92
daniel.lewis 20 Feb 2008, 11:30
Embarassed I tried finding it in documentation, but even though I'm sure this is a very trivial thing to do, I couldn't figure it out the intuitive ways.

Could someone provide an example of how to do:

labelA:
nop
nop
ret

myTable:
dd labelA, $0, $0, $0, labelA.sp, $0, $0, $0 ; <--- this should be a pointer to labelA
dw labelB, $0, eof, $0, $0, $0, $0, $0 ; <--- brownie points for near jump pointers!

I've already tried it with:

$labelA
[labelA]
labelA
@labelA


Last edited by daniel.lewis on 20 Feb 2008, 13:57; edited 1 time in total
Post 20 Feb 2008, 11:30
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 20 Feb 2008, 11:40
absolute address doesn't fit (in 32bit mode) to word. you can use relative address, eg. "label1 - label2"
Post 20 Feb 2008, 11:40
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 19873
Location: In your JS exploiting you and your system
revolution 20 Feb 2008, 11:42
If your writing a Win32 app then dw labelA won't work since the value of labelA > 65535.

But in general this is how to do it.
Code:
org 0
labelA: nop
Table1:
db labelA
dw labelA
dd labelA
...    


Or for Win32
Code:
...
.code
labelA: nop
table2:
dd labelA
...    
Post 20 Feb 2008, 11:42
View user's profile Send private message Visit poster's website Reply with quote
daniel.lewis



Joined: 28 Jan 2008
Posts: 92
daniel.lewis 20 Feb 2008, 12:57
Yeah, except I'm making 256 of them for *each jump table* Forcing the use of a far jump and doubling my allocation is actually a serious problem.

How else am I supposed to do:

lea ebx, [table+eax*2]
jmp near [ebx]

If I need to, I'll do it by calculating it all out by hand?
Post 20 Feb 2008, 12:57
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 19873
Location: In your JS exploiting you and your system
revolution 20 Feb 2008, 13:05
Why are you running out of memory with just a few tables? Are you writing for DOS and have a 64K segment limit?

It would be helpful to know just what you are trying to achieve so that people can help you better.

Ususally "jmp near [table+eax*X]" is good enough. Is it 32bit code or 16bit code? It makes a difference as to what "jmp near" will do.
Post 20 Feb 2008, 13:05
View user's profile Send private message Visit poster's website Reply with quote
daniel.lewis



Joined: 28 Jan 2008
Posts: 92
daniel.lewis 20 Feb 2008, 13:11
Well, it's 32-bit code. I'm not sure what the options are, but I'm trying to pack it in. I'm writing a JavaScript interpreter. There's no point in reinventing the wheel - unless this time it's round.
Post 20 Feb 2008, 13:11
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 19873
Location: In your JS exploiting you and your system
revolution 20 Feb 2008, 13:23
Okay, since you want to compress your jump table then you have a problem. You need to extend the addresses to 32bit.
Code:
table_start:
  dw labelA-table_start
       dw labelB-table_start
       dw labelC-table_start
       dw labelD-table_start
       dw labelE-table_start
...


        mov     ebx,table_start
     mov     eax,[function_byte]
 movzx   eax,word[ebx+eax*2] ;read the table
 add     eax,ebx ;add the offset
     jmp     eax ;call eax also works    
Post 20 Feb 2008, 13:23
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4324
Location: Now
edfed 20 Feb 2008, 13:41
ok, i see the problem, i have the same for my own projects...

Code:

;i name this the flist, it can be compared to the IVT
;but it's composed of 32:32 far pointers (to be aligned)

include         'put.inc'
include         'refresh.inc'
include         'palette.inc'
include         'node.inc'
include         'txt.inc'
include         'htm.inc'
include         'frame.inc'
include         'box.inc'
include         'pong.inc'
include         'keyboard.inc'
f          dd   @f-$-4
.null      dd   0          ,0    ; the null function
.node      dd   node       ,0  ; this is a 32:32 far pointer
.refresh   dd   refresh    ,0   ;offset first, and segment second
.palette   dd   palette    ,0   ;shall be changed at load time
.put       dd   put        ,0   ;of the functions...
.txt       dd   txt        ,0
.htm       dd   htm        ,0
.frame     dd   frame      ,0
.pong      dd   pong       ,0
.box       dd   box        ,0
.key       dd   keyb       ,0
@@:

    


and then, to call, i make it:
____________________________
item:
.call=0
____________________________
item1 dd f.func
____________________________
use32 or use16

mov esi,item1
mov eax,[esi+item+call]
mov eax,[eax]
call eax
____________________________
use32

mov esi,item1
mov eax,[esi+item+call]
call far [eax]

mov eax,f.func
call far [eax]
_______________________________
and it works in all the 3 cases above

Code:
to compress this list:
c:
.null      db   0             ; the null function
.node      db   (f.node-f)/8        ; this is a 8bit pointer
.refresh   db   (f.refresh-f)/8     ; the position of the function in the flist
.palette   db   (f.palette-f)/8     ; updated at run time too
.put       db   (f.put-f)/8           
.txt       db   (f.txt-f)/8        
.htm       db   (f.htm-f)/8     
.frame     db   (f.frame-f)/8  
.pong      db   (f.pong-f)/8    
.box       db   (f.box-f)/8       
.key       db   (f.keyb-f)/8      

    


and to call, then:

movzx eax,byte[c.func]
lea eax,[eax*8+f]
mov eax,[eax]
call eax

i don't know how it is named, but i name it the LAYERS
or levels

it works for code as for datas...

as code is datas

Code:

label:
inc al
inc ah
inc bh
inc bh
inc cl
inc ch
inc dl
inc dh
.end:     ;used to test the breakpoint CS:EIP, if it is in this table, then return to main code start or somewhere else...

i:
.incal db 0
.incah db 1
.incbl db 2
.incbh db 3
.inccl db 4
.incch db 5
.incdl db 6
.incdh db 7


assume breakpoint irq active

mov esi,i.incal
movzx ebx,byte[esi]
add ebx,label
jmp ebx
    


Last edited by edfed on 20 Feb 2008, 14:08; edited 1 time in total
Post 20 Feb 2008, 13:41
View user's profile Send private message Visit poster's website Reply with quote
daniel.lewis



Joined: 28 Jan 2008
Posts: 92
daniel.lewis 20 Feb 2008, 13:57
Solved:
mov AL, [ESI]
and AL, 0x7F
mov BL, [PARSE_TABLE+EAX*2]
mov [HERE-1], BL
jmp short HERE
HERE: mov EAX, 0xDEADBEEF
int 0x03
ret

SPACE: mov EAX, 0xBABEEEEE
int 0x03
ret


~~~

PARSE_TABLE:
db SPACE-HERE, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0
dw $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0


The debugger says EAX = 0xBABEEEEE!
Post 20 Feb 2008, 13:57
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4324
Location: Now
edfed 20 Feb 2008, 14:12
yeah
good, and i'm sure you'll try to make it for far pointers and other self-modifiable code?
Post 20 Feb 2008, 14:12
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 19873
Location: In your JS exploiting you and your system
revolution 20 Feb 2008, 14:13
Doesn't look very solved to me. Why do you read with eax*2 when your table is bytes? Why is the second part of the table words? Overwriting your code with bl is a sure way to make the processor go crazy updating the caches and prefetch queue with the suddenly changed instruction that follows (100's of clock cycles wasted for no good reason).
Post 20 Feb 2008, 14:13
View user's profile Send private message Visit poster's website Reply with quote
daniel.lewis



Joined: 28 Jan 2008
Posts: 92
daniel.lewis 20 Feb 2008, 14:21
THANK YOU! I was wondering how come for non-zero values it was crashing on me with weird EIP addresses! : )

I'm not sure about the instruction pipe kill on SMC, I'll have to read up. Worst case, I'll use dw and near addresses (and remember to use EAX*2 again)

Update:

http://www.ptlsim.org/Documentation/html/node8.html

They agree with you - SMC on something in the instruction pipeline will cause a cache flush and reload the page from memory.

Using the SMC method, I had my program very quickly handling all ECMA defined whitespace.

This is what I'm now doing; still using a byte jump-table. Unfortunately, it's crashing randomly 2 or 3 characters in.

mov EBX, HERE
and AL, 0x7F
add BL, [PARSE_TABLE+EAX]
jmp EBX
HERE:


Last edited by daniel.lewis on 20 Feb 2008, 15:12; edited 1 time in total
Post 20 Feb 2008, 14:21
View user's profile Send private message Reply with quote
Alphonso



Joined: 16 Jan 2007
Posts: 295
Alphonso 20 Feb 2008, 15:02
I'm having a bad day today, so if I've misunderstood, sorry. Anyway here's some code, very similar to what revolution has written, except maybe you can use the rept mac to save some typing.

Code:
        mov eax,1                    ;Label1
        movzx ebx,word[Table1+eax*2] ;displacement from Label0
        jmp near [Label0+ebx]        ;add offset

Table1:
        rept 3 count:0               ;start count from 0, 3 labels
        { dw Label#count-Label0 }    ;dw Label0-Label0, Label2-Label1,Label3-Label1 etc..

Label0:
        nop
        nop
        ;....
Label1:
        nop
        nop
        ;....

Label2:
        nop
        nop
        ;.... etc..     
For more labels just increase rept number and add labels.
Post 20 Feb 2008, 15:02
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 19873
Location: In your JS exploiting you and your system
revolution 20 Feb 2008, 15:12
Alphonso wrote:
jmp near [Label0+ebx] ;add offset
Hmm, that won't work.
Post 20 Feb 2008, 15:12
View user's profile Send private message Visit poster's website Reply with quote
daniel.lewis



Joined: 28 Jan 2008
Posts: 92
daniel.lewis 20 Feb 2008, 15:17
Yeah, Alphonso... me too. : ) Thanks for trying to help.

What's happening is EBX is the address to jump to. As soon as you put anything beyond the two nops, each label is separated by a different sized segment of bytes (jagged array problem). It works when you know the array isn't jagged.

For general cases where each label has different code, you need to set up a table which stores sufficient information to build pointers from it. In my case:

void* x = baseAddress + table[i];
goto x;

Regards,
Dan
Post 20 Feb 2008, 15:17
View user's profile Send private message Reply with quote
Alphonso



Joined: 16 Jan 2007
Posts: 295
Alphonso 20 Feb 2008, 15:40
revolution wrote:
Alphonso wrote:
jmp near [Label0+ebx] ;add offset
Hmm, that won't work.

Who put those brackets there like that! Rolling Eyes hehe

Yep, try
Code:
        add ebx,Label0               ;add offset
        jmp near ebx    
Post 20 Feb 2008, 15:40
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 3892
Location: vpcmipstrm
bitRAKE 20 Feb 2008, 15:59
Code:
Dispatcher:
  movzx eax,[TABLE+eax]
  lea eax,[COMMON+eax*8]
  jmp eax



TABLE db \
  (Route00 - COMMON)/8,\
  (Route01 - COMMON)/8,\
  ...
  (Route66 - COMMON)/8


  align 8
COMMON:

  align 8
Route00:

  align 8
Route01:


...    
...of course, the routines can be moved around to save bytes. Much can be done in 8 bytes - it's common for some routines to be very similar.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 20 Feb 2008, 15:59
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 19873
Location: In your JS exploiting you and your system
revolution 20 Feb 2008, 16:03
Hehe, bitRAKE: the align 8 will probably cost more than you save by using db.
Post 20 Feb 2008, 16:03
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 3892
Location: vpcmipstrm
bitRAKE 20 Feb 2008, 16:05
revolution wrote:
Hehe, bitRAKE: the align 8 will probably cost more than you save by using db.
It worked for me.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 20 Feb 2008, 16:05
View user's profile Send private message Visit poster's website Reply with quote
Alphonso



Joined: 16 Jan 2007
Posts: 295
Alphonso 20 Feb 2008, 16:14
Should work for jagged arrays, but maybe not the best way to do it.
Code:
include 'win32ax.inc'

start:
        mov eax,2                    ;Label2
        movzx ebx,word[Table1+eax*2] ;displacement from Label0
        add ebx,Label0               ;add offset
        jmp ebx

Table1:
        rept 4 count:0               ;start count from 0, 4 labels
        { dw Label#count-Label0 }    ;dw Label0-Label0, Label2-Label1,Label3-Label1 etc..

Label0:
        invoke MessageBox,NULL,"Label 0","Table",MB_OK
        jmp exit
        db 'Some other stuff'
Label1:
        invoke MessageBox,NULL,"Label 1","Table",MB_OK
        jmp exit
        db 'more stuff'
Label2:
        invoke MessageBox,NULL,"Label 2","Table",MB_OK
        jmp exit
        db 'stuffed'
Label3:
        invoke MessageBox,NULL,"Label 3","Table",MB_OK
        jmp exit
        db 'Not stuffed'
exit:
            invoke ExitProcess,0
.end start    
Post 20 Feb 2008, 16:14
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.