Class: RMasm::DataItem
- Inherits:
-
BinaryDirective
- Object
- Directive
- BinaryDirective
- RMasm::DataItem
- Defined in:
- lib/rmasm/data_core.rb
Overview
RMasm::DataItem represents a single data declaration in a program.
The following primitive are defined at a global scope :
-
db : a byte (8 bits)
-
dw : a word (16 bits)
-
dd : a double word (32 bits)
-
dq : a quad word (64 bits)
-
float: a 32 bits floating point
-
float2: a vector of 2 floats
-
float3: a vector of 3 floats
-
float4: a vector of 4 floats.
A declaration can accept multiple declaration on a single line. Each declaration item could be
-
a NUMERIC value: declare a datatype with a default value
example : db 0 # initialize a byte with the 0 value float 1.5 # initialize a float with the 1.5 value dd 1555 # initialize a dword with the dword value 1555 MyStruct 0 # Initialize MyStruct using the 0 value as the default byte values for the struct
-
a SYMBOL :symbol value: declare a datatype with an attached label to it and a default value that is equal to data.default.value. There are 2 cases in the symbol :
- the symbol starts with a @. This symbol is considered as an address referencing the :xxxx symbol example : dd :@other_symbol # initialize a dword with the adress of :other_symbol - otherwise, if the symbol is a plain symbol, this is equivalent to declare :nil[0 => data.default.value] example : dd :a # initialize a dword accessible from the label :a
-
a SYMBOL ARRAY :symbol, declare an array of the datatype. The array_size can be :
- an integer value : like in :my_symbol[50]. Declare an array with 50 elements. If this value == 0, then the array is considered as a variable array. Note that you cannot use an array with a struct that contains a variable array. - an association integer => default_value, like in :my_symbol[50 => 1], Declare an array of 50 elements with default value 1. The value should be the same type as the datatype. - if the symbol is :nil, then the array is an anonymous array (no labels are emitted)
-
a plain ARRAY [array_size], that depends on the datatype :
- if the datatype is a primitive, the array declare an array of datatype with array_size elements. The default value can be affected as well as for the :symbol[array_size] example : db [50] # initialize 50 bytes with the value = data.default.value dd [50 => 1] # initialize 50 dword with the dword value 1 - if the datatype is a struct, then the array is considered to fill the structure example: with have a basic struct :MyStruct { db :a; dw :b; dd :c } MyStruct [0, 1, 2] # initialize a MyStruct this MyStruct.a = 0, MyStruct.b = 1, MyStruct.c = 2
-
a plain HASH { key => value, …} that depends on the datatype :
- if the datatype is a primitive, the key is an integer and represents an index with associated value example : db { 5 => 1, 50 => 2} # initialize an array of 51 elements with the data.default.value. But set the 5th element to 1 and the 50th element to 2 - if the datatype is a struct, then the key are considered as named parameters for the struct example : MyStruct { :b => 1, :c => 2, :a => 1 } # initialize a MyStruct this MyStruct.a = 0, MyStruct.b = 1, MyStruct.c = 2. Remark that you can initialize the fields in any orders you want if the field is not supplied, the whole structure is by default fill with the data.default.value
-
an EXPRESSION element: when performing operations with :@symbols
example : dd :first_array[50] dd (:@_ - :@first_array) # is equivalent to calculate the sizeof(:first_array), or :first_array.sizeof
-
a STRING used with the byte datatype (or char datatype for unicode strings)
example : db "this is rmasm in action", 0 # initialize a null terminated string of bytes dc "this is rmasm in action", 0 # initialize a null terminated string of char (can be byte or word)
SYMBOL declaration can the be initialized with the << operator
example : db :xxxx[50] << [0,1,2,3] << { 4..9 => 4, 10 => 5, 11..-1 => 255 }
# initialize an array of 50 bytes with the 4 first value equals to 0, 1, 2, 3
# then the :xxxx[4] to :xxxx[9] will be set to 4
# then the value :xxxx[10] = 5
# remaining values are set to 255, meaning that :xxxx[11..49] = 255
Direct Known Subclasses
Instance Attribute Summary collapse
-
#array_size ⇒ Object
readonly
Returns the value of attribute array_size.
-
#default_value ⇒ Object
readonly
Returns the value of attribute default_value.
-
#symbol ⇒ Object
readonly
Returns the value of attribute symbol.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
Attributes inherited from Directive
Class Method Summary collapse
Methods included from IBinIOWriter
#_binary_read, #_binary_write, #binary_read, #binary_write, #from_binary, #to_binary
Methods inherited from Directive
Instance Attribute Details
#array_size ⇒ Object (readonly)
Returns the value of attribute array_size.
155 156 157 |
# File 'lib/rmasm/data_core.rb', line 155 def array_size @array_size end |
#default_value ⇒ Object (readonly)
Returns the value of attribute default_value.
155 156 157 |
# File 'lib/rmasm/data_core.rb', line 155 def default_value @default_value end |
#symbol ⇒ Object (readonly)
Returns the value of attribute symbol.
155 156 157 |
# File 'lib/rmasm/data_core.rb', line 155 def symbol @symbol end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
155 156 157 |
# File 'lib/rmasm/data_core.rb', line 155 def type @type end |
Class Method Details
.decode(type, value) ⇒ Object
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/rmasm/data_core.rb', line 194 def self.decode(type, value) symbol = :nil default_value = Data::DEFAULT.value initial_default_value = default_value value_ext = default_value array_size = nil is_prim = type.is_primitive? check_the_default_value = nil if value.is_a?(Numeric) value_ext = value elsif value.is_a?(String) value_ext = value elsif value.is_a?(Symbol) symbol = value elsif value.is_a?(Array) if is_prim array_size, default_value, value_ext = decode_array_size(value) else value_ext = value end elsif value.is_a?(Hash) if is_prim # if value is a hash, then consider this has a variable array with hash value initialization array_size, default_value, value_ext = decode_array_size([0, value]) else # else the value must be interpreted by the struct value_ext = value end elsif value.is_a?(RMasm::SymbolModifier) symbol = value.symbol array_size, default_value, value_ext2 = decode_array_size(value.size) value_ext = (value_ext2.nil?)? value.value : value_ext2 + value.value else return Report.error(:R4053, value.class, type, value) end # Check if the default value is changed if default_value != initial_default_value if is_prim return Report.error(:R4033, default_value, type, type.range) if !type.valid?(default_value) else return Report.error(:R4062, default_value, type) if !Byte.valid?(default_value) end end if is_prim return PrimitiveDataItem.new(type, symbol, array_size, default_value, value_ext) end return StructDataItem.new(type, symbol, array_size, default_value, value_ext) end |
.decode_array_size(value) ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/rmasm/data_core.rb', line 157 def self.decode_array_size(value) # Return [array_size, default_value, init_values] default_value = Data::DEFAULT.value array_size = value # If value is an array then expect the first one to be the array size description if value.is_a?(Array) return [Report.error(:R4041, value)]*3 if value.empty? array_size = value.shift if value.empty? value = nil end else # if the value is not an array, then set this value to nil, array_size contains now the value value = nil end # If we have a Hash as an array_size, this is a [size => default_value] if array_size.is_a?(Hash) # Check the the size of the array is correct return [Report.error(:R4011, array_size)]*3 if array_size.size != 1 new_size, default_value = array_size.shift # Check that key is a positive integer return [Report.error(:R4022, new_size, "#{new_size} => #{default_value}")]*3 if !(new_size.is_a?(Integer) && new_size >= 0) array_size = new_size elsif !(array_size.is_a?(Integer) && array_size >= 0) return [Report.error(:R4022, array_size, array_size)]*3 end # return the decoding [array_size, default_value, value] end |
.fetch(type, value) ⇒ Object
248 249 250 251 |
# File 'lib/rmasm/data_core.rb', line 248 def self.fetch(type, value) data = decode(type, value) data.fetch if !data.nil? end |