NASM - The Netwide Assembler
NASM Forum => Example Code => Topic started by: zoh90 on January 26, 2012, 06:05:22 PM
-
Hi!
I would like to know how do you interface fortran with assembly.
For example I have the following code in fortran:
program testassembly
implicit none
integer summ
write(6,*)summ(3,4)
end
integer function summ(a,b)
implicit none
integer a,b
summ=a+b
end
Is there a way that I can write my `summ` function in assembly and then call it from the fortran code with a and b? If yes what would be the way?
Thanks.
Bence
~
-
Well... yeah, you should be able to do that. You may need to help me out with the Fortran. I helped a member named Michael do something like this - a couple of years ago - but I'm not sure I remember just how it went...
As I recall, Fortran can use 32-bit integers or 64-bit integers, and this is decided on the command line, not in the code. Do you know which you need? Can you show us the command line (or makefile) you're using for the Fortran part?
As I recall, Fortran always passes the address(es) of the variable(s), rather than the variable(s) themselves. Does that sound right?
As I recall, Fortran uses a trailing underscore on external variables/functions. Does that sound right?
What we were doing was for Fortran under Linux. Are you using Linux, or are we going to have to figure out Windows, too? I hope this is for a 32-bit system - I don't know much about 64-bit!
I'm thinking, if we're working with 32-bit integers, you may want something like this...
global summ_
summ_:
push ebp
mov ebp, esp
mov eax, [ebp + 8] ; address of first parameter
mov ecx, [ebp + 12] ; address of second parameter
mov eax, [eax] ; first parameter
mov ecx, [ecx] ; second parameter
add eax, ecx ; add 'em up
; return result in eax?
mov esp, ebp
pop ebp
ret
That's untested, and probably not right. Can you refresh my memory at all? How much assembly language do you already know? Do you understand what I've done above?
I'm sure we can figure this out, but it'll probably take a few posts back and forth...
edit: here's that other thread...
http://forum.nasm.us/index.php?topic=397.msg1210#msg1210
Best,
Frank
-
Thanks for your fast answer.
Well it can be decide wheather I wanna use 32 or 64 bit integers, I just declare them as integer*8 or integer*4 and can also set the -i8 flag to the compiler for default 64bit integers. But usually in my calculations, we use 64 bit architecture.
Yes, you remember right, fortran always passes the variables by reference, so the address of them instead of their values, which sometimes can be very useful.
But i think that might cause problems when you want to interface it with an assembly source.
You were also right with the external functions.
I am using Arch Linux.
I know a little bit of assembly, as I am studying electrical engeneering, so I understood what you did.
My code now is:
thats fortran.f:
program testassembly
implicit none
integer*8 summ,a,b
a=3
b=4
write(6,*)summ(a,b)
end
thats to compile:
nasm -f elf64 summ.asm
gfortran -o run summ.o fortran.f -g
and thats assembly:
global summ_
summ_:
push rbp
mov rbp, rsp
mov rax, [rbp + 8] ; address of first parameter
mov rcx, [rbp + 16] ; address of second parameter
mov rax, [rax] ; first parameter
mov rcx, [rcx] ; second parameter
add rax, rcx ; add 'em up
; return result in eax?
mov rsp, rbp
pop rbp
ret
I have search for 64 bit arch. and figured out that the registers (eax,ebx etc...) were renamed to rax,rbx so just a change in the first letter to r.
If I do ./run it gives me segmentation fault all the time. I think something is wrong with the address, so I`m asking for your help guys!
Thank you.
Bence
-
As I mentioned, I don't know much about 64-bit code, except that I know they've changed the rules. Instead of passing parameters on the stack, parameters are in rdi, rsi, rdx, rcx, r8, and r9 (if there are more, they go on the stack, I think). So "probably", what you need is more like:
mov rax, [rdi]
add rax, [rsi]
ret
There are requirements for stack alignment too, I think - I'm not sure if we run into that in this case. There's documentation at http://www.x86-64.org which might help...
A minor nit... if parameters were still on the stack, we'd have a 64-bit return address plus a 64-bit rbp, so the first parameter would be at [rbp + 16]... but I don't think that's how they do it.
I see you've used the "-g" switch to gfortran. Nasm's "-g" switch also enables debugging info, but in the default "stabs" format. "-F dwarf" would add "dwarf" format debugging info, which might help...
Maybe someone with 64-bit experience would have further ideas...
Best,
Frank