flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > How to get each character from a string in a macro (fasmg) |
| Author |
|
|
Serke 24 Nov 2025, 16:13
Code: macro str_with_attr label_name, str, attr label_name: repeat lengthof str db (str shr ((%-1) * 8)) and 0xff db attr end repeat end macro or Code: macro str_with_attr label_name, str, attr local area_label label_name: virtual at 0 area_label:: db str end virtual repeat sizeof area_label load char : byte from area_label : %-1 db char, attr end repeat end macro |
|||
|
|
Rostrocop 24 Nov 2025, 16:31
Thank you so much Serke, I have a lot to learn. Could you please explain a little bit the first example? It looks great, but I am having a hard time understaing how it works.
By the way, do you know if there is any documentation about fasmg macro syntax besides the official fasmg user manual? Best regards. |
|||
|
|
Serke 24 Nov 2025, 19:48
Rostrocop wrote: Thank you so much Serke, I have a lot to learn. Could you please explain a little bit the first example? It looks great, but I am having a hard time understaing how it works. The first and second examples are similar, the difference lies in how the string is processed. In the second example, the string is basically treated as an array-like sequence of characters (or bytes). In the first example, however, the string is implicitly converted to a number because a bitwise operation is applied to it. That number is right-shifted (shr) for each character by the character’s position multiplied by 8 (since each ASCII character occupies 8 bits) and masked with 'and 0xff' to extract the individual character’s byte. For example, consider the string "Bye". 'B' 'y' 'e' correspond to ASCII codes 42 79 65. When converted to a single number, this becomes 0x657942 ('eyB' in memory order). Here is what happens inside the repeat loop: Iteration 1 Shift right by (%-1) * 8 = (1-1) * 8 = 0 bits: 0x657942 Mask with 0xff: 0x42 ('B') Iteration 2 Shift right by (%-1) * 8 = (2-1) * 8 = 8 bits: 0x006579 Mask with 0xff: 0x79 ('y') Iteration 3 Shift right by (%-1) * 8 = (3-1) * 8 = 16 bits: 0x000065 Mask with 0xff: 0x65 ('e') I hope this helps. |
|||
|
|
Rostrocop 24 Nov 2025, 21:22
Thank you for taking the time to write such a detailed explanation. In the first example, when you say that the string is implicitly converted to a number, do you mean a sequence of bytes? Otherwise there would be a limit of bits depending on the target processor (for example, 8 bytes in x64). Also, the order is little endian, is that dependant on the target processor or is it always the same order regardless of the processor?
As for the second example, I suppose the use of "virtual at 0" is some kind of "discard" area that is only valid while the macro is being executed, am I right? |
|||
|
|
Tomasz Grysztar 24 Nov 2025, 21:49
Rostrocop wrote: Thank you for taking the time to write such a detailed explanation. In the first example, when you say that the string is implicitly converted to a number, do you mean a sequence of bytes? Otherwise there would be a limit of bits depending on the target processor (for example, 8 bytes in x64). Also, the order is little endian, is that dependant on the target processor or is it always the same order regardless of the processor? Rostrocop wrote: As for the second example, I suppose the use of "virtual at 0" is some kind of "discard" area that is only valid while the macro is being executed, am I right? |
|||
|
|
Rostrocop 24 Nov 2025, 23:42
Hi Tomasz! Thank you for your response, everything is clear now.
P.S. I was just watching your videos about real mode, they are great. I am really enjoying programming again after many years (I am 47 now). I had my first computer (an Amstrad PCW) when I was 7 years old, so I like the simplicity of old school computers and operating systems, and fasm is a great tool for experimenting with that. In fact, I have just finished my first boot sector game Best regards. |
|||
|
|
Tomasz Grysztar 25 Nov 2025, 17:17
One more thing: I think it would be more natural to use STRUC here instead of MACRO:
Code: struc (label_name) str_with_attr str, attr local area_label label_name: virtual at 0 area_label:: db str end virtual repeat sizeof area_label load char : byte from area_label : %-1 db char, attr end repeat end struc game_over_string str_with_attr "GAME OVER", 0x1F |
|||
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.