Author Topic: Rotate 64-bit word  (Read 28521 times)

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 171
  • Country: br
Re: Rotate 64-bit word
« Reply #15 on: June 07, 2021, 03:34:31 PM »
Not sure what you mean by, "why use a stack frame?" But, from Joseph Weizenbaum's "Symetric List Processor" document:

4. CONT(A)       are functions which have as their values the
     and             information stored in the word the machine
5. INHALT(A)   address of which appears as an integer in A.

Here's CONT:
(Note: NOT from the Weizenbaum document, which only supplies the fortran.)

global cont_

section .text ;return the (64-bit real) contents of a  (32-bit address)

cont_:
  push  ebp
  mov   ebp, esp
  mov   eax, [ebp+8]
  mov   eax, [eax]
  pop   ebp
  fld qword  [eax]
;  mov   edx, [eax+4]
;  mov    eax, [eax]
   ret

As you can see, the code is identical to INHALT except for how the result is returned.

Fortran assumes an undeclared variable or function name to be integer if it begins with any letter of "ijklmn", otherwise assumes it as real. Contradicions arise with:

 I=C
 I=D(_)
 C=I
 C=I(_)

-mjrice

I mean... The prologue (push ebp/mov ebp,esp) and epilogue (pop ebp) aren't necessary. The same function can be implemented as:
Code: [Select]
struc cont_stk
        resd 1    ; return address
.ptr:   resd 1
endstruc

  global cont_
cont_:
  mov eax,[esp+cont_stk.ptr]  ; Get the pointer from stack
  mov eax,[eax]       ; Get pointer pointed by EAX
  fld qword [eax]      ; Get double pointed by the second pointer.
  ret

Assuming this is correct... Why 2 indirections?
« Last Edit: June 07, 2021, 03:38:18 PM by fredericopissarra »

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 171
  • Country: br
Re: Rotate 64-bit word
« Reply #16 on: June 07, 2021, 03:43:29 PM »
If A is double (REAL*8?), then I assume the stack would be, after que call:

Code: [Select]
; ESP+4 -> A (8 bytes)
; ESP -> ret addres
struc cont_stk
    resd 1
.A: resq 1
endstruc

  global count_:
count_:
  fld qword [esp+count_stk.A]
  ret

Or... If A is a pointer:

Code: [Select]
; ESP+4 -> ptr A (4 bytes)
; ESP -> ret addres
struc cont_stk
       resd 1
.Aptr: resd 1
endstruc

  global count_:
count_:
  mov eax,[esp+count_stk.Aptr]
  fld qword [eax]
  ret

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #17 on: June 08, 2021, 02:13:02 AM »
All fortran function and subroutine args are pointers. One can change their values inside a function.

procedure swap(a, b)
    temp : Integer;
begin
    temp := a;
    a := b;
    b := temp;
end swap;

The struc is interesting. I understand it's done with a macro and a recent addition to nasm, not built into the compiler from the ground up. I first encountered macros in Lisp back in the '70s. Not being aware of this macro's existence could be the reason they weren't used in this code. I wrote some of the simple code, Frank did the more complicated functions and subroutines, four or more years ago. It works very well. What I'm doing now is trying to add to that, this first followed by three more.

From what I've read about a struc, one needs to be instantiated before use. I'm confused, where in the code does this occur?

-mjrice

struc rot8left64_stk
    resd  1   ; return address.
.lo: resd  1
.hi: resd  1
endstruc

  section .text

  global rot8left64_
rot8left64_:
  mov   eax, [esp+rot8left64_stk.lo]
  mov   edx, [esp+rot8left64_stk.hi]
  mov   ecx, eax
  shld  eax, edx, 8
  shld  edx, ecx, 8
  ret












Offline fredericopissarra

  • Full Member
  • **
  • Posts: 171
  • Country: br
Re: Rotate 64-bit word
« Reply #18 on: June 08, 2021, 02:52:37 PM »
All fortran function and subroutine args are pointers. One can change their values inside a function.

