NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: munair on February 27, 2022, 09:59:56 AM
-
Some NASM examples I found put 'size:' as a final member of a structure and use it to obtain the structure's size. Is this correct?
The following code is compiler generated and NASM has no trouble compiling it:
struc _D27
_D27_fname: resd 1
_D27_sname: resd 1
_D27_age: resd 1
size:
endstruc
SECTION .text
global _start
global _end
_start:
mov eax, [_I0 + _D27_age]
_end:
mov ebx, 0
mov eax, 1
int 80h
SECTION .data
_I0: istruc _D27
at _D27_fname, dd 0
at _D27_sname, dd 0
at _D27_age, dd 0
iend
If the 'size:' member is correct, can it also be prepended, or is the name 'size' default for NASM to be recognized?
-
I THINK that Nasm defaults to "_D27_len" for the size of the structure. Check me on that, though.
Best,
Frank
-
That would be _D27_size, which doesn't require the 'size' member (_D27_len does not compile).
-
Hmm, it looks like I figured it out. The following code gives me the size:
struc _D27
_D27_fname: resd 1
_D27_sname: resd 1
_D27_age: resd 1
endstruc
SECTION .text
global _start
global _end
_start:
mov eax, _D27_size
; printing eax outputs 12
_end:
mov ebx, 0
mov eax, 1
int 80h
BTW, what happens here:
mov eax, [_D27_size]
That's what I tried first but it causes a segmentation fault when trying to print eax to the standard output device.
-
That would treat _D27_size as a pointer and would load eax with whatever is at the memory address it points to.
-
I figured as much but I still would've expected garbage output.
Perhaps the _size "macro" is doing something under the hood that causes the segmentation fault?
-
_size should be an equate to an integer number, in this case 12 so no idea why it doesn't work. It should be equivalent to mov eax,[ds:12] in your case, which will be garbage as you have no data beyond the istruc.
-
As the documentation says NASM has no intrinsic means to define data structures, so macros are used instead. Appending "_size" probably also invokes macros, which may lead to these unexpected results. First I thought the segmentation fault was caused by the print routine, but simple assignment causes the same error:
mov eax, [_D27_size]
mov [_I86], eax
The confusion is that without brackets one would think the address of variable _D27_size is assigned, so it is important to know that "_D27_size" is NOT a variable.
For clarity, the above two lines are generated from the assignment in this SharpBASIC code:
struc SPerson is
fname: str;
sname: str;
age: uint;
end
dim person: SPerson;
dim size: uint;
main do
size = len(person);
print(size);
end
If I let the compiler emit without brackets, the code compiles and runs fine.
-
Looks like a BASIC problem to me.
mov eax. [12]
will almost certainly SEGFAULT.
You know about "virtual memory"? "paging"?
Nasm is not doing this to you, but your OS almost certainly is.
Best,
Frank
-
mov eax. [12]
Well, I wouldn't think of doing that with an immediate, but it is tempting to see something like _D27_size as a variable or constant rather than something that is replaced by an immediate.
-
mov eax. [12]
Well, I wouldn't think of doing that with an immediate, but it is tempting to see something like _D27_size as a variable or constant rather than something that is replaced by an immediate.
A constant is the same as an immediate.
-
A constant is the same as an immediate.
I realized that later on. It is just that after two years of working on the SharpBASIC compiler that notion has slipped away. This is because SharpBASIC does not use EQU for constant datatypes:
movsx eax, byte [_C4]
call _sb_print_int ; 5
...
SECTION .rodata
_C4 db 5
Thanks for reminding me.