flat assembler
Message board for the users of flat assembler.
Index
> Main > What is your favourite calling standard? Goto page 1, 2, 3 Next |
Author |
|
edfed 18 Feb 2008, 17:20
i have an other standard, and this one is very powerfull.
esi is the current item edi is the parent item the entry is made by a call to the first dword pointed to by esi. Code: xor edi,edi ;to say there is no parent mov esi,main ;the current item mov eax,[esi+item.call] ;tge first dword of item is the function call eax ;to call all registers can be returned no stack passing the stack is used internally to save temporary states. the items are at ds:esi the items are simple arrays, all item begin with a dword, to knowwhat to execute. for exemple, a graphic node: Code: node: dd caller,0,0,0,0,@-$-4 dd item1,item2,item3,... @@: the four 0 are for the graphic window x,y,xl,yl an other caller is used for non graphic items. to change the screen buffer: Code: .setvesa: dd setbuff,vesascreen1 to handle a key, or more: Code: onetimekeys: ;to execture only at key press edge. dd kb.otk,@f-$-4 dd key.echap,incb,exit dd key.up,decd,curs.y dd key.down,incd,curs.y etc... i implement this in all code write now. to build an app, i don't code asm, only the structures, and use the standard platform to execute. the functions will be indexed in a table, so, it will be possible to change the config at run time by only changing the function palette all datas constituting this model are modifiable from anywhere. so, it is powerfull. as it is in devellopment, it have many lacks, but if people are ok to help, it's welcome, but all functions of this lib shall be accepted by me, post me the code, and i'll analyse it to see if it respects the ?? style. Last edited by edfed on 18 Feb 2008, 22:16; edited 1 time in total |
|||
18 Feb 2008, 17:20 |
|
revolution 18 Feb 2008, 17:30
edfed: It looks like you are describing an interpreter there.
So your favourite call standard is to pass in by array and pass back by all registers? Is that correct? |
|||
18 Feb 2008, 17:30 |
|
edfed 18 Feb 2008, 17:45
no
the index esi and edi are for the context addressing and all registers are used internally in the functions it's not an interpreter it's an execution tree, with priorities, properties and links it is more easy to use than to invent, but it is not really ready i am in the version 0.5 of this convention for now this is designed to build games and independants applications. to build the squeleton, i use the tables and structures, and when i need an extra feature, i create a new structure, a new function, and i debug it. this is for 2D gui, for 3D, i will wait to have a stable 2D, 1D and 0D lib. 2D is the gui 1D is the input 0D is the system 3D will be the phisical environment, for a direct threading of objects as real objects. it is in devellopment in the last release of fasm browser, there is the OO?? lib partially implemented. it's hard to obtain a stable structure. you can try with this one 2D processing.zip i build this lib cause i saw the assembly is not everything, the datas are everything. and to build any programms, we need to write a lot of stuff before to obtain the desired effect. for exemple, a menu, or a dialog... and i don't aggree with all previous standards, because they are made in a logic of productivity and business. i don't want to enter their fuckin businez, i want ot code freely, with no os. only a fasm version on a bootable drive, and that's all. for the functions that are not to be used with this structure, i prefer the parameters via memory. by a pointer or an imediate value in register, stack for me is not for librry interfacing, for me, it's exactlly like the stack for embeded processor, used to save temporary values. about the dynamic size buffer, i use free memory zones, and pointers to know where, how many and who create this zone. for little functions, to test on frozen environments, i prefer the data in fixed memory places. in programming, all is data, the code is just there to manipulate the datas. and for datas, i dislike the stack. irq can pilot this kind of stuff. to make it real time. |
|||
18 Feb 2008, 17:45 |
|
bitRAKE 18 Feb 2008, 20:18
I like to pass everything in registers then do a PUSHAD/POPAD. Not only does this preserve the registers, but there is also two copies (one to change, one to test). Granted this isn't used for everything - a fairly large granularity - smaller stuff is usually macro-ized (inlined).
Downside is of course the need to manually manage the stack, and the need to store return values on the stack prior to POPAD (or use flags). Additional stack space can be reserved before or after, but doing it beforehand allows the same interface code for different space requirements. _________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
18 Feb 2008, 20:18 |
|
vid 18 Feb 2008, 21:42
after i disasmed some 64bit fastcall code, i realized it clearly wins on 64bit machines. but it's a bit uglier to use in hand-crafted asm code.
|
|||
18 Feb 2008, 21:42 |
|
daniel.lewis 20 Feb 2008, 13:33
My favorite for the x86-32 platform is this:
xor EAX, EAX xor EBX, EBX mov AL, [ESI] push .done push argsForFunc2 push Func2 push argsForFunc1 push Func1 push argsForFunc0 jmp Func0 .done: When Func0 returns, it will return directly into Func1, which will return into Func2. The advantage of this over this system: push argsForFunc0 call Func0 push argsForFunc1 call Func1 push argsForFunc2 call Func2 Is that code flow for my system performs 4 EIP changes (4 instruction pipe flushes or 1+n) compared to the common way which does this 6 times (2n). I tend to custom craft my function inputs, but use conventions like: EAX is a good place to return integers and pointers ECX is a good counter Don't push only to pop again, just pass the register ESI for input strings EDI for output strings EBX and EDX are commonly thrashed - but each function's different. ESP is used for extra arguments and return pointers I only use EBP stack frame adjustment if a function is recursive, so I might use EBP in a pinch. Do not restrict yourself unnecessarily. |
|||
20 Feb 2008, 13:33 |
|
revolution 20 Feb 2008, 13:48
daniel.lewis wrote: My favorite for the x86-32 platform is this: daniel.lewis wrote:
|
|||
20 Feb 2008, 13:48 |
|
daniel.lewis 21 Feb 2008, 00:37
call/ret prediction circuitry?
I thought it just did roughly this: call = push $+5 ; return address (I might be wrong on the actual offset) jmp x ret = pop eip Which flushes the instruction pipeline because it's fetching a new bunch of stuff for the next couple instructions.... Are we talking about the same chipset? _________________ dd 0x90909090 ; problem solved. |
|||
21 Feb 2008, 00:37 |
|
revolution 21 Feb 2008, 00:43
daniel.lewis wrote: call/ret prediction circuitry? |
|||
21 Feb 2008, 00:43 |
|
revolution 21 Feb 2008, 00:46
Intel optimisation manual wrote: Avoid implementing a call by pushing the return address and jumping to the target. The hardware can pair up call and return instructions to enhance predictability. Intel optimisation manual wrote: To enable the use of the return stack mechanism, calls and returns must be matched in pairs. If this is done, the likelihood of exceeding the stack depth in a manner that will impact performance is very low. |
|||
21 Feb 2008, 00:46 |
|
edfed 21 Feb 2008, 01:22
my favourite call standard is:
here: ... ... ret .. call here |
|||
21 Feb 2008, 01:22 |
|
vid 21 Feb 2008, 02:20
edfed: pretty poor (unusuable) standard. Your standard doesn't define procedures with arguments.
|
|||
21 Feb 2008, 02:20 |
|
daniel.lewis 21 Feb 2008, 05:38
Yeah, but his is faster. : )
I have an even faster one: nop nop What do you think? Perhaps now you see why I said not to restrict yourself. While on one hand you could force all of your code to use 16-byte SSE2 registers so you can drop data in arrays regardless of type, you could also need absolutely no arguments at all, or just need to pass ESI/EDI. The best way really is situation dependent. The only reasons I can see to conform to a single standard are: 1) to ease library use 2) because compilers suck 3) because you don't know better 4) because AMD or intel might say so Good luck. _________________ dd 0x90909090 ; problem solved. |
|||
21 Feb 2008, 05:38 |
|
revolution 21 Feb 2008, 05:50
daniel.lewis wrote: The only reasons I can see to conform to a single standard are: |
|||
21 Feb 2008, 05:50 |
|
daniel.lewis 21 Feb 2008, 06:04
Umm, or we can all just force ourselves to pass arguments by only the stack in the order that they appear and return in EAX, if it means I'll be sworn at less. I thought comments and debuggers were supposed to provide the desired inspective functionality so one could revisit things. |
|||
21 Feb 2008, 06:04 |
|
revolution 21 Feb 2008, 06:24
Of course you are perfectly free to write your code without any internal standard but that is a path to destruction. Every time you write a new thing and want to integrate it with something else you have to check "what did I do with that function over there", speed of production diminishes, mistakes amplify, pushes and pops around calls appear everywhere, incorporating code from different places into a new program becomes a nightmare, and lots of other nasty things like that.
After a few months of coding without any standard you will start to see the problems. This is also a major reason why HLL people like to poke fun at asm, they see some random hacker write a completely ugly piece of asm and scream with horror. |
|||
21 Feb 2008, 06:24 |
|
daniel.lewis 21 Feb 2008, 06:30
*shrug*
|
|||
21 Feb 2008, 06:30 |
|
daniel.lewis 28 Feb 2008, 07:21
I do more or less know what registers I'm going to use based on what the function is supposed to accomplish. If it's a memcpy then ESI is input, EDI is output and ECX is length. If it's Math_randomInt, EAX is both. If it's Math_randomDouble, then MM0 is both.
I comment my functions with: String_replace ; ESI=old, EDI=haystack ; ECX=old.length, EBX=haystack.length ; [0]=new, [1]=new.length To be honest, I enjoy knowing it means my code avoids 8 or 24 cycles here and there and is a little shorter. "beauty is that which is neither insufficient nor superfluous, which meets exactly it's end" In my opinion when folks approach me and: 1) they're not willing to learn 2) their method is less streamlined, less interesting 3) they're whining about my method because it's unfamiliar or hard Then yes, at that point I feel elitist - I want to mock them. I've interacted with several people that do this to me, and I've come to appreciate the method. Mocking people carefully in this situation does the following things that I want to achieve. 1) It makes them think I'm an asshole, and so I don't get surrounded by vorgons [Hitchhiker's Guide] 2) It might make them snap out of it. 3) They work hard on coming up with good rebuttals and I learn. |
|||
28 Feb 2008, 07:21 |
|
MichaelH 28 Feb 2008, 08:17
Quote:
Wouldn't it be easier to just use a towel? I know, I know, pretty weak but someone had to post it |
|||
28 Feb 2008, 08:17 |
|
Goto page 1, 2, 3 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.