Author Topic: A 64-bit Nasm assignment procedure; set(val,var)?  (Read 2564 times)

Offline mjrice

  • Jr. Member
  • *
  • Posts: 18
A 64-bit Nasm assignment procedure; set(val,var)?
« on: June 22, 2018, 01:44:05 AM »
Callable from 64-bit Linux, gfortran or gcc (pick one). Is there a thread for function/procedure code contributions?

To keep it simple, val is a literal real or integer, var a variable.

global set_

set_:

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2373
  • Country: us
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #1 on: June 24, 2018, 02:00:09 AM »
Dunno. Maybe something like...
Code: [Select]
global set_ ; trailing underscore for fortran?
set_:
; align stack?
mov rax, [rdi] ; dereference val?
mov [rsi], rax ; put it in var?
; restore stack?

Did you get your other problem solved?

Best,
Frank


Offline mjrice

  • Jr. Member
  • *
  • Posts: 18
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #2 on: September 30, 2018, 03:42:16 PM »
Dunno. Maybe something like...
Code: [Select]
global set_ ; trailing underscore for fortran?
set_:
; align stack?
mov rax, [rdi] ; dereference val?
mov [rsi], rax ; put it in var?
; restore stack?

Did you get your other problem solved?

Best,
Frank

Hi, Frank.

If you mean from years ago, when you helped me successfully implement assembly code for Joseph Weisenbaum's SLIP? Yes, I'm that "Michael."

I SLIP-ed up. When I posted back in June I thought I'd receive an email notification that somebody had posted a reply. Since I never did, I just waited. Sorry about that.

Back in June I was thinking of recoding the SLIP NASM functions, formerly written for 32 bit, for a 32 bit gfortran, to run in 64 bit. I'll now continue with that but would first like to verify that the code I archived will still run in a 32 bit environment, which I no longer have. Is there a way to make 32 bit NASM code acceptable to a 64 bit environment? Or maybe a 64 bit environment to emulate 32 bit?

Michael

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2373
  • Country: us
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #3 on: October 01, 2018, 06:43:34 AM »
Hi Michael,

By "other problem" I meant the "loc" function. I'm afraid I don't remember "SLIP".
 Good to see you still around, though!

To get emails about replies, you've got to check the "notify" box. Click on "unnotify" to turn it off if the volume becomes overwhelming.

32-bit code should run in a 64-bit system, provided that any libraries you link to are present. You might need to install "gcc multilibs" or some such. 32-bit NASM code itself shouldn't be a problem. You'll need to tell ld "-m elf_i386". "-m32" for gcc, to get 32-bit code. Dunno about gfortran.

Best,
Frank


Offline mjrice

  • Jr. Member
  • *
  • Posts: 18
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #4 on: October 01, 2018, 07:18:43 PM »
Hello, Frank.

The SLIP work was seven or more years ago. I know that for sure because I dated the dvd (2011) on which I archived it. Long time. Good to see you're still around too. You were big help.

Back in June it seemed I'd have to use fortran's loc function instead of writing my own madov (SLIP machine address) function in NASM.  I'll be looking into that again.

Thanks for explaining the "Notify" function. Checked.

Just before I returned to the forum today I found this on the web:

dnf install gfortran-multilib
gfortran -m32 foo.f

And away we go...

Michael






Offline mjrice

  • Jr. Member
  • *
  • Posts: 18
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #5 on: October 10, 2018, 02:00:24 AM »
I added two commands to set and restore the stack, then commented them out.

Variable k gets changed from 0 to 13 in both versions, but also get the same seg fault with both. How does one
return to Fortran from a subroutine call?

Michael

*****************************

global set_ ; trailing underscore for fortran?
set_:
; align stack?
push rbp       ; <== added
mov rax, [rdi] ; dereference val?
mov [rsi], rax ; put it in var?
; restore stack?
pop rbp        ; <== added
ret

      external :: set
      integer k
      k=0
      call set(13,k)
      print *, k
      end

*************************************

[mrice@localhost ~]$ nasm -f elf64 set.asm -o set.o && gfortran settest.f90 set.o && ./a.out
          13

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
Segmentation fault (core dumped)
[mrice@localhost ~]$

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2373
  • Country: us
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #6 on: October 10, 2018, 03:48:58 AM »
I ASSume that we return to fortran with "ret". How else?

The fact that your code prints "13" indicates that the "set_" worked. It also indicates that we returned to fortran  before the segfault occurred. I have no idea what's happening here.

Best,
Frank


Offline mjrice

  • Jr. Member
  • *
  • Posts: 18
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #7 on: October 10, 2018, 11:02:16 AM »
Makes sense.

I fixed it by adding some gfortran flags I used the last time, but wasn't sure I needed them for true 64-bit.

