flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > Simple listing macro for fasmg Goto page 1, 2 Next |
Author |
|
Tomasz Grysztar 27 May 2016, 19:01
Seeing the listing-like macros that people create for fasm 1, I was inspired to try something similar in fasmg and this is the result:
Code: define Listing namespace Listing offset = $%% macro disphex number*,digits:8 repeat digits digit = ((number) shr ((%%-%) shl 2)) and 0Fh if digit < 10 display '0'+digit else display 'A'+digit-10 end if end repeat end macro end namespace macro ? line& line namespace Listing undefined_bytes = $% - $%% defined_bytes = $%% - offset if $ - undefined_bytes - defined_bytes < $$ defined_bytes = $ - undefined_bytes - $$ end if offset = $%% disphex offset-defined_bytes,8 display ': ' column = 0 while defined_bytes if column = 8 column = 0 display 13,10,' ' end if load data:byte from $ - undefined_bytes - defined_bytes disphex data,2 display ' ' defined_bytes = defined_bytes - 1 column = column + 1 end while repeat 8-column display ' ' end repeat display `line,13,10 end namespace end macro This works well with x86 examples, but not with the examples that use HEX output - there the formatting macros intercept the bytes generated by instructions and convert them into hex text. In that case some other variant of listing macros would be needed - perhaps displaying the actual addresses instead of file offsets, and the bytes generated by instruction regardless of whether they go into the final output or not. |
|||
27 May 2016, 19:01 |
|
Tomasz Grysztar 28 May 2016, 19:22
Here's that slightly modified variant that displays assumed addresses instead of file offsets and shows bytes generated by instructions even when they are in a virtual block and do not go into output file:
Code: define Listing namespace Listing base = $$ offset = $ macro disphex number*,digits:8 repeat digits digit = ((number) shr ((%%-%) shl 2)) and 0Fh if digit < 10 display '0'+digit else display 'A'+digit-10 end if end repeat end macro end namespace macro ? line& line namespace Listing if ~ $$ eq base base = $$ offset = $$ end if bytes = $ - offset if $ - bytes < $$ bytes = $ - $$ end if offset = $ disphex (offset scale 0)-bytes,8 display ': ' column = 0 while bytes > 0 if column = 8 column = 0 display 13,10,' ' end if load data:byte from $ - bytes disphex data,2 display ' ' bytes = bytes - 1 column = column + 1 end while repeat 8-column display ' ' end repeat display `line,13,10 end namespace end macro Last edited by Tomasz Grysztar on 20 Sep 2016, 13:48; edited 1 time in total |
|||
28 May 2016, 19:22 |
|
l_inc 29 May 2016, 00:20
Tomasz Grysztar
Quote: shows bytes generated by instructions even when they are in a virtual block and do not go into output file Which is in most cases not desirable actually. For that reason I explicitly omitted everything placed in nested virtual blocks, while allowing to display their internal content when additionally placing the ilen_/_ilen block inside. But in your case you also handle the virtual blocks incorrectly, because changing the addressing space does not necessarily mean setting current offset to the new base: Code: 00401000: B8 00 00 00 00 mov eax,0 00401005: virtual 00401005: B8 01 00 00 00 mov eax,1 00401000: B8 00 00 00 00 end virtual ;<- All of a sudden 00401005: B8 02 00 00 00 mov eax,2 This approach has also another disadvantage: the instructions are not shown if they are generated by a higher-level macro such as invoke. This results in longer byte sequences without providing a good reference to what these refer to. _________________ Faith is a superposition of knowledge and fallacy |
|||
29 May 2016, 00:20 |
|
Tomasz Grysztar 29 May 2016, 07:22
l_inc wrote: Tomasz Grysztar |
|||
29 May 2016, 07:22 |
|
l_inc 29 May 2016, 22:36
Tomasz Grysztar
Quote: The purpose of this second variant was noted in the first post Sorry, I missed that part. But the idea I tried to express is still same: it's better to use block-wise application of whatever effects. Nested blocks allow to differentiate what effect should be applied first. If done right, works quite well. For example, the implementation of HEX.seg/HEX.endseg is problematic: to allow for nesting I always used in-place modification (needs improvement for compression cases) instead of enclosing into virtual-blocks. The org-directive however is a pain in the ass, and in early implementations I used the same close-reopen-block trick in an org-redefinition, but many encodings (e.g., into base64) are very hard to do that way, and supporting nesting requires to do all paired macros of such "encoding"-kind in a uniform way. So I switched to a different approach: all the data across all addressing spaces separated by the org directive are gathered into a single virtual-block, then converted using whatever encoding, then stored back overwriting the original bytes. _________________ Faith is a superposition of knowledge and fallacy |
|||
29 May 2016, 22:36 |
|
jmg 18 Sep 2016, 22:59
Tomasz Grysztar wrote: Here's that slightly modified variant that displays assumed addresses instead of file offsets and shows bytes generated by instructions even when they are in a virtual block and do not go into output file: This is cool, but there were no actual usage examples ? I played around by drop of the above into listing.inc & then Code: include 'listing.inc' and that seems to generate a listing in the console, needing this for a file Code: ..\..\fasmg invert.asm invert.bin > invert.lst I notice that seems to go a little strange if Code: include 'hex.inc' is also active - ie it seems designed for BIN output only? or is there a include order or placement that works better with HEX ? addit: Testing this, I see it appends this at end of list, on a pass 2 passes, 95 bytes. and appends nothing on an asm fail, which is a little vague. Can Fasmg instead list the Errors, so the LST file says either of 2 passes, 95 bytes. 0 Errors. or 3 Errors. It seems to not report the errors in the list file ? - I'm not sure how easy that is to add ? |
|||
18 Sep 2016, 22:59 |
|
Tomasz Grysztar 19 Sep 2016, 07:40
jmg wrote: or is there a include order or placement that works better with HEX ? Quote: It seems to not report the errors in the list file ? - I'm not sure how easy that is to add ? |
|||
19 Sep 2016, 07:40 |
|
jmg 19 Sep 2016, 08:49
Tomasz Grysztar wrote:
That 2nd one, was the one I used for the tests. It seems to do the listing part ok, but then appends some extra garbage, when HEX is enabled ? |
|||
19 Sep 2016, 08:49 |
|
Tomasz Grysztar 19 Sep 2016, 09:30
jmg wrote: That 2nd one, was the one I used for the tests. Code: postpone purge ? end postpone Because the macro does not differentiate what lines does it show, if you want all the lines from hex.inc to be ignored you may also modify the HEX macros themselves and make them generate listing of the code-related lines (this could be a "HEX with listing" macro package). Or even this simple trick could do the job: Code: macro ? line& line if __FILE__ <> 'hex.inc' ; <<< additional condition namespace Listing if ~ $$ eq base ; ... end namespace end if end macro |
|||
19 Sep 2016, 09:30 |
|
shoorick 20 Sep 2016, 09:48
I've got a lot of garbage, seems, because of macro "proc" (maybe because of semicolon after .end):
Code: ... 0000000F: C3 00 C8 jmp 0C800h 00000012: restore proc 00000012: define proc 1 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: a2im equ ma2i 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: .end: 00000012: proc negh 00000012: 7C mov a,h ... _________________ UNICODE forever! |
|||
20 Sep 2016, 09:48 |
|
Tomasz Grysztar 20 Sep 2016, 10:02
This looks very strange. What is your "proc" macro like?
|
|||
20 Sep 2016, 10:02 |
|
shoorick 20 Sep 2016, 10:15
Code: if ~ defined proc restore proc define proc 1 macro proc name name: if used name end macro macro endp! end if .end: end macro end if (seems I took wrong variant) |
|||
20 Sep 2016, 10:15 |
|
Tomasz Grysztar 20 Sep 2016, 10:34
Oh I see, this is because procs are not included when not used, but ".end:" gets processed for each one since it is outside of "if used" (does it need to be outside?).
Anyway, you could modify the listing macros in some way like this: Code: Listing? = 1 namespace Listing base = $$ offset = $ macro disphex number*,digits:8 repeat digits digit = ((number) shr ((%%-%) shl 2)) and 0Fh if digit < 10 display '0'+digit else display 'A'+digit-10 end if end repeat end macro end namespace macro ? line& match =no? =listing?, line Listing? =: 0 else match =listing? =back?, line restore Listing? else line if Listing namespace Listing if ~ $$ eq base base = $$ offset = $$ end if bytes = $ - offset if $ - bytes < $$ bytes = $ - $$ end if offset = $ disphex (offset scale 0)-bytes,8 display ': ' column = 0 while bytes > 0 if column = 8 column = 0 display 13,10,' ' end if load data:byte from $ - bytes disphex data,2 display ' ' bytes = bytes - 1 column = column + 1 end while repeat 8-column display ' ' end repeat display `line,13,10 end namespace end if end match end macro Last edited by Tomasz Grysztar on 20 Sep 2016, 13:49; edited 1 time in total |
|||
20 Sep 2016, 10:34 |
|
shoorick 20 Sep 2016, 10:45
maybe something more simple?
i mean more standard single word switch, like NOLIST / LIST in other assemblers |
|||
20 Sep 2016, 10:45 |
|
Tomasz Grysztar 20 Sep 2016, 10:53
Modify it however you wish.
|
|||
20 Sep 2016, 10:53 |
|
Tomasz Grysztar 20 Sep 2016, 15:29
Apparently this variant of listing.inc does not work well with such "proc" anyway, because "proc" is not an unconditional macro (so it becomes a line processed by listing macro) but it opens "if" block without closing it - and this variant of listing macro tries to execute original line inside the "else" block, thus creating an overlapping of the control blocks, which leads to errors.
Here is a corrected variant that still executes the line outside of the control blocks. Some additional dummy macros are needed. EDIT: updated with some additional improvements. Code: Listing? = 1 namespace Listing base = $$ offset = $ virtual at 0 HexDigits:: db '0123456789ABCDEF' end virtual end namespace macro ? line& line rmatch =nolist?, line Listing? =: 0 else rmatch =list?, line restore Listing? else if Listing namespace Listing if ~ $$ eq base base = $$ offset = $$ end if bytes = $ - offset if $ - bytes < $$ bytes = $ - $$ end if offset = $ address = (offset scale 0)-bytes repeat 8 load digit:byte from HexDigits:((address) shr ((%%-%) shl 2)) and 0Fh display digit end repeat display ': ' if bytes < 0 bytes = 0 end if while bytes > 0 if bytes > 8 load data:8 from $ - bytes repeat 8 load digit:byte from HexDigits:(data shr ((%-1) shl 3 + 4)) and 0Fh display digit load digit:byte from HexDigits:(data shr ((%-1) shl 3)) and 0Fh display digit,' ' end repeat bytes = bytes - 8 display 13,10,' ' else load data:bytes from $ - bytes repeat bytes load digit:byte from HexDigits:(data shr ((%-1) shl 3 + 4)) and 0Fh display digit load digit:byte from HexDigits:(data shr ((%-1) shl 3)) and 0Fh display digit,' ' end repeat break end if end while repeat 8-bytes display ' ' end repeat display `line,13,10 end namespace end if end rmatch end macro macro nolist? end macro macro list? end macro postpone nolist end postpone Last edited by Tomasz Grysztar on 18 Oct 2016, 20:48; edited 5 times in total |
|||
20 Sep 2016, 15:29 |
|
jmg 20 Sep 2016, 21:01
Tomasz Grysztar wrote: Apparently this variant of listing.inc does not work well with such "proc" anyway, because "proc" is not an unconditional macro (so it becomes a line processed by listing macro) but it opens "if" block without closing it - ... ? Isn't that normally considered an error ? Most pgms I use, get rather upset if they hit unbalanced blocks, as usually that is a user-typo. |
|||
20 Sep 2016, 21:01 |
|
shoorick 21 Sep 2016, 02:48
Yes, it's working, but I have added macros list/nolist to proc.inc also (inside if block to not clone lot of them), to not generate error if any other project do not use listing.
|
|||
21 Sep 2016, 02:48 |
|
Tomasz Grysztar 21 Sep 2016, 06:22
jmg wrote:
|
|||
21 Sep 2016, 06:22 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.