procedure swap(a, b)
    temp : Integer;
begin
    temp := a;
    a := b;
    b := temp;
end swap;
Interesting...

Quote
The struc is interesting. I understand it's done with a macro and a recent addition to nasm, not built into the compiler from the ground up.

Nope... struc is always there since the first versions of NASM. It's not a MACRO, mas macro too are constructs NASM has -- since the first versions...

Quote
From what I've read about a struc, one needs to be instantiated before use. I'm confused, where in the code does this occur?
If you want to create an instance of a struct... Not the case here. I am using only to avoid stack offset calculations.

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #19 on: June 08, 2021, 04:47:25 PM »
Thanks for the information.

I removed my INHALT function, renamed your function by adding an "i" to the  front, and reran it (same input). Segmentation fault is gone but the result, after to two lines of input and output, is 5 characters similar to ??*?? (the asterisk replacing a character missing from my keyboard. When I copied the characters and pasted them into a new text file they got printed on the right side of the page. Expand the page rightward and they remain on the right of the page.

Apparently the data isn't getting where it's supposed to go.

-mjrice

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 171
  • Country: br
Re: Rotate 64-bit word
« Reply #20 on: June 08, 2021, 06:51:19 PM »
Thanks for the information.

I removed my INHALT function, renamed your function by adding an "i" to the  front, and reran it (same input). Segmentation fault is gone but the result, after to two lines of input and output, is 5 characters similar to ??*?? (the asterisk replacing a character missing from my keyboard. When I copied the characters and pasted them into a new text file they got printed on the right side of the page. Expand the page rightward and they remain on the right of the page.

Apparently the data isn't getting where it's supposed to go.

-mjrice

If it's true all functions receive pointers as arguments then the code is wrong... It should be (with that info):

Code: [Select]
struc rot8left64_stk
      resd 1
.ptr: resd 1
endstruc

  global rot8left64_
rot8leff64_:
  mov   eax,[esp+rot8left64_stk.ptr]  ; get pointer

  mov   edx, [eax+4]   ; get QWORD from pointer.
  mov   eax, [eax]

  mov   ecx, eax
  shld  eax, edx, 8
  shld  edx, ecx, 8
  ret
« Last Edit: June 08, 2021, 06:53:47 PM by fredericopissarra »

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #21 on: June 08, 2021, 07:35:22 PM »
mrice@debian10-uni:~/work$ nasm -f elf krot8left64.asm -o krot8left64.o
krot8left64.asm:8: error: symbol `rot8left64_stk.ptr' undefined
mrice@debian10-uni:~/work$

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #22 on: June 08, 2021, 07:50:07 PM »
Do you see something i missed?

mrice@debian10-uni:~/work$ gfortran test.o krot8left64.o -o test
/usr/bin/ld: test.o: in function `MAIN__':
test.f95:(.text+0x115): undefined reference to `krot8left64_'
collect2: error: ld returned 1 exit status
mrice@debian10-uni:~/work$

  100 FORMAT(A8)
      READ(*,100) LW
      WRITE(*,100) LW
      MW=KROT8LEFT64(LW)
      WRITE(*,100) MW
      END

struc krot8left64_stk
      resd 1
.ptr: resd 1
endstruc

  global krot8left64_
krot8leff64_:
  mov   eax,[esp+krot8left64_stk.ptr]  ; get pointer

  mov   edx, [eax+4]   ; get QWORD from pointer.
  mov   eax, [eax]

  mov   ecx, eax
  shld  eax, edx, 8
  shld  edx, ecx, 8
  ret



 

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 171
  • Country: br
Re: Rotate 64-bit word
« Reply #23 on: June 08, 2021, 08:37:51 PM »
Code: [Select]
  bits 32      ; to be sure.

struc krot8left64_stk
      resd 1
.ptr: resd 1
endstruc

  section .text  ; This was missing.

  global krot8left64_
krot8leff64_:
  mov   eax,[esp+krot8left64_stk.ptr]  ; get pointer

  mov   edx, [eax+4]   ; get QWORD from pointer.
  mov   eax, [eax]

  mov   ecx, eax
  shld  eax, edx, 8
  shld  edx, ecx, 8
  ret

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #24 on: June 08, 2021, 10:29:54 PM »
Check line 7 of the new code you gave me.

-------------------------------
struc rot8left64_stk
      resd 1
.ptr: resd 1
endstruc

  global rot8left64_
rot8leff64_:
  mov   eax,[esp+rot8left64_stk.ptr]  ; get pointer

  mov   edx, [eax+4]   ; get QWORD from pointer.
  mov   eax, [eax]

  mov   ecx, eax
  shld  eax, edx, 8
  shld  edx, ecx, 8
  ret

Fixed it! The "bits 32" line doesn't matter. Same answer, with and without. I'd never seen it before, thought it was left in accidentally.


mrice@debian10-uni:~$ cd work
mrice@debian10-uni:~/work$ nasm -f elf krot8left64.asm -o krot8left64.o
mrice@debian10-uni:~/work$ gfortran -c -fdefault-integer-8 -fdefault-real-8 -fno-range-check test.f95 -o test.o
mrice@debian10-uni:~/work$ gfortran test.o krot8left64.o -o test
mrice@debian10-uni:~/work$ ./test
 ABCDEFG
 ABCDEFG
G ABCDEF
mrice@debian10-uni:~/work$

Looking better. Where to from here?

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #25 on: June 09, 2021, 01:26:16 AM »
I first printed out the characters formed by eax and edx before any shld. They matched the input.

I then printed out the integer formed by eax and edx after the first shld, commenting out the second shld, just to check where we are at that point.

 5135868584534286407

4746454442412047

 G F E D B A b G

Reversed

G ABDEFG

I then wrote them out as charcters. They match, both missing the "C".

 ABCDEFG
 ABCDEFG
G ABDEFG

The "C" gets placed back in after the second shld.

Any thoughts?






Offline fredericopissarra

  • Full Member
  • **
  • Posts: 171
  • Country: br
Re: Rotate 64-bit word
« Reply #26 on: June 09, 2021, 01:49:44 AM »
Any thoughts?
Nope... I am not familiar with FORTRAN and not interested in the language since the compiler don't give me an optimized code (did some tests here). I'm sorry, but from now on, you're on your own...

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #27 on: June 09, 2021, 12:46:11 PM »
Thanks for trying.

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #28 on: June 12, 2021, 01:58:53 AM »
Not redy to give up, yet. If gfortran is the problem, might this give me a correct answer?


extern printf

section .text

global main

main:
    push ebp
    mov ebp, esp

    push msg
    call printf

    push msg
    call rot8left64
;
;  a way to move result, in eax & edx, to ans?
;
    push ans   
    call printf
    add esp, 8

    leave
    ret

section .data
     msg     dq  ' ABCDEFG'
     ans     dq

---------------------------------------

  global rot8left64
rot8left64:
  mov   eax,[esp+rot8left64_stk.ptr]  ; get pointer

  mov   edx, [eax+4]   ; get QWORD from pointer.
  mov   eax, [eax]

  mov   ecx, eax
  shld  eax, edx, 8
  shld  edx, ecx, 8
  ret

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 136
  • Country: gb
    • GPUZoo
Re: Rotate 64-bit word
« Reply #29 on: June 12, 2021, 05:52:23 AM »
Shouldn't

  shld  eax, edx, 8
  shld  edx, ecx, 8

actually be

  shld  eax, edx, 8
  shr   edx,8
  shld  edx, ecx, 8

?

It seems to me that after the first shld, the low byte of edx is all zero. So you are inserting a zero byte into your result.
My graphics card database: www.gpuzoo.com