flat assembler
Message board for the users of flat assembler.
![]() Goto page 1, 2 Next |
Author |
|
vid 20 Feb 2008, 11:40
absolute address doesn't fit (in 32bit mode) to word. you can use relative address, eg. "label1 - label2"
|
|||
![]() |
|
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 ... |
|||
![]() |
|
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? |
|||
![]() |
|
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. |
|||
![]() |
|
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.
|
|||
![]() |
|
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 |
|||
![]() |
|
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 |
|||
![]() |
|
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! |
|||
![]() |
|
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? |
|||
![]() |
|
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).
|
|||
![]() |
|
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 |
|||
![]() |
|
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.. |
|||
![]() |
|
revolution 20 Feb 2008, 15:12
Alphonso wrote: jmp near [Label0+ebx] ;add offset |
|||
![]() |
|
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 |
|||
![]() |
|
Alphonso 20 Feb 2008, 15:40
revolution wrote:
Who put those brackets there like that! ![]() Yep, try Code: add ebx,Label0 ;add offset jmp near ebx |
|||
![]() |
|
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: ... _________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
![]() |
|
revolution 20 Feb 2008, 16:03
Hehe, bitRAKE: the align 8 will probably cost more than you save by using db.
|
|||
![]() |
|
bitRAKE 20 Feb 2008, 16:05
revolution wrote: Hehe, bitRAKE: the align 8 will probably cost more than you save by using db. _________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
![]() |
|
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 |
|||
![]() |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.