flat assembler
Message board for the users of flat assembler.
![]() Goto page Previous 1, 2, 3 Next |
Author |
|
Borsuc 28 Feb 2008, 16:15
I agree, no calling standards needed. Actually it wouldn't be 'destructive' at all, if you take your time to document and comment the code (which IS a good thing regardless of your calling standard).
After all, every programmer should at least check the functions to see "the big picture" how they work and at the very least what registers they use as inputs (this should be documented and commented well). So yes, "no standards" is a good way if used properly. |
|||
![]() |
|
vid 28 Feb 2008, 18:18
Quote: So yes, "no standards" is a good way if used properly Have you ever tried to code something big using "no standards" way? If every function is called same way, you don't need to always look up how it's called each time you look at code. |
|||
![]() |
|
Borsuc 28 Feb 2008, 19:30
But you look at it's parameters, otherwise of course it'll be a source of bugs..
and when you look at the parameters, you can look at what parameter goes where too (instead of which parameter goes first, you see which goes where). same thing |
|||
![]() |
|
vid 28 Feb 2008, 19:50
Still, it's extra information, and more space for bugs.
Also, when reviewing code, you usually don't look up every function used, usually should names be enough. Seriously, this is completely pointless, it just makes coding hard, and there is virtually no gain in it. |
|||
![]() |
|
Borsuc 28 Feb 2008, 20:08
vid wrote: Still, it's extra information, and more space for bugs. vid wrote: Also, when reviewing code, you usually don't look up every function used, usually should names be enough. vid wrote: Seriously, this is completely pointless, it just makes coding hard, and there is virtually no gain in it. |
|||
![]() |
|
revolution 28 Feb 2008, 20:29
The_Grey_Beast wrote: IMHO the worst bugs come from not understanding/reviewing at least "the big picture" of the code. So it's best to look up every function used. |
|||
![]() |
|
edfed 28 Feb 2008, 20:29
Quote: i don't like 'standarts' in my asm code, if i would need 'standarts' i would use hll no way, you shall use a bit of standard into your codes, in asm or in anything else. because if not, the code is impossible to maintain. a systematic speed and size optimisation is not a good thing. you should use some "standard", even non-standard "standard". it will help you to select a function for each cases. the faster is to do nothing. then, instead to execute a sequantial code, make some tests to know if it's needed to execute a call is usefull. and will be faster than a systematic execution. cutting the code in layers, to isolate the functional parts. for example, the low level control, then the logical layer, then the abstraction, then the human interface. all this is the explanation for the presence of RINGs in IA 32 arch. it's a bit unbalanced as it shall not be hardware but pure software. sometimes, some layers covers many abstractions levels. and some abstraction levels can covers many layers. structural code. |
|||
![]() |
|
Borsuc 28 Feb 2008, 20:38
revolution wrote: You seem to be confusing "the big picture" with "the small details". Reviewing about what are the inputs and outputs of every function and comparing it to each and every instance of where it is called are very small details that will seriously overload the human brain and muddy the big picture. In normal "stdcall" standard way you have to do this: Look at prototype, see which parameter goes where (e.g: a function might take the first parameter being y, then z, then x, for example, in a coordinate). Of course this was a stupid example, but imagine such a function has different parameters apart from coordinates. In order to know which goes first, you have to study the prototype. And what's wrong if, in the prototype (documentation), there are different "places" for these parameters? For example: x goes in ecx z goes in esi y goes in ebx totally random of course, but it proves the point to the extreme. Same thing. |
|||
![]() |
|
revolution 28 Feb 2008, 20:54
The_Grey_Beast wrote: x goes in ecx I already have this in my function and I need to call your function:
ecx=z esi=y And all other registers in use How do I call your function described above? BTW: In additional to the inputs x, y & z you also need to specify what registers are corrupted and what registers are the return values for each and every function, that is a lot of stuff to write. |
|||
![]() |
|
Borsuc 28 Feb 2008, 20:58
Alas that is optimization you're talking about -- and of course you can fine tune this and achieve the "hard to maintain" project if you're willing for optimization (i would since otherwise i would be coding in C).
And yes there is some documentation to be written, but perhaps it isn't significant for me as I type fast -- I don't really know how fast others type, but for me writing documentations is enjoyable, not because I like to do it, but because I always forget something when I go back, even the same project (if it's big enough, like working some months for it! trust me it happened to me). so at least this method reminds you that documentation is essential, otherwise you skip it and it'll be for the worst. |
|||
![]() |
|
vid 28 Feb 2008, 21:41
Quote: Alas that is optimization you're talking about -- and of course you can fine tune this and achieve the "hard to maintain" project if you're willing for optimization this way you will write something small that is of very high "quality" regarding code size and speed. but such things are practically useless. if you want something useful, it has to be big, eg. easy to maintain. sad, but in practice code quality is second. there is shitload of small apps no one uses. |
|||
![]() |
|
daniel.lewis 28 Feb 2008, 23:24
*sigh*
Well some people seem to agree with me. This may not be the best answer, but here's my answer: For any calling convention, you *cannot* just take: ebx=x, ecx=z, esi=y and use: ecx=x, esi=z, ebx=y You will *always* have to juggle registers and/or the stack. What the difference is between my 'calling convention' and stdcall or cdecl or any other, is that the method I use is to use the most sensible register for a given purpose. ESI is best for input strings because all of the lodsb, movsb, scasd functions expect it. EDI is best for output strings for the same reason. ECX is best for loop counters because of jecxz and loop etc etc. However, as I showed in my last post, sometimes there are conflicts such as with String_replace (there are 3 strings, 3 lengths?) so it does need to be looked at. How much harder is: ESI=haystack EDI=old ECX=haystack.length EBX=old.length [0]=new [1]=new.length Than: (char* haystack, char* old, uint haystack_length, uint old_length, char* _new, uint new_length) What I suggest is not just a "random" distribution of registers, I suggest using what is *SENSIBLE* for the function instead of trying to stuff the circle into the square. If that means that occassionally you have to look at the function parameters, ![]() ![]() Someone said 'oh, but optimization doesn't matter'. Go program in Java. I'm here to make the best program I possibly can because the Java version's already been written 13 times by 11 different teams. "it's inside that counts" "beauty is that which neither insufficient nor superfluous, which meets exactly it's own end" Regards, Dan _________________ dd 0x90909090 ; problem solved. |
|||
![]() |
|
edfed 28 Feb 2008, 23:53
esi = source
edi = destination or parent source. and that's all. it's compatible with a lot of µP, like 68000, 6809, PIC 16f84, etc... as they commonly have 2 index registers minimum. the stack pointer is always here, and on the non x86 µP, it's rarelly used for param passing, so, i never pass by stack on x86 for compatibility reasons... compatibility is a big word, but just imagine, adopt the same syntax, mnemonics and registers names in all arch will be a step to multiplatform assembly. then, limit the possibilities to a common one. exeption are the RISC arch, that don't have a lot of mnemonics, for this, it's also possible to code with macros without slow down of executions. yes, the multiplatform assembly can start in the assembler itself. where is it stated that we MUST code for 68000 with D1, D2, D3 mnemonics, or X86 with eax, ebx, ecx? we can make a common syntax for all µP, then select the target with an option, and it will generate the code for the selected platforms. |
|||
![]() |
|
bitRAKE 29 Feb 2008, 01:39
I retardedly code crap like this:
Code: macro STACK nm,reg{ macro nm#.top r \{ mov r,[reg] \} macro nm#.push r \{ mov [reg+4],r add reg,4 \} macro nm#.pop r \{ mov r,[reg] sub reg,4 \} macro nm#.depth r \{ lea r,[reg+4] sub r,nm shr r,2 \} lea reg,[nm-4] } ![]() My algorithms follow the same general crap-tastic style. Some limitation might get a page of documentation, and then I decide to do something else. Which means another page of text explaining why it isn't done the way just stated, lol. I like to include references to the papers I followed which lead to the code and then try to model the code with similar naming to the paper. |
|||
![]() |
|
ic2 01 Mar 2008, 08:00
I think I see what revolution want to do. I have not been here long and I could be wrong, but I think revolution wrote the Ollydbg and he need some cooperation with Fasm coders to keep the craziness out of the debugger. He have been dedicated for a long time and never asked for much in return from anyone. For the first time starting last week I can started using the new Ollydbg and it's fun and educational.
If many are like myself, I use Message Boxes to debug and I wasted a lot of time trying to do everything POSSIBLE to STOP my program from being debug by others. So you know my coding is really quite retarded. That's the major problem with debuggers and I don't believe it's only me ... My question and suggestion is lets use a few standard way of skill writing that will help other who have brought this little miracle into existence. Mental balance is now the key to advancement. They know it all already,,, but order is now needed so mistakes don't start happing. NOW..... I would appreciate to find more 100% TRUE anti-debugging code ( that cannot be easily step-upon or replaced ) that we can use when needed and comment out whenever we want to run the real code through the debugger and no one would know better ways of how to do that than revolution himself... Maybe impossible but it will help to eliminate this problem. This way we all kill two birds with one stone with-out any major disagreements. I would love to code like I got some since for a change and keep in-step with others. Hope I'm on track and making a little since here. I'm getting close to coding Fasm to stay step to step with masm and poasm using Fasm macros with-out losing any Fasm flare. (It will not take much to switch back and forth preety soon) I'll be back after I master the manuals. Hope a common standard can be reached. Deal or No-Deal ![]() |
|||
![]() |
|
revolution 01 Mar 2008, 08:15
ic2 wrote: ... I think revolution wrote the Ollydbg ic2 wrote: ... and he need some cooperation with Fasm coders to keep the craziness out of ... ic2 wrote: NOW..... I would appreciate to find more 100% TRUE anti-debugging code ( that cannot be easily step-upon or replaced ) ... |
|||
![]() |
|
bitRAKE 01 Mar 2008, 08:53
Standards are a double-edged sword: programmers get dumbed down with all the hand-holding and eventually have no clue that PROC is a macro, or that EBP is a general purpose register. I'm not in favor of creating ignorant coders, but the learning curve can be steep. Using multiple language is one way - creating abstractions in x86 is another. I think x86 programmers should learn the architecture they are attempting to program on, and not focus on abstractions above it - like the Windows API. Invoke is not an instruction.
Once a level of understanding of x86 is reached the calling convention is hardly an issue. We have shortcut names: stdcall, c, pascal, fastcall, etc. There are editors that will hint when a function is being used, so no lookup is even needed - nothing to remember besides the basics. Who corrects the stack, and how registers/flags are used can be hinted by the editor. |
|||
![]() |
|
revolution 01 Mar 2008, 09:01
Also, ESP is a general purpose register. Difficult to master but possible.
I have tried a few times to free up EBP with various macro changes and things, but they were all rejected (or at least ignored) by posters here (mostly because they were lame ideas that had too many restrictions). So I figured, don't try to fight the world, just go with the flow. Am I being dumbed down? ![]() |
|||
![]() |
|
bitRAKE 01 Mar 2008, 09:25
I'm not claiming abstractions don't have a purpose - I am saying that that purpose conflicts directly with the primary reason to code in assembly language - control (typically for performance). EBP is not only required for creating flexible stack frames, but the instructions set is specifically designed to use it in that manner - both with supporting instructions and addressing modes.
Though, to use it generally in that manner is to instantly code at a lower performance level than compiled HLL code. Rarely, is it needed in the way it was designed to be used (excluding 16-bit code). ![]() |
|||
![]() |
|
Goto page Previous 1, 2, 3 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.