flat assembler
Message board for the users of flat assembler.
Index
> Main > [fasmg] push dword 640 + (480 shl 16) |
Author |
|
Tomasz Grysztar 28 Apr 2017, 14:01
These kinds of operands were ambiguous to begin with and the PUSH/POP macros I wrote for fasmg support only the strict use of whitespace as a separator.
I suggest to use a intermediary variable to hold the calculated value, because even though it worked with fasm 1, it is still ill-defined: is it a single expression "640 + (480 shl 16)", or is it "640" and then a separate expression "+ (480 shl 16)"? In fasm 1 the whitespace was stripped by preprocessor so it was not possible to use it as a hint and the expressions were collected eagerly, so it led to problems like "push -1 -1" being a single "push -2". I felt that this was contrary to expectations and that's why I made use of whitespace recognition in fasmg to handle this. It has a downside that you cannot use complex arguments containing whitespace because they are going to be treated as a bunch of separate arguments, but it also makes the whole system more predictable. The only whitespace is allowed between the size operator and value, any other space is going to be treated as an argument separator. |
|||
28 Apr 2017, 14:01 |
|
Tomasz Grysztar 28 Apr 2017, 14:13
It is of course possible to write a macro for fasmg* that would emulate the behavior of fasm 1 for PUSH/POP arguments and I may try writing it just for fun, but I wouldn't want to make it default.
Oh, and you can also trick the whitespace requirements even without intermediate variable: Code: push dword 640+(480)shl(16) ___ * This doesn't even say much, with fasmg the only limiting factor is how much sluggishness can you bear when macros become too complex. |
|||
28 Apr 2017, 14:13 |
|
VEG 28 Apr 2017, 14:28
Oh, it supports
Code: push eax ebx ecx edx Maybe something like this will suit this extended syntax of the push: Code: push (640 + (480 shl 16)) eax ebx ecx edx push <640 + (480 shl 16)> eax ebx ecx edx UPD. Code: push dword 640+(480)shl(16) In any case, what do you think about my variants? It would be nice to have consistency in how you can do some inline calculations during assembly time. Maybe it is not so hard to implement. |
|||
28 Apr 2017, 14:28 |
|
Tomasz Grysztar 28 Apr 2017, 19:25
VEG wrote: In any case, what do you think about my variants? It would be nice to have consistency in how you can do some inline calculations during assembly time. Maybe it is not so hard to implement. |
|||
28 Apr 2017, 19:25 |
|
VEG 28 Apr 2017, 20:07
Yeah, but maybe ( and ) is a bit more intuitive. Actually, it was the first thing I've tried when I'd encountered this problem. It was a big surprise for me that push in the default x86 implementation accepts more than one arguments. It could cause some unexpected results, for example, when someone will write something like this: push 1 +3. It will be assembled as 2 pushes without any errors. Maybe it will be more clear when comma will be used as a delimiter, for example, as it is used in the similar situation in the invoke macros. I'm not insisting on it. It's just some thoughts about it.
I'd like to know if any other standard x86 instructions were extended like this one. Are there some notes about it? |
|||
28 Apr 2017, 20:07 |
|
Tomasz Grysztar 28 Apr 2017, 20:38
VEG wrote: Yeah, but maybe ( and ) is a bit more intuitive. Actually, it was the first thing I've tried when I'd encountered this problem. It was a big surprise for me that push in the default x86 implementation accepts more than one arguments. It could cause some unexpected results, for example, when someone will write something like this: push 1 +3. It will be assembled as 2 pushes without any errors. Maybe it will be more clear when comma will be used as a delimiter, for example, as it is used in the similar situation in the invoke macros. I'm not insisting on it. It's just some thoughts about it. In standard macros for fasmg it might be a good idea to allow an option of disabling the multi-operand syntax of PUSH/POP at all (perhaps in addition to the <> option that I have already prepared). It could be done by simply switching the "x86.parse_operand_sequence" macro to an implementation that would treat an argument like a single operand. |
|||
28 Apr 2017, 20:38 |
|
Furs 29 Apr 2017, 12:06
I have to say that the ability to push multiple things in one instruction is probably the dumbest syntax I've ever seen, because it uses the name of an actual instruction so this technically isn't even real assembly anymore. Yeah I'm quite surprised this thing even exists, lol.
I'd be ok if a comma was required because it makes sense and at least it forms an illegal normal push instruction. But the lack of comma to generate multiple instructions from one is just hopelessly bad in my opinion. Reminds me of "evil macros" memes in C that redefine what a directive does like Code: #define if while |
|||
29 Apr 2017, 12:06 |
|
revolution 29 Apr 2017, 12:08
IIRC it came about because of the MASM proc.
Code: proc func uses ebx esi edi,arg1,arg2 |
|||
29 Apr 2017, 12:08 |
|
Furs 29 Apr 2017, 12:23
Well that's stupid. The proc is fine, since it's not an instruction, but adding it to push was a bad idea. Was it so hard to add something like .push (with dot) or pushmore or whatever to avoid confusion and know it's a macro
|
|||
29 Apr 2017, 12:23 |
|
revolution 29 Apr 2017, 12:46
I think fasm 1 gets it right with the greedy evaluation. I think anything else gets it wrong with whitespace separator evaluation. Just IMO of course.
Code: push x * y ;fasm 1 = okay, fasmg = error |
|||
29 Apr 2017, 12:46 |
|
Tomasz Grysztar 29 Apr 2017, 13:06
As I wrote above, whatever variant I choose it is going to cause problems for somebody, this syntax is irredeemable in general. Perhaps to avoid the controversy it would be best to leave the basic single-operand PUSH as default and only turn on the whitespace-separated multiple arguments by including additional optional macros.
|
|||
29 Apr 2017, 13:06 |
|
revolution 29 Apr 2017, 13:16
Yes, both will cause problems in various situations, nothing is perfect unfortunately. But I still think one version is the right way (with fewer surprises and fewer problems) and the other version is not as friendly to the uninitiated.
|
|||
29 Apr 2017, 13:16 |
|
VEG 29 Apr 2017, 13:56
TL;DR. I like the idea of using comma as a separator of arguments in push, it will be more consistent. But disabling of this feature is also ok for me.
Actually, with FASMG you can rewrite almost any part of the standard x86 instructions, so if someone will not like something, it will be possible to change it. So, it is not a big drama when you think that something is wrong and have to be changed. Just change it, with FASMG it is easy Quote: MASM Code: mov eax, [labelname] mov eax, [esi] mov eax, labelname mov eax, esi Code: mov eax, labelname mov eax, [esi] mov eax, offset labelname mov eax, esi This was the first thing which I had loved in FASM years ago The second was an ability to assemble plain binary files with custom format, and the third thing was the power of macroses Quote: IIRC it came about because of the MASM proc. If comma will be used as a delimiter for registers in the push, we can use the same delimiter for registers in the proc macros, like this: proc func uses <ebx, esi edi>,arg1,arg2. These symbols < and > are already used in FASM for grouping several things with commas in one argument, so it will be understandable But for my opinion MASM's syntax is a mess of arguments and it is better to introduce a special submacros for the proc which can be used just after the proc definition for automatic preserving of registers (and this proc can be automatically unset outside the proc). For example: Code: proc WindowProc hwnd,wmsg,wparam,lparam uses ebx, esi, edi mov ebx, 2 mov esi, 3 mov edi, 4 ... ret end proc So, "uses" will change settings of the current proc, it will add "push ebx, esi, edi", and it will pop these registers before ret. It is easy to raise an error when this macros is used not just after the proc definition. This idea can also be used in different situations when complex macroses are used with huge amount of optional settings. Last edited by VEG on 29 Apr 2017, 14:13; edited 1 time in total |
|||
29 Apr 2017, 13:56 |
|
Tomasz Grysztar 29 Apr 2017, 14:09
I changed the basic implementation of x86 macros so that PUSH/POP are just regular instructions that take single argument. And I think it's a good riddance. The self-hosting of fasmg uses an additional macro that enables whitespace-separated ones:
Code: iterate instr, push,pop macro instr? op local sequence sequence equ op -- while 1 match --, sequence break else match car= cdr, sequence redefine sequence cdr match :sz, x86.car match --, sequence instr car break else match head= tail, sequence redefine sequence tail instr car head end match else instr car end match end match end while end macro end iterate As for an "eagerly parsing" macro that would work similarly to fasm 1, I may write it later and share as another option. |
|||
29 Apr 2017, 14:09 |
|
Tomasz Grysztar 29 Apr 2017, 15:52
VEG wrote: Actually, with FASMG you can rewrite almost any part of the standard x86 instructions, so if someone will not like something, it will be possible to change it. So, it is not a big drama when you think that something is wrong and have to be changed. Just change it, with FASMG it is easy And yes, using commas would probably be a better choice, but a non-standard one. And of course, if you want to use comma-separated lists for PUSH, it is really easy to write a macro either for fasm 1 or fasmg that would do that. And I'm happy with leaving the basic instruction disallowing multiple arguments. After all, no Intel manual defines a multiple-argument PUSH. VEG wrote: But for my opinion MASM's syntax is a mess of arguments and it is better to introduce a special submacros for the proc which can be used just after the proc definition for automatic preserving of registers (and this proc can be automatically unset outside the proc). For example: Code: proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam |
|||
29 Apr 2017, 15:52 |
|
Tomasz Grysztar 30 Apr 2017, 07:23
Here comes a macro for PUSH/POP that eagerly collects expression arguments like fasm 1 does:
Code: define xpctrgmnt iterate operator, not,bsf,bsr,string,float,trunc,sizeof,lengthof,elementsof,\ byte,word,dword,fword,pword,qword,tbyte,tword,dqword,xword,qqword,yword,dqqword,zword define operator?.xpctrgmnt + end iterate iterate operator, xor,and,or,shl,shr,bswap,element,scale,metadata,elementof,scaleof,metadataof define xpctrgmnt.operator? + define operator?.xpctrgmnt + end iterate iterate instruction, push,pop macro instruction? operand local buffer,remaining remaining equ operand : buffer equ while 1 match car= cdr, remaining buffer reequ buffer car redefine remaining cdr match any+, :car else match +any, cdr else match any-, :car else match -any, cdr else match any*, :car else match *any, cdr else match any/, :car else match /any, cdr else match any+, :car.xpctrgmnt else match +any, xpctrgmnt.cdr else match any(, :car else match )any, cdr else match collected, buffer instruction collected buffer reequ end match else match collected, buffer instruction collected end match break end match end while end macro end iterate In particular it treats "push eax+0" as "push eax", not "push eax 0" like fasm 1 did. In fasm 1 this was a bad side-effect. And in fasmg expressions that yield register as a result are allowed in operands for any instruction. |
|||
30 Apr 2017, 07:23 |
|
VEG 30 Apr 2017, 11:00
Thank you for your examples.
BTW, It is a surprise for me also that FASM1 is able to assemble "push 1 2 3" as three actual pushes without any additional macroses =) I think that it is better to stick to less ambiguous variants, like "one push - one argument" or "comma as a delimiter". |
|||
30 Apr 2017, 11:00 |
|
Tomasz Grysztar 30 Apr 2017, 11:57
VEG wrote: BTW, It is a surprise for me also that FASM1 is able to assemble "push 1 2 3" as three actual pushes without any additional macroses =) I think that it is better to stick to less ambiguous variants, like "one push - one argument" or "comma as a delimiter". |
|||
30 Apr 2017, 11:57 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.