Page 1 of 1
Repeat / Duplicate for DataSection
Posted: Thu Feb 23, 2012 4:18 pm
by wilbert
As far as I know, when you want 80 times a quad value of 100 inside the data section, you have to specify it 80 times at the moment.
I would appreciate some sort of duplicate or repeat option so you can say you want a value n times repeated.
Re: Repeat / Duplicate for DataSection
Posted: Thu Feb 23, 2012 4:27 pm
by Shield
Try this as a workaround
(god I love that word...)
I'm not sure if the generated code is correct (don't have the time to check), so be careful.
It doesn't work with PB's Data instruction.
Code: Select all
For i = ?start To ?stop - 1 Step SizeOf(Quad)
Debug PeekQ(i)
Next
DataSection
start:
!repeat 80
!dq 100
!end repeat
stop:
EndDataSection
Re: Repeat / Duplicate for DataSection
Posted: Thu Feb 23, 2012 4:39 pm
by wilbert
I don't know about Windows and Linux but on OS X it doesn't work.

I prefer something cross platform but when it comes to data handling, FASM and NASM don't use the same syntax
A compiler directive like ...
CompilerIf #PB_Assembler = #PB_Assembler_FASM
CompilerIf #PB_Assembler = #PB_Assembler_NASM
might also do.
Re: Repeat / Duplicate for DataSection
Posted: Thu Feb 23, 2012 5:49 pm
by Danilo
Good request.
What about extending the request for a 'Times' keyword for use in Macros, too?
Could be useful in Macros to repeat something n times.
wilbert wrote:I don't know about Windows and Linux but on OS X it doesn't work.

I prefer something cross platform but when it comes to data handling, FASM and NASM don't use the same syntax

