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 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} and \c{ENDSTRUC} are used to define a structure data type.
\c{STRUC} takes one parameter, which is the name of the data type. \c{STRUC} takes one or two parameters. The first parameter is the name
This name is defined as a symbol with the value zero, and also has of the data type. The second, optional parameter is the base offset of
the suffix \c{_size} appended to it and is then defined as an the structure. The name of the data type is defined as a symbol with
\c{EQU} giving the size of the structure. Once \c{STRUC} has been the value of the base offset, and the name of the data type with the
issued, you are defining the structure, and should define fields suffix \c{_size} appended to it is defined as an \c{EQU} giving the
using the \c{RESB} family of pseudo-instructions, and then invoke size of the structure. Once \c{STRUC} has been issued, you are
\c{ENDSTRUC} to finish the definition. 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 For example, to define a structure called \c{mytype} containing a
longword, a word, a byte and a string of bytes, you might code 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} \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. as 39, and \c{mytype} itself as zero.
The reason why the structure type name is defined at zero is a side The reason why the structure type name is defined at zero by default
effect of allowing structures to work with the local label 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 mechanism: if your structure members tend to have the same names in
more than one structure, you can define the above structure like this: 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 correct syntax is \c{mov ax,[mystruc+mt_word]} or \c{mov
ax,[mystruc+mytype.word]}. 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 \S{istruc} \i\c{ISTRUC}, \i\c{AT} and \i\c{IEND}: Declaring
\i{Instances of Structures} \i{Instances of Structures}

View File

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