0
0
mirror of https://github.com/netwide-assembler/nasm.git synced 2025-09-22 10:43:39 -04:00

FR 2499968: structures with non-zero base offset

Add an optional second argument to struc, document it and test it.
Also removed trailing whitespace in nasmdoc.src in the process.
This commit is contained in:
Victor van den Elzen
2009-03-27 03:53:59 +01:00
parent 1d7d7c64cf
commit 56b820355c
3 changed files with 119 additions and 64 deletions

View File

@@ -3742,13 +3742,15 @@ structures; instead, the preprocessor is sufficiently powerful that
data structures can be implemented as a set of macros. The macros
\c{STRUC} and \c{ENDSTRUC} are used to define a structure data type.
\c{STRUC} takes one parameter, which is the name of the data type.
This name is defined as a symbol with the value zero, and also has
the suffix \c{_size} appended to it and is then defined as an
\c{EQU} giving the size of the structure. Once \c{STRUC} has been
issued, you are defining the structure, and should define fields
using the \c{RESB} family of pseudo-instructions, and then invoke
\c{ENDSTRUC} to finish the definition.
\c{STRUC} takes one or two parameters. The first parameter is the name
of the data type. The second, optional parameter is the base offset of
the structure. The name of the data type is defined as a symbol with
the value of the base offset, and the name of the data type with the
suffix \c{_size} appended to it is defined as an \c{EQU} giving the
size of the structure. Once \c{STRUC} has been issued, you are
defining the structure, and should define fields using the \c{RESB}
family of pseudo-instructions, and then invoke \c{ENDSTRUC} to finish
the definition.
For example, to define a structure called \c{mytype} containing a
longword, a word, a byte and a string of bytes, you might code
@@ -3767,8 +3769,8 @@ from the beginning of a \c{mytype} structure to the longword field),
\c{mt_word} as 4, \c{mt_byte} as 6, \c{mt_str} as 7, \c{mytype_size}
as 39, and \c{mytype} itself as zero.
The reason why the structure type name is defined at zero is a side
effect of allowing structures to work with the local label
The reason why the structure type name is defined at zero by default
is a side effect of allowing structures to work with the local label
mechanism: if your structure members tend to have the same names in
more than one structure, you can define the above structure like this:
@@ -3792,6 +3794,26 @@ so code such as \c{mov ax,[mystruc.mt_word]} is not valid.
correct syntax is \c{mov ax,[mystruc+mt_word]} or \c{mov
ax,[mystruc+mytype.word]}.
Sometimes you only have the address of the structure displaced by an
offset. For example, consider this standard stack frame setup:
\c push ebp
\c mov ebp, esp
\c sub esp, 40
In this case, you could access an element by subtracting the offset:
\c mov [ebp - 40 + mytype.word], ax
However, if you do not want to repeat this offset, you can use -40 as
a base offset:
\c struc mytype, -40
And access an element this way:
\c mov [ebp + mytype.word], ax
\S{istruc} \i\c{ISTRUC}, \i\c{AT} and \i\c{IEND}: Declaring
\i{Instances of Structures}

View File

@@ -39,14 +39,14 @@
__SECT__
%endmacro
%imacro struc 1.nolist
%imacro struc 1-2.nolist 0
%push
%define %$strucname %1
[absolute 0]
[absolute %2]
%$strucname: ; allow definition of `.member' to work sanely
%endmacro
%imacro endstruc 0.nolist
%{$strucname}_size:
%{$strucname}_size equ ($-%$strucname)
%pop
__SECT__
%endmacro
@@ -57,7 +57,7 @@ __SECT__
%$strucstart:
%endmacro
%imacro at 1-2+.nolist
times %1-($-%$strucstart) db 0
times (%1-%$strucname)-($-%$strucstart) db 0
%2
%endmacro
%imacro iend 0.nolist

33
test/struc.asm Normal file
View File

@@ -0,0 +1,33 @@
;Testname=test; Arguments=-fbin -ostruc.bin; Files=stdout stderr struc.bin
bits 32
; Simple struc example
struc teststruc1
.long: resd 1
.word: resw 1
.byte: resb 1
.str: resb 32
endstruc
; Reference with offset
mov [ebp - 40 + teststruc1.word], ax
istruc teststruc1
at .word, db 5
iend
; Struc with base offset
; should be the same as the previous stuc
struc teststruc2, -40
.long: resd 1
.word: resw 1
.byte: resb 1
.str: resb 32
endstruc
mov [ebp + teststruc2.word], ax
istruc teststruc2
at .word, db 5
iend