flat assembler
Message board for the users of flat assembler.
Index
> Main > switching from NASM to FASM Goto page 1, 2 Next |
Author |
|
revolution 14 Oct 2014, 21:59
In both cases macro could do such things. It would look something like this:
Code: macro htons reg,value { ;macro code here } macro cstring [string] { forward ;macro code here } htons eax,1 cstring 'Hello World!\0' |
|||
14 Oct 2014, 21:59 |
|
str8c 14 Oct 2014, 23:02
For the first case, consider this:
Code: mov dword [rax + 12], htons(0x806) | (htons(1) << 16) mov dword [rax + 16], htons(0x800) | ((6 | (4 << 8)) << 16) How would I make a generic "htons" macroinstruction which can deal with cases like these too? For the second case, I don't know how to make a macro to replace escape sequences in the string (my knowledge of FASM macros is still somewhat limited), can you provide a quick example? |
|||
14 Oct 2014, 23:02 |
|
revolution 15 Oct 2014, 02:53
I've only ever seen htons used once in any particular program. And the prospect of writing a special macro to deal with all the millions of different ways it might be entered is probably not worth all the effort IMO. A macro could be made to do all of the above but it would be rather long an involved and its usefulness is limited.
For the c-string thing, I seem to recall someone else already doing that and posting a solution somewhere here. I don't have time to find it right now, but perhaps a but of search-fu could reveal an answer? |
|||
15 Oct 2014, 02:53 |
|
typedef 15 Oct 2014, 03:06
str8c wrote: but FASM seems to be missing some useful features. lol |
|||
15 Oct 2014, 03:06 |
|
revolution 15 Oct 2014, 04:53
One useful feature that is missing is inline macros. This is why things like the htons example above require a bit more work to do with the current macro capabilities.
The c-string style is more a matter of familiarity than being demonstrably better or worse. With fasm's use of the angle brackets (<>) we can make single string values with embedded characters: Code: invoke function,<'abc',9,'123',0> |
|||
15 Oct 2014, 04:53 |
|
edfed 15 Oct 2014, 07:49
fasmw:
ctrl + h: replace, "`" by "'" and then, "\0'" by "',0" replacing nasm by fasm is a very good idea then welcome |
|||
15 Oct 2014, 07:49 |
|
Tomasz Grysztar 15 Oct 2014, 09:10
str8c wrote: For the first case, consider this: The language of fasm's preprocessor is very different from the counterparts in the other assembler. When you cannot translate something directly it appears to be a deficiency of the target language, but it may simply arise from the different philosophy behind it that causes a very different style to be used to perform analogous tasks. It may be like in the case of translating from language that allows multiple consecutive commands in the same line into a Python-like language, where you are suddenly forced to use line breaks. And it is even worse in this case. fasm's preprocessor does not have inline macros - by design, it was intended to reflect the fact that assembly language is a "line-based" language, in which every instruction occupies a separate line. This leads to a different way of arranging the thoughts in code. Probably the closest possible translation of your "htons" snippet to fasm would look like: Code: struc htons x { . = ((x and 0xFF) shl 8) or (x shr 8) } LO htons 0x806 HI htons 1 mov dword [rax+12],LO or (HI shl 16) str8c wrote: For the second case, I don't know how to make a macro to replace escape sequences in the string (my knowledge of FASM macros is still somewhat limited), can you provide a quick example? It is something I prepared quickly, but it is not really simple, even though it handles only the decimal escape values: Code: macro cstring [string] { common local src,len,a,esc,val virtual at 0 src:: db string len = $ end virtual esc = 0 repeat len load a byte from src:%-1 if esc>0 if a>='0' & a<='9' esc = esc + 1 val = val*10 + a-'0' else db val esc = 0 end if else if a<>'\' db a end if if a='\' esc = 1 val = 0 end if end repeat if esc>1 db val end if } cstring 'Hello World!\13\10\0' |
|||
15 Oct 2014, 09:10 |
|
revolution 15 Oct 2014, 10:48
I think the C escape values are in octal, not decimal.
"\12" is a line feed. And you have to limit the count of numbers to 3 so that things like ASCII numbers following can be supported. "\0123" decodes to <10,"3"> |
|||
15 Oct 2014, 10:48 |
|
str8c 15 Oct 2014, 11:04
Tomasz Grysztar wrote:
Thanks for the reply. As a C programmer, I would not say your solution for the first case is perfect, but it is more than satisfying. For the second, the macro you provided was useful, but did not behave as expected (it skipped characters following escape sequences). Here is my revised version which works as expected: Code: macro str [string] { common local src, len, a, esc, val virtual at 0 src:: db string len = $ end virtual esc = 0 repeat len load a byte from src:%-1 if a >= '0' & a <= '7' if esc > 0 esc = esc + 1 val = val * 8 + a - '0' else db a end if else if a = '\' if esc > 0 db '\' esc = 0 else esc = 1 val = 0 end if else if esc > 0 esc = 0 db val end if db a end if end if end repeat if esc > 1 db val end if } |
|||
15 Oct 2014, 11:04 |
|
revolution 15 Oct 2014, 11:23
What does the following give?
Code: str "\0123" Code: "\x1223420522545feda45" ;how many characters are generated? |
|||
15 Oct 2014, 11:23 |
|
str8c 15 Oct 2014, 11:32
revolution wrote: What does the following give? I didn't need it for my uses, but here is another revised version which should correctly limit octal sequences to 3 characters ("\0123" becomes 10, "3"): Code: macro str [string] { common local src, len, a, esc, val virtual at 0 src:: db string len = $ end virtual esc = 0 repeat len load a byte from src:%-1 if a >= '0' & a <= '7' if esc > 0 if esc < 4 esc = esc + 1 val = val * 8 + a - '0' else esc = 0 db val db a end if else db a end if else if a = '\' if esc > 0 db '\' esc = 0 else esc = 1 val = 0 end if else if esc > 0 esc = 0 db val end if db a end if end if end repeat if esc > 1 db val end if } |
|||
15 Oct 2014, 11:32 |
|
l_inc 15 Oct 2014, 11:43
str8c
One remark about addressing space labels. If you use an addressing space label in a virtual addressing space, then the addressing space data becomes persistent across a compilation pass and this way more memory is used during the compilation. If you don't put an addressing space label into a virtual addressing space, then the memory is freed on closing the address space. This is an empirical discovery, thus I hope Tomasz Grysztar will confirm that. For that reason I'd rather suggest to put an addressing space label outside of the virtual block and to store the converted data from inside of it to the outside addressing space. That's what I normally do to prevent wasting memory. P.S. And you should always start label names (including addressing space labels) used in macros with a double dot. Otherwise you'll have to confront undesired effects. _________________ Faith is a superposition of knowledge and fallacy |
|||
15 Oct 2014, 11:43 |
|
revolution 15 Oct 2014, 11:47
l_inc wrote: str8c Also, are you meaning that the converted data should overwrite the original data? Plus, I've never seen any method or function in fasm to "free" memory. It doesn't work that way. |
|||
15 Oct 2014, 11:47 |
|
l_inc 15 Oct 2014, 12:01
Quote: I don't know how one closes an address space? Closing a virtual addressing space is done with end virtual. Quote: Also, are you meaning that the converted data should overwrite the original data? No. I mean, that the converted data should be written into a preallocated buffer. Quote: Plus, I've never seen any method or function in fasm to "free" memory fasm does it's own kind of memory management, but I don't know the details. _________________ Faith is a superposition of knowledge and fallacy |
|||
15 Oct 2014, 12:01 |
|
Tomasz Grysztar 15 Oct 2014, 13:17
l_inc wrote: If you don't put an addressing space label into a virtual addressing space, then the memory is freed on closing the address space. This is an empirical discovery, thus I hope Tomasz Grysztar will confirm that. |
|||
15 Oct 2014, 13:17 |
|
str8c 15 Oct 2014, 15:44
l_inc wrote: For that reason I'd rather suggest to put an addressing space label outside of the virtual block and to store the converted data from inside of it to the outside addressing space. That's what I normally do to prevent wasting memory. Can you provide an example of how you would do this (I am still a bit lost when I comes to FASM's more complex macro features)? l_inc wrote:
I realized this, is there any reason FASM doesn't do this automatically for local labels? |
|||
15 Oct 2014, 15:44 |
|
Tomasz Grysztar 15 Oct 2014, 16:17
str8c wrote:
|
|||
15 Oct 2014, 16:17 |
|
l_inc 15 Oct 2014, 22:55
Tomasz Grysztar
Quote: Yes, it's true. The details are a bit more complex OK. Thanks for the confirmation. Quote: But you have to be using them extensively in order to notice the difference. I suppose, string definition is something that might appear many times in a project. Lots of the resulting persistent memory spaces might eat up the memory in case of larger projects. str8c Quote: Can you provide an example of how you would do this I've just blindly rewritten your last macro without considering any meaning behind the code (it's been a long hard day): Code: macro str [string] { common local ..asDst, ..dst, pos, len, a, esc, val ..asDst:: ..dst rb len virtual at 0 db string pos = 0 esc = 0 repeat $ load a byte from %-1 if a >= '0' & a <= '7' if esc > 0 if esc < 4 esc = esc + 1 val = val * 8 + a - '0' else esc = 0 store byte val at ..asDst:..dst+pos store byte a at ..asDst:..dst+pos+1 pos = pos + 2 end if else store byte a at ..asDst:..dst+pos pos = pos + 1 end if else if a = '\' if esc > 0 store byte '\' at ..asDst:..dst+pos pos = pos + 1 esc = 0 else esc = 1 val = 0 end if else if esc > 0 esc = 0 store byte val at ..asDst:..dst+pos pos = pos + 1 end if store byte a at ..asDst:..dst+pos pos = pos + 1 end if end if end repeat if esc > 1 store byte val at ..asDst:..dst+pos pos = pos + 1 end if len = pos end virtual } Quote: I realized this, is there any reason FASM doesn't do this automatically for local labels? Tomasz Grysztar has already answered that, thus I just want to explain my wording. "Always" and "undesired" refer to common cases. If you know that the effects of a regular global label are exactly what you want to have, then you obviously would not prepend it with a double dot. For the same reason I could say, that you should never use an anonymous label in a macro, but I expect readers to sieve that through a bit of common sense and not to take that "always" for an immutable law. _________________ Faith is a superposition of knowledge and fallacy |
|||
15 Oct 2014, 22:55 |
|
revolution 16 Oct 2014, 02:32
One extra function that I occasionally find missing (and perhaps inline macros could provide) is string manipulation for label names. For example: stripping a leading character is something I've never been able to do. Perhaps my knowledge is just lacking but it appears that it can't be done. We have the concatenate operator (#) but no equivalent extractor operator.
|
|||
16 Oct 2014, 02:32 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.