[mrice@localhost ~]$ nasm -f elf64 set.asm -o set.o && gfortran -fdefault-integer-8 -fdefault-real-8 -fno-range-check settest.f90 set.o && ./a.out
                   13
[mrice@localhost ~]$

Michael




Offline mjrice

  • Jr. Member
  • *
  • Posts: 18
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #8 on: October 10, 2018, 11:19:41 AM »
I have at least 13 of these conversions of 32-bit NASM subprograms to 64-bit for use with Fortran to do that may prove useful for anyone doing something similar. I now have two threads, this one and another, "Running i386 on x86-64" or something like that. Should I just continue on this thread, the one I started back in June, or another one all together in a different category?

Michael   

Offline mjrice

  • Jr. Member
  • *
  • Posts: 18
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #9 on: October 10, 2018, 04:53:25 PM »
Another setter subroutine, strind(var,var-addr). Tested ok.

Anything troubling about the asm code? I held my breath when I ran it.

Michael

global strind_
strind_:
mov rax, [rdi] ; dereference val?
push rbp
mov rbp, [rsi] ; dereference addr of var?
mov [rbp], rax ; put val where rbp points?
pop rbp
ret

      external :: strind
      integer k
      k=0
      call strind(13,loc(k))
      print *, k
      end

[mrice@localhost ~]$ nasm -f elf64 strind.asm -o strind.o && gfortran -fdefault-integer-8 -fdefault-real-8 -fno-range-check strindtest.f90 strind.o && ./a.out
                   13
[mrice@localhost ~]$


Offline dreamCoder

  • Full Member
  • **
  • Posts: 106
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #10 on: October 11, 2018, 02:25:04 AM »
I added two commands to set and restore the stack, then commented them out.

Variable k gets changed from 0 to 13 in both versions, but also get the same seg fault with both. How does one
return to Fortran from a subroutine call?

Michael

*****************************

global set_ ; trailing underscore for fortran?
set_:
; align stack?
push rbp       ; <== added
mov rax, [rdi] ; dereference val?
mov [rsi], rax ; put it in var?
; restore stack?
pop rbp        ; <== added
ret


      call set(13,k)
*************************************

Segmentation fault - invalid memory reference.

I know nothing about FORTRAN but at this line, you're using dereferencing instead of taking direct values from the register?

should be
    mov rax,rdi   ;13 is a direct immediate
instead of
    mov rax,[rdi]? ;13 is an address

Or I maybe wrong altogether.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2373
  • Country: us
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #11 on: October 11, 2018, 03:24:07 AM »
Hi dreamCoder.

Thanks for jumping in here! If rdi holds the value 13, you are certainly correct. My understanding was that fortran always passes parameters "by reference". If I misunderstand that, it would explain a lot. However, I don't think fortran would be printing 13 at all (?).

In "strind_", Michael dereferences the value twice, and this seems to work. We don't use rbp as the usual "stack frame pointer", but this shouldn't be a problem.

I don't seem to have gfortran on this machine, so I can't try this stuff. I may get up the ambition to install it, but haven't yet. I'm old and tired and burnt out and a little depressed. My memory is all shot and my ambition is worse. Sorry.

I suppose multiple threads - with meaningful names - would make it easier for people to find this stuff in the future. I dunno...

Best,
Frank


Offline mjrice

  • Jr. Member
  • *
  • Posts: 18
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #12 on: October 11, 2018, 04:16:11 AM »
Yes, Fortran passes by reference.

Frank, what would be a conventional way to do the necessary dereferencing?

Michael

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2373
  • Country: us
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #13 on: October 11, 2018, 05:03:46 AM »
Code: [Select]
mov rdi, [rdi]
... would do it. It's okay to use the same register... Or a different register...

Best,
Frank


Offline dreamCoder

  • Full Member
  • **
  • Posts: 106
Re: A 64-bit Nasm assignment procedure; set(val,var)?
« Reply #14 on: October 11, 2018, 11:49:52 AM »
Hi dreamCoder.

Thanks for jumping in here! If rdi holds the value 13, you are certainly correct. My understanding was that fortran always passes parameters "by reference". If I misunderstand that, it would explain a lot. However, I don't think fortran would be printing 13 at all (?).

In "strind_", Michael dereferences the value twice, and this seems to work. We don't use rbp as the usual "stack frame pointer", but this shouldn't be a problem.

I don't seem to have gfortran on this machine, so I can't try this stuff. I may get up the ambition to install it, but haven't yet. I'm old and tired and burnt out and a little depressed. My memory is all shot and my ambition is worse. Sorry.

I suppose multiple threads - with meaningful names - would make it easier for people to find this stuff in the future. I dunno...

Best,
Frank
Ok then. I am completely clueless on FORTRAN. But I wonder where in memory the value is maintained? Where does RDI point to? Because sending an immediate 13 as argument doesn't reveal much about its storage (static, heap, stack etc). Anyway this is a good revelation for me about a new calling convention.