Addressing structure members

A few words need to be said on how individual members of a structure may be addressed. When statically allocated, we may refer to a structure by its label/name, which is translated into its address. For example, if we have a strtabentry structure named se defined in our data section, and we need to read the nth byte from the string, all we have to do would be this:

mov  al, [se.string + n]   ; 0 <= n < 30

If, on the other hand, we cannot use a label (for example, we are in a procedure, and a pointer to a structure is its parameter), then we can use the mighty virtual directive. As a quick demonstration, here's a procedure that returns the length of the string, not including the terminating zero:

get_string_length:
push ebp
mov ebp, esp
push ebx
;=========
virtual at ebp + 8 ; Give a name to the parameter on stack
.structPtr dd 0 ; The parameter itself is not modified
end virtual
;---------
virtual at ebx ; Give local name to the structure
.s strtabentry 0 ; The structure is not really defined
end virtual ; so the string is not modified
;=========
mov ebx, [.structPtr] ; Load structure pointer to EBX
mov ax, [.s.length] ; Load AX with the length
movzx eax, ax ; Upper 16 bits may still contain garbage
; so we need to clean it
dec eax ; Exclude null terminator
pop ebx
leave
ret 4

Just to keep things fresh in memory, let's take another look at the lines where we read the pointer from the stack and where we load AX with the length of the string. The first one is as follows:

mov   ebx, [.structPtr]

The preceding code loads the parameter from the stack. As we remember, declaring a virtual label lets us assign a readable name to the memory locations that cannot be named otherwise, and the stack is one of the examples. In this specific case, .structPtr is translated into ebp + 8, thus the line itself is equivalent to the following:

mov   ebx,[ebp + 8]

Similarly, had there be a second parameter, the virtual declaration would look like this:

virtual at ebp + 8
.structPtr dd 0
.secondParam dd 0
end virtual

In that case, reading the second parameter would be done like this:

mov   ecx, [.secondParam]

Also, it would translate into the following:

mov   ecx, [ebp + 12]  ; Which is ebp + 8 + sizeof(.structPtr)

Here is the second line we are interested in:

mov   ax, [.s.length]

In this specific case, we are accessing the first member of the structure - .length, which means that the line is translated into this:

mov   ax, [ebx]

However, should we need to access the string itself, for example, if we need to load a register with the address of the string, the code would look like this:

lea   eax, [.s.string]

This would, in turn, translate into the following:

lea   eax, [ebx + 2]
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset