flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > [fasm g] how do I concatenate strings |
Author |
|
zhak 20 Apr 2016, 22:33
How do I concatenate multiple strings into one?
Code: macro cpu? type include 'arch/'#`type#'.inc' end macro cpu 8086 doesn't seem to be working in fasm g |
|||
20 Apr 2016, 22:33 |
|
bitRAKE 21 Apr 2016, 03:38
I don't know if this is the intended way?
Code: macro cpu? type* eval 'include "arch/',`type,'.inc"' end macro cpu 8086 |
|||
21 Apr 2016, 03:38 |
|
zhak 21 Apr 2016, 07:05
I'm so dumb I tried eval, but used it improperly. Thanks a lot!
|
|||
21 Apr 2016, 07:05 |
|
Tomasz Grysztar 21 Apr 2016, 08:47
I have uploaded the bugfix. Now that macro works correctly also in this form:
Code: struc concat? first*,rest*& . = string first iterate s, rest . = string . + (s) shl (((bsr . - 1) shr 3 + 1) shl 3) end iterate end struc |
|||
21 Apr 2016, 08:47 |
|
fabbel 31 Jan 2023, 07:56
Hi
Quote:
Any particular reason why not adding some string operators indeed ? Tx Rgds |
|||
31 Jan 2023, 07:56 |
|
Tomasz Grysztar 31 Jan 2023, 12:14
fabbel wrote: Any particular reason why not adding some string operators indeed ? The reason why this never was especially pressing issue is that it tends to become hidden once you have some kind of framework established. Let me show a couple samples: Code: include 'inline.inc' inlinemacro strcat? a*, b* return = string (a) or (b) shl (8*lengthof (a)) end inlinemacro inlinemacro concat? head*, tail& local buffer buffer = string head iterate item, tail buffer = strcat(buffer,item) end iterate return = buffer end inlinemacro inlinemacro current_line rept 1, line:__line__ return = concat(__file__,' [',`line,']') end rept end inlinemacro display 'Current line: ', current_line() Code: include 'xcalm.inc' calminstruction calminstruction?.err? list*& local buffer, item compute buffer, '' loop: match item=,list, list jno final compute buffer, string buffer + item shl (8*lengthof buffer) jump loop final: compute buffer, string buffer + list shl (8*lengthof buffer) asm err buffer end calminstruction calminstruction test err 'This is a',10,9,9,'multi-line message' end calminstruction test To be clear: I'm not saying that specialized operators are completely unnecessary because you can emulate them with existing features. It's just that their implementation becomes less crucial because of that and I like to focus on things that open new doors. But the right hour for implementing them may still come. |
|||
31 Jan 2023, 12:14 |
|
Calanor 24 Feb 2023, 15:05
Tomasz: I've tried similar approaches as in your CALM example, which works fine - up until a point. It seems like if I end a string with a 8-bit character rather than 7-bit, things will get messed up. Example:
Code: calminstruction append a, b local c compute c, a compute c, string c + b SHL (8 * lengthof c) publish a, c end calminstruction Calling the code like this will at first seem to work: Code: a = "A" b = "€" append a, b However, the resulting length will be reported as 3 rather than 2. If I then perform an additional append to the result... Code: c = "B" append a, c ...I'll get a null between "€" and "B", messing up the result. The string expressed as a sequence of hexadecimal values ends up as 42008041h. Any suggestions on how I can solve this problem and, perhaps more importantly, what's causing it? |
|||
24 Feb 2023, 15:05 |
|
revolution 24 Feb 2023, 15:11
Maybe b isn't what you thought?
Code: ~ cat euro.asm b = "€" dd b ~ fasm euro.asm && hd euro.bin flat assembler version 1.73.08 (4028172 kilobytes memory) 1 passes, 4 bytes. 00000000 e2 82 ac 00 |....| 00000004 |
|||
24 Feb 2023, 15:11 |
|
Calanor 24 Feb 2023, 15:52
revolution: Good point regarding negative values. With this in mind I think I'll find a workaround, but if anyone has some nifty solution then by all means feel free to post it!
|
|||
24 Feb 2023, 15:52 |
|
Tomasz Grysztar 24 Feb 2023, 16:19
When you use "b" as a number, it is interpreted as a positive one, and then if it has the highest bit set, it requires additional byte to be stored properly, that's why converting it back to string brings an additional zero byte.
You could get around it by detecting a specific case: Code: calminstruction append a, b local c check b & lengthof b shl 3 = bsr b + 1 jno ok compute b, -b ok: compute c, a compute c, string c + b SHL (8 * lengthof c) publish a, c end calminstruction Although, with some of the recently added CALM commands, I would actually recommend another approach: Code: virtual at 0 StringBuffer:: rb 10000h end virtual calminstruction append a, b local c store StringBuffer:0, lengthof a, a store StringBuffer:lengthof a, lengthof b, b load c, StringBuffer:0, lengthof a + lengthof b publish a, c end calminstruction |
|||
24 Feb 2023, 16:19 |
|
Calanor 24 Feb 2023, 16:46
Oh, you've added load and store to CALM? Excellent! Thanks for the example, it's much appreciated! Somewhat off-topic, but is there any change log somewhere? I often find it hard to tell what's changed between different versions of fasm/g.
|
|||
24 Feb 2023, 16:46 |
|
Tomasz Grysztar 24 Feb 2023, 16:51
I prepared a StringBuilder example to showcase the current abilities of CALM:
Code: virtual at 0 StringBuilder:: rb 10000h .POSITION = 0 end virtual calminstruction .append s store StringBuilder:StringBuilder.POSITION, lengthof s, s compute StringBuilder.POSITION, StringBuilder.POSITION + lengthof s end calminstruction calminstruction .init s compute StringBuilder.POSITION, 0 call StringBuilder.append, s end calminstruction calminstruction .get target local s load s, StringBuilder:0, StringBuilder.POSITION publish target, s end calminstruction ; Test: StringBuilder.init "A" StringBuilder.append "€" StringBuilder.get a db a Calanor wrote: Somewhat off-topic, but is there any change log somewhere? I often find it hard to tell what's changed between different versions of fasm/g. |
|||
24 Feb 2023, 16:51 |
|
Calanor 24 Feb 2023, 21:59
Thanks, Tomasz! I'm still encountering problems in some situations. One block of code that would use append/concat is my base64 decoding, where I append decoded text one character at the time to the resulting string. As I use bitshifting etc to decode, the character is once again treated as a possibly signed value. Creating an alternative CALM-instruction that will only store one byte from the "text" that's to be appended works, though it doesn't feel like a very good solution.
|
|||
24 Feb 2023, 21:59 |
|
Tomasz Grysztar 26 Feb 2023, 16:00
I have finally implemented the BAPPEND operator as planned. I have no other plans for string-related additions at the moment, but this one should be quite helpful.
The problem that started this thread now has a pretty straightforward solution: Code: _ equ bappend macro cpu? type include 'arch/' _ `type _ '.inc' end macro cpu 8086 |
|||
26 Feb 2023, 16:00 |
|
Calanor 27 Feb 2023, 19:42
BAPPEND seems to work very well with both explicit strings and ASCII values. Thanks again! [Edit] Oops, spoke to soon - that issue with signed values still pops up, but BAPPEND will still be useful.
|
|||
27 Feb 2023, 19:42 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.