'times' is NASM syntax and works also with FASM. Does the following work on OS X?
1st try:
Code: Select all
Macro ASMRepeat
!times
EndMacro
Macro Times(_times_,_value_,_type_) ; type: b, w, d, q, t
_value_
CompilerIf _times_ <> 1
ASMRepeat _times_ - 1 d#_type_ _value_
CompilerEndIf
EndMacro
i=1
Restore start
Repeat
Read.q q.q
Debug RSet(Str(i),3,"0") + ": " + Hex(q)
i+1
Until q=0
DataSection
start:
Data.q Times(16, $100, q)
Data.b Times( 8, $AB, b)
Data.w Times( 4, $1234, w)
Data.l Times( 2, $AABBCCDD, d)
Data.q 0
EndDataSection
2nd try:
Code: Select all
Macro ASMRepeat
!times
EndMacro
Macro Times(_type_,_times_) ; type: b, w, d, q, t
ASMRepeat _times_ d#_type_
EndMacro
i=1
Restore start
Repeat
Read.q q.q
Debug RSet(Str(i),3,"0") + ": " + Hex(q)
i+1
Until q=0
DataSection
start:
Data.q -1
Times(q,2) $01,$02,$03
Times(q,4) $100
Times(b,8) $AB
Times(w,4) $1234
Times(d,2) $AABBCCDD
Data.q 0
EndDataSection
Re: Repeat / Duplicate for DataSection
Posted: Thu Feb 23, 2012 10:07 pm
by wilbert
It seems to repeat something but it also results in a number of errors like
- integer supplied to a DQ instruction
- symbol 'AB' undefined
- symbol 'AABBCCDD' undefined
- phase error detected at the end of assembly.
Re: Repeat / Duplicate for DataSection
Posted: Mon Feb 27, 2012 12:33 pm
by wilbert
It turns out
dq only works with double precision numbers and not with a quad integer for nasm.
Hex values need to be encoded with 0x instead of $.
Besides that the code seems to work. This works on OS X
Code: Select all
Macro ASMRepeat
!times
EndMacro
Macro Times(_type_,_times_) ; type: b, w, d, q, t
ASMRepeat _times_ d#_type_
EndMacro
i=1
Restore start
Repeat
Read.q q.q
Debug RSet(Str(i),3,"0") + ": " + Hex(q)
i+1
Until q=0
DataSection
start:
Data.q -1
Times(b,4) 0x01, 0x02
Times(b,8) 0xAB
Times(w,4) 0x1234
Times(d,2) 0xAABBCCDD
Data.q 0
EndDataSection
Re: Repeat / Duplicate for DataSection
Posted: Wed Jan 02, 2013 4:41 pm
by Tenaja
I'd like to +1 this feature request; it would be nice to have this a native implementation.
I found this thread by searching for how to generating repeating data. ("+Duplicate +Data" found the thread.)
In the meantime, I have added a cleaner way to repeat Strings. I also renamed the Macro... I would rather do Rep than do Time.
This shows the two methods of producing repeating strings (original vs new), and the full code with demo code below it:
Code: Select all
Rep(b,4) "Hi", 0 ; Duplicates a STRING--This WORKS; produces: times 4 db "Hi", 0
RepString("Yo",4) ; Duplicates a STRING-- Also WORKS: times 4 db "Yo", 0
Code: Select all
Macro ASMRepeat
!times
EndMacro
Macro DQ
"
EndMacro
Macro Rep(_type_,_times_) ; type: b, w, d, q, t
ASMRepeat _times_ d#_type_
EndMacro
Macro RepString(s, _times_) ; String type only
ASMRepeat _times_ db s, 0
EndMacro
i=1
Restore start
Repeat
Read.q q.q
Debug RSet(Str(i),3,"0") + ": " + Hex(q)
i+1
Until q=0
; ------------------------------------
; Print the Hi's:
Read.s s.s
Debug s
Read.s s.s
Debug s
Read.s s.s
Debug s
Read.s s.s
Debug s
; Print the Yo's:
Read.s s.s
Debug s
Read.s s.s
Debug s
Read.s s.s
Debug s
Read.s s.s
Debug s
; ------------------------------------
DataSection
start:
Data.q -1
Rep(b,4) 0x01, 0x02
Rep(b,8) 0xAB
Rep(w,4) 0x1234
Rep(d,2) 0xAABBCCDD
Data.q 0
Rep(b,4) "Hi", 0 ; Duplicates a STRING--This WORKS; produces: times 4 db "Hi", 0
RepString("Yo",4) ; Duplicates a STRING-- Also WORKS: times 4 db "Yo", 0
EndDataSection
Replicating data
Re: Repeat / Duplicate for DataSection
Posted: Wed Jan 02, 2013 6:17 pm
by freak
The following code is crossplatform (no asm needed) and works for all types. It can repeat 0-999 times. The macro can be extended easily to support more, but I don't see the sense in repeating the same value in a datasection more than 1000 times
Code: Select all
; repeat once
Macro _R1(_type_, _val_)
Data._type_ _val_
EndMacro
; repeat 10 times
Macro _R10(_type_, _val_)
_R1(_type_, _val_): _R1(_type_, _val_): _R1(_type_, _val_): _R1(_type_, _val_): _R1(_type_, _val_)
_R1(_type_, _val_): _R1(_type_, _val_): _R1(_type_, _val_): _R1(_type_, _val_): _R1(_type_, _val_)
EndMacro
; repeat 100 times
Macro _R100(_type_, _val_)
_R10(_type_, _val_): _R10(_type_, _val_): _R10(_type_, _val_): _R10(_type_, _val_): _R10(_type_, _val_)
_R10(_type_, _val_): _R10(_type_, _val_): _R10(_type_, _val_): _R10(_type_, _val_): _R10(_type_, _val_)
EndMacro
; repeat _count_ times (0-999)
Macro Times(_type_, _val_, _count_)
CompilerIf (_count_) > 999
CompilerError "Repeat count cannot be more than 999"
CompilerEndIf
CompilerIf (_count_) >= 900: _R100(_type_, _val_): CompilerEndIf
CompilerIf (_count_) >= 800: _R100(_type_, _val_): CompilerEndIf
CompilerIf (_count_) >= 700: _R100(_type_, _val_): CompilerEndIf
CompilerIf (_count_) >= 600: _R100(_type_, _val_): CompilerEndIf
CompilerIf (_count_) >= 500: _R100(_type_, _val_): CompilerEndIf
CompilerIf (_count_) >= 400: _R100(_type_, _val_): CompilerEndIf
CompilerIf (_count_) >= 300: _R100(_type_, _val_): CompilerEndIf
CompilerIf (_count_) >= 200: _R100(_type_, _val_): CompilerEndIf
CompilerIf (_count_) >= 100: _R100(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 100 >= 90: _R10(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 100 >= 80: _R10(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 100 >= 70: _R10(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 100 >= 60: _R10(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 100 >= 50: _R10(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 100 >= 40: _R10(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 100 >= 30: _R10(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 100 >= 20: _R10(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 100 >= 10: _R10(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 10 >= 9: _R1(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 10 >= 8: _R1(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 10 >= 7: _R1(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 10 >= 6: _R1(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 10 >= 5: _R1(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 10 >= 4: _R1(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 10 >= 3: _R1(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 10 >= 2: _R1(_type_, _val_): CompilerEndIf
CompilerIf (_count_) % 10 >= 1: _R1(_type_, _val_): CompilerEndIf
EndMacro
; ---- example ----
Restore values
For i = 1 To 134
Read.s x.s
Debug Str(i) + ": " + x
Next i
DataSection
values:
Times(s, "foo", 23)
Times(s, "bar", 111)
EndDataSection
Re: Repeat / Duplicate for DataSection
Posted: Wed Jan 02, 2013 6:27 pm
by Tenaja
freak wrote:The following code is crossplatform (no asm needed) and works for all types. It can repeat 0-999 times. The macro can be extended easily to support more, but I don't see the sense in repeating the same value in a datasection more than 1000 times
Thanks! Is there a reason to avoid asm in this situation? Are the assembler commands above not cross platform?
Re: Repeat / Duplicate for DataSection
Posted: Wed Jan 02, 2013 6:31 pm
by freak
I just prefer a PB only solution if there is one. It will correctly handle ascii/unicode switches or 32bit/64bit differences. Also you don't have to worry about NASM/FASM differences.
Re: Repeat / Duplicate for DataSection
Posted: Thu Jan 03, 2013 4:12 am
by Shield
Now that's a pretty nifty solution...
