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:
@@ -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}
|
||||||
|
@@ -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
33
test/struc.asm
Normal 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
|
Reference in New Issue
Block a user