|
|
The way to find out the size of a memory type is to look it up in the predefined list sizeof using the constants defined above as indices, like this:
-> (sizeof c-pointer) 8 -> (sizeof c-byte) 1 -> (sizeof c-float) 4 -> (sizeof c-double) 8 -> (sizeof c-short) 2 -> (sizeof int64) 8 -> (sizeof real32) 4
-> (set onek (allocate-memory 1024)) 0x140264a00 -> (set intarray (allocate-memory (* 10 (sizeof c-int)))) 0x140118830 -> (set realarray (allocate-memory (* 10 (sizeof c-float)))) 0x140118860 -> (free-memory onek realarray intarray) Null
( address memtype )
( address [ memtype len ] )
( address [ memtype len offset ] )
( address memtype val )
( address [ memtype len ] val )
( address [ memtype len offset ] val )
The first memory retrieval construct reads a single element of memory of the given type from the given address and returns it, converted to the most appropriate Isis type. The second retrieves an array of data from memory, returned as a list of values, unless len is zero, in which case a single (non-list) value is returned (as in the first form). The last form works the same way, but adds an offset to the address to determine where to retrieve the value.
The memory storage operators work in an analogous fashion. In each case val is converted to the specified memory type and stored at the specified location. If val is a list, an array is written into memory, up to a maximum number of elements specified by len if given. Otherwise, only a single value is stored into memory, even if len is non-zero. All of the storage operators return the same val that was passed to them.
Certain Isis types may not be compatible with certain memory types, in which case an error message will be printed and Null returned. For example, you cannot store Isis procedures as any type, and you cannot store Isis addresses as any type other than c-pointer. An error will also be printed if you try to store a list containing elements of different types.
Here are some examples:
-> (set oneint (allocate-memory (sizeof c-int))) 0x140008da0 -> (oneint c-int 424242) 424242 -> (oneint c-int) 424242 -> (oneint c-int 53.23) 53.23 -> (oneint c-int) 53 -> (free-memory oneint) Null -> (set onebyte (allocate-memory 1)) 0x140008d80 -> (onebyte c-byte 42) 42 -> (onebyte c-byte) 42 -> (onebyte c-byte 1001) # This will overflow the byte 1001 -> (onebyte c-byte) 233 -> (free-memory onebyte) Null -> (set array1 (allocate-memory (* 3 (sizeof c-int)))) 0x140008de0 -> (array1 c-int [1 2 3]) [ 1 2 3 ] -> (array1 [c-int 3]) [ 1 2 3 ] -> (array1 [c-int 10]) # Peeking past the end of the allocated area [ 1 2 3 0 0 0 14 0 1076136672 1 ] -> (array1 c-int [4.4 5.3 6.7]) [ 4.4 5.3 6.7 ] -> (array1 [c-int 3]) [ 4 5 6 ] -> (free-memory array1) Null -> (set array2 (allocate-memory (* 5 (sizeof c-int)))) 0x140008de0 -> (array2 [c-int 5] [1 2 3 4 5 6 7]) 0x140008de0 -> (array2 [c-int 0 (* 3 (sizeof c-int)) ] 42) 42 -> (array2 [c-int 5]) [ 1 2 3 42 5 ] -> (free-memory array2) Null
reverse-bytes reverses the byte order of elements in a buffer. It accepts word sizes of 2, 4, or 8 bytes. The output buffer address is returned, or Null if an invalid word size was specified.
-> (set b1 (allocate-memory 16)) 0x14014cc40 -> (set b2 (allocate-memory 16)) 0x14014cc60 -> (set-memory 16 42 b1) 0x14014cc40 -> (b1 [c-byte 16]) [ 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 ] -> (compare-memory 16 b1 b2) False -> (copy-memory 16 b1 b2) 0x14014cc60 -> (compare-memory 16 b1 b2) True -> ((+ b2 6) c-byte 57) 57 -> (set b3 (search-memory 16 57 b2)) 0x14014cc66 -> (set index (integer (- b3 b2))) 6 -> (search-memory 16 88 b2) Null -> (b1 c-byte [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]) 0x14014cc60 -> (reverse-bytes 4 4 b1 b2) 0x14014cc60 -> (b2 [c-byte 16]) [ 4 3 2 1 8 7 6 5 12 11 10 9 16 15 14 13 ]