NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: mjrice on June 06, 2018, 03:30:23 PM
-
I ask the subject line question because, as I understand it, function parameters are located in different registers depending upon whether they are ints or floats. How would a function, maddr, know where to get its parameter, since it must return the machine addresses of both ints and floats? And Fortran passes by reference, seemingly a pointer to a pointer, i.e., pointer to a machine address. Is there some flag to determine this?
-
Which OS, and which bit level? Pointers are considered integers, return vectors are rax for the first one
Linux/Unix and win64 have abi to follow for the pattern of the registers and they are both different.
32 bit follow a c based convention.
in the 64 bit Linux /Unix function call, rax is the count of floats put in xmm0 to xmm7. The other arguments have a specific map.
http://refspecs.linuxbase.org/elf/x86_64-abi-0.21.pdf (http://refspecs.linuxbase.org/elf/x86_64-abi-0.21.pdf) pg 19 has other description.
Windows I do not have any information.
You sound like you are loading FORTRAN code some where and calling the function from assembly. That would follow the calling convention of the OS.
-
Looks like this is going to be a short thread.
I haven't programmed any fortran or nasm in at least ten years and coming back to it after that long and from 32-bit to 64-bit has been a bit overwhelming. But I persisted. The problem I was having was caused by my accidentally misdeclaring the maddr function in my fortran code as real, making me think the maddr function was at fault. See below for the code for the maddr function plus two fortran examples of its usage compared with fortran's loc function for both an x86-64 integer and an x86-64 real. If you see any slipups, please let me know.
Michael
Nasm machine address function:
global maddr_
section .text ;return the (64-bit integer) machine address of a variable
maddr_:
push rbp
mov rax, rdi
pop rbp
ret
=======Tested with loc in gfortran=======
Machine address of x86-64 integer variable
integer, external :: maddr
integer i,j
integer k
k=33
i=loc(k)
j=maddr(k)
write(*,*) i,j
end
nasm -f elf64 maddr.asm -o maddr.o && gfortran maddrtest.f90 maddr.o && ./a.out
2099635748 2099635748
Machine address of x86-64 real variable
integer, external :: maddr
integer i,j
real c
c=17.5
i=loc(c)
j=maddr(c)
write(*,*) i,j
end
nasm -f elf64 maddr.asm -o maddr.o && gfortran maddrtest.f90 maddr.o && ./a.out
1430344396 1430344396
-
What I think you want in that assembly code: You have stated that is returning address to a variable?
;mov rax, rdi
;mov xmm0, [rax] ;to put the value some where
;or
mov xmm0, [rdi] ; Where floats are put
mov rax, 1 ; the count of reals in xmm0 to xmm7, possible count of 8
return
This would return the value and not the address.
-
Sorry to be so tardy with a reply. I don't recall seeing your post in my email, so I may have accidentally deleted it.
I found that if I run the code I posted multiple times I can get identical negative addresses for both the loc function and the maddr function.
Also, if I just code
write(*,*) loc(k), maddr(k)
instead of putting the returned addresses in variables i and j to be written, the two resulting addresses no longer match.
Going to have to do some digging.