Author Topic: Interface asm with fortran  (Read 21414 times)

Offline zoh90

  • Jr. Member
  • *
  • Posts: 2
Interface asm with fortran
« 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
~                   

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Interface asm with fortran
« Reply #1 on: January 26, 2012, 07:26:38 PM »
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...

Code: [Select]
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

« Last Edit: January 26, 2012, 08:47:59 PM by Frank Kotler »

Offline zoh90

  • Jr. Member
  • *
  • Posts: 2
Re: Interface asm with fortran
« Reply #2 on: January 27, 2012, 09:59:50 AM »
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


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Interface asm with fortran
« Reply #3 on: January 27, 2012, 05:05:28 PM »
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:

Code: [Select]
    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