NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: paml27 on April 07, 2020, 12:36:52 AM
-
In the .data section I defined a struc:
%define O_RDWR 00000002
struc mq_attr
.mq_flags: resd 1
.mq_maxmsg: resd 1
.mq_msgsize: resd 1
.mq_curmsgs: resd 1
endstruc
mq_attributes:
istruc mq_attr
at mq_attr.mq_flags, dd O_RDWR
at mq_attr.mq_maxmsg, dd 100
at mq_attr.mq_msgsize, dd 1000 ;656
at mq_attr.mq_curmsgs, dd 0
iend
In the text (code) section, I followed the directions in the 2.13.02 manual to examine the structure elements, but only the third element shows correctly:
194 mov rax,[mq_attributes+mq_attr.mq_flags]
rax 0x6400000002 429496729602
195 mov rax,[mq_attributes+mq_attr.mq_maxmsg]
rax 0x3e800000064 4294967296100
196 mov rax,[mq_attributes+mq_attr.mq_msgsize]
rax 0x3e8 1000
197 mov rax,[mq_attributes+mq_attr.mq_curmsgs]
rax 0x6e616c6300000000 7953757589370568704
Did I calculate the offsets correctly (e.g. mq_attributes+mq_attr.mq_flags)? If so, why do elements 1, 2 and 4 not show correctly?
Thanks very much.
-
Since the structure fields are DWORDs, you should use, for example:
; the upper 32 bits will be zeroed!
mov eax,[mq_attributes+mq_attr.mq_flags]
-
Thanks, Frederico. That turned out to be the right answer. I'm surprised it didn't zero-extend into rax.
-
Is there some magic going on under the hood which explains this? I'm just curious as to why the number being moved into rax wouldn't just put it into rax proper. This almost looks like some sort of signedness issue to me based on the values that were in there in the example the OP showed, but I'm not sure why this would be the case.
-
Is there some magic going on under the hood which explains this? I'm just curious as to why the number being moved into rax wouldn't just put it into rax proper. This almost looks like some sort of signedness issue to me based on the values that were in there in the example the OP showed, but I'm not sure why this would be the case.
The almighty chief engineer at AMD,years ago, conjured some demon and, since then, the x86-64 standard dictates every time you change the lower 32 bits of R?? register, the upper DWORD will be zeroed (read the holy Intel SDM and AMD CPU manuals)..
-
x86-64 standard dictates every time you change the lower 32 bits of R?? register, the upper DWORD will be zeroed
Actually, this is not accurate. Bits 32..63 of GPR will be zeroed only when the operand size is 32.
MOV RAX,0x123456789ABCDEF0h
; RAX is now 0x123456789ABCDEF0h, nothing is zeroed, though the lower 32 bits are changed.
MOV EAX,0x12345678
; RAX is now 0x0000000012345678, upper DWORD is zeroed.
The only reason is performance: removing internal dependencies in CPU microcode, prefectly explained at StackOverflow (https://stackoverflow.com/questions/11177137/why-do-x86-64-instructions-on-32-bit-registers-zero-the-upper-part-of-the-full-6)