flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
baldr 11 Sep 2008, 00:05
edfed wrote: i will code a set of basic functions in fool |
|||
![]() |
|
bitRAKE 11 Sep 2008, 01:58
edfed wrote: then, how to assign a jcc to a cc? platform independant? ![]() Jump table based on CC - blah. Bit set/get - usually only one is ever needed. Only update flags prior to use. |
|||
![]() |
|
edfed 11 Sep 2008, 20:39
in fool ( fasm? fast? object oriented language)
a thing i "invented" because each time i coded something, it appeared clearlly that the graphical functions had always the same basic structure. FUNC,X,Y,XL,YL,COLOR after, all normal functions had the same base, then, i wrote a set of functions, "easy to use", and object oriented. objects are only datas structures. theses objects have "always" the same base. that's all. for example, a if in this language is: Code: if: .call=0 .op1=4 .cc=8 .op2=12 .then=16 .else=20 ;esi is the current item ;edi is hte parent item mov eax,[esi+.op1] mov ebx,[esi+.op2] mov ecx,[esi+.cc] cmp eax,ebx call get result push esi jc @f mov esi,[esi+.then] @@: mov esi,[esi+.else] or esi,esi je .end mov eax,[esi+.call] or eax,eax je .end mov eax,[eax] je .end call eax .end: pop esi ret and how to use it: Code: main: .if dd f.if,var1,equ,var2,way1,way2 way1 dd f.functionx,?,?,?,?,?,?,?,?,? way2 dd 0 in this example, the if have only a single way. if var1=var2, then, go in way1 else, do nothing. this way, i can then code in asm, without asm, and close to asm. but to be more hardcore, i want it multiplatform, but close to asm. each object is a data structure, and then, an execution context for a function. the problem is to code the CC to use for the fool, i think about a LUT |
|||
![]() |
|
baldr 19 Sep 2008, 17:50
edfed,
Looks like you're going to (re)invent something like direct threaded code in Forth (cute programming language by Charles Moore), or bytecode in Java™ (or even instruction set for your virtual CPU ![]() You will surely implement arithmetic operations, won't you? Then why do you have to constrain if's condition only to var1 CC var2? Implement additionally comparison and logical operations to evaluate some expression (even so simple as var1 = var2) to zero/non-zero result and pass it as a parameter to if. Look-up table can be used (for example it can translate CC constants to jCC opcodes for IA-32 to use in self-modifying code), but being able only to compare two variables as a branch condition seems cumbersome and awkward. Are f.functionx's parameters always passed by pointer (i.e. as an address, never a constant)? Code: jc @f mov esi,[esi+.then] @@: mov esi,[esi+.else] By the way, mov eax, [eax] doesn't set flags... Maybe you'll be interested to take a glance at Forth, IMHO it's as close to assembly as high-level language may come. |
|||
![]() |
|
edfed 19 Sep 2008, 21:10
first, thanks for the positive feedback. ;D
about math operations, of course it is planed to do them. as an input, the arithmetic formula, in ascii. as output, the result, with a set of flags. and finally, a branch, or a call, or nothing. then, a formula will be pointed to by an address. this formula will be a set of bytes. all bytes will have an ascii value. and the arithmetic parser will compute the formula. for the moment, the formulas will be limited to 2 operands and 1 operation. coding shall always start in the simplest form. about the pointer, yes, it is always needed, but it is possibel to have constants. for example, the code to draw a window in an application can be used in another application from the same pointer. then, maybe a real data base access to object is the goal. some speed never obtained in file manipulation. famos is one of the OS to do the same thing, and reading it's site explains why it's better to do it in ram instead on disk. but be carefull, fool is not so fool, it very powerfull and can destroy any system if you execute: Code: killhda: dd f.disk db disk.write,disk.hda dw 65536 dd 0 dd cs:0 <-- to say it is in cs segment, mov ax,cs, mov [killhda+disk.segment],ax dd 0 dd 0 oops, you show me a bug in the pseudo code i've posted. Code: jc .not mov esi,[esi+.then] jmp @f .not: mov esi,[esi+.else] @@: mov eax,[esi] mov eax,[eax] call eax effectivelly, it was not a if then else. but about if, i've tryed it, and constated it is hard to make it as easy as pure asm. cmp reg,[mem] cmp reg,const cmp [mem],const cmp reg,reg cmp [mem],[mem] cmp [[mem]],[reg] etc,etc... |
|||
![]() |
|
baldr 20 Sep 2008, 12:05
edfed,
I've meant this: Code: ;... check_for_intruder: dd f.sub, object.x, base.x, diff.x dd f.sub, object.y, base.y, diff.y dd f.mul, diff.x, diff.x, diff_x_squared dd f.mul, diff.y, diff.y, diff_y_squared dd f.add, diff_x_squared, diff_y_squared, distance_squared dd f.cmp_le, distance_squared, literal_100, object_is_near_base dd f.cmp_eq, object.color, literal_color_red, object_is_red dd f.boolean_and, object_is_near, object_is_red, red_object_is_near_base dd f.if, red_object_is_near_base, red_alert, all_your_base_are_belong_to_us ;... red_alert: dd f.zap, object, literal_immense_power dd f.say, literal_favorite_phrase ;... all_your_base_are_belong_to_us: dd f.stomp, area_around ;... literal_100 dd 100 literal_immense_power dd 666 literal_favorite_phrase db "Was that you, John Wayne?", 0 ![]() The big question is: why do you need this? Additional layer over raw machine code must be thin and transparent, or else you probably will end up with something like HLA (Randall did a good effort in structuring inherently "spaghetty-code" assembly language and his "Art of Assembly Language" is awesome). But I beg to differ: I'm in assembly language programming for raw and sheer power it gives. Here is the example (the idea was simple, but it tooks me around an hour to cast it in metal): Code: format PE GUI include "WIN32A.INC" section ".code" code executable readable writeable entry $ mov esp, wicked_stack MessageBox: jmp [__imp__MessageBoxA@16] ExitProcess: jmp [__imp__ExitProcess@4] eax_eq_literal?_branch: cmp eax, [esp] pop eax pop eax jnz @f mov esp, eax @@: ret rb 65536 section ".data" data readable writeable wicked_stack: dd MessageBox dd HWND_DESKTOP, hello_world, hello_caption, MB_OK+MB_ICONEXCLAMATION dd eax_eq_literal?_branch dd HWND_DESKTOP, goodbye_world, hello_caption, MB_YESNO+MB_ICONQUESTION dd IDYES, goodbye_ok dd MessageBox dd ExitProcess dd HWND_DESKTOP, goto_hell_world, hello_caption, MB_OK+MB_ICONINFORMATION dd 0 dd -1 goodbye_ok: dd ExitProcess dd 0 dd 0 hello_caption db "Wicked Hello", 0 hello_world db "Hello, World!", 0 goodbye_world db "Goodbye, World?", 0 goto_hell_world db "Go to hell, cruel World!", 0 data import library USER32, "USER32.DLL",\ KERNEL32, "KERNEL32.DLL" import USER32,\ __imp__MessageBoxA@16, "MessageBoxA" import KERNEL32,\ __imp__ExitProcess@4, "ExitProcess" end data Especially I like that MessageBox function returns from the first "call" (jmp to be correct) right to itself's start (recursion? no, stack flow control ![]() eax_eq_literal?_branch function demonstrates conditional jump after comparison (eax==parameter). The great flaw of this example is that flow-controlling data on stack is literally obliterated ![]() |
|||
![]() |
|
edfed 21 Sep 2008, 07:21
Quote:
i don't need this, nobody needs any computer, just human being want it to work. for me, fool is just a way to don't have to do multiples mov's or push's each time i call a function. as a result, it gives a language. about the function to do the if: Code: dd f.if, expression,condition,way1,way2 expression db '((object.x-base.x)²+(object.y-base.y)²) <= 100 & [object.color]=red',0 condition dd true way1 dd f.x,?,?,? way2 dd f.x,?,?,? coding expression directlly in ascii seems to be a good thing. |
|||
![]() |
|
baldr 21 Sep 2008, 11:45
edfed wrote:
![]() Is it only parameters' passing conventions that you don't like? If so, maybe you take a look at Forth? I'm not pushing you in any way... ![]() The IA-32 is somewhat constraining regarding to general-purpose registers (we can easily have 1-2-3-4 GB of relatively slow RAM and sink it through so small number of fast registers? Not to mention cache coherency and other issues with multi-CPU systems). Is it so difficult to have several hundreds of registers? Locally code uses only small portion of them, I think four base pointers to big registers' file plus 2..3-bit index will be enough to have four objects (in wide sense) to manipulate their properties without access to RAM. CPUs have to be designed by their programmers, period. ![]() When the authors of the game's rules don't play it (or don't have to abide by them)… My hopes toward Intel® 64 architecture was gone with the wind. Sorry for this rant. |
|||
![]() |
|
revolution 21 Sep 2008, 12:02
baldr wrote: Is it so difficult to have several hundreds of registers? |
|||
![]() |
|
edfed 21 Sep 2008, 12:13
there, we see the lack of adatative comportment from IA arch designers.
why don't use all the existing instruction set, and say, in hardware, address space from xxxxx to yyyyy is not related to memory, but registers. and with this, mov [reg],value will act as a very fast memory operation... it willl be pb, how to code mov [ezx],[ekx]? |
|||
![]() |
|
baldr 22 Sep 2008, 05:54
revolution wrote: It is not difficult to actually provide the registers, it is difficult to access the registers. Because it means the entire instruction set needs to have multiple bits available to fully identify which of the hundreds of registers one wants to use. baldr wrote: Locally code uses only small portion of them, I think four base pointers to big registers' file plus 2..3-bit index will be enough to have four objects (in wide sense) to manipulate their properties without access to RAM. |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.