The previous subsection shows us how to approach arrays of uniform structures. As there is no particular reason to have string buffers of fixed size and, therefore, no reason for a fixed size structure, let's first of all make a tiny correction to the structure declaration:
struc strtabentry [s]
{
.length dw .pad - .string ; Length of the string
.string db s, 0 ; Bytes of the string
.size = $ - .length ; Size of the structure (valid
; in compile time only)
}
We only removed the .pad member of the strtabentry structure, thus allowing it to be of variable size. Obviously, we may no longer use the same get_string_length procedure as we have no constant step to iterate through the array. But you might have definitely noticed the strtabName_ptr structure in the preceding image. This structure is there to help us solve the problem of lack of a fixed step. Let's rewrite the get_string_length procedure so that it would accept a pointer to an array of pointers to structures, rather than a pointer to the array itself and an index of the desired structure. The procedure would then look like this:
get_string_length:
push ebp,
mov ebp, esp
push ebx ecx
virtual at ebp + 8
.structPPtr dd ? ; Assign label to first parameter
.structIdx dd ? ; Assign label to second parameter
end virtual
virtual at ebx
.s strtabentry ? ; Assign label to structure pointer
end virtual
mov ebx, [.structPPtr] ; Load pointer to array of structures
mov ecx, [.structIdx] ; Load index of the structure of interest
shl ecx, 2 ; Multiply index by 4 (size of pointer
; on a 32-bit platform
cmp ecx, [.structPPtr] ; Check the index to fit the size of the
; array of pointers
jae .idx_too_big ; Return error if index exceeds the bounds
mov ebx, [ebx + ecx + 4]; We have to add 4 (the size of int), in
; order to skip the number of structure
; pointers in the array
mov ax, [.s.length] ; Read the length
movzx eax, ax
.return:
dec eax
pop ecx ebx
leave
ret 8
.idx_too_big:
xor eax, eax ; The value of EAX would be -1 upon return
jmp .return
Voila! We only had to make a few tiny modifications, add a line here and a line there, and now we are able to handle structures of variable sizes.
Nothing complicated thus far, nothing complicated to follow. While there are not too many types of data, there are more ways to arrange it. While the structure may be considered both a data type and a method of arrangement for non-uniform data, we will, for convenience, treat it as a type that we are free to define. By now, we have seen how data may be arranged in static memory when the arrangement thereof is not expected to change, but what if we are dealing with dynamic data when the amount of data is not known at the time of writing the code? In such case we should know how to deal with dynamic data. This leads us to the next stage in data arrangement-linked lists and their types.