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

#### fredericopissarra

• Full Member
• Posts: 156
• Country:
##### 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 1endstruc  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 »

#### fredericopissarra

• Full Member
• Posts: 156
• Country:
##### 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 addresstruc cont_stk    resd 1.A: resq 1endstruc  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 addresstruc cont_stk       resd 1.Aptr: resd 1endstruc  global count_:count_:  mov eax,[esp+count_stk.Aptr]  fld qword [eax]  ret`

#### mjrice

• Jr. Member
• Posts: 40
##### 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
.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

#### fredericopissarra

• Full Member
• Posts: 156
• Country:
##### 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.

#### mjrice

• Jr. Member
• Posts: 40
##### 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

#### fredericopissarra

• Full Member
• Posts: 156
• Country:
##### 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 1endstruc  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 »

#### mjrice

• Jr. Member
• Posts: 40
##### 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\$

#### mjrice

• Jr. Member
• Posts: 40
##### 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)
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

#### fredericopissarra

• Full Member
• Posts: 156
• Country:
##### 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 1endstruc  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`

#### mjrice

• Jr. Member
• Posts: 40
##### 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?

#### mjrice

• Jr. Member
• Posts: 40
##### 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?

#### fredericopissarra

• Full Member
• Posts: 156
• Country:
##### 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...

#### mjrice

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

#### mjrice

• Jr. Member
• Posts: 40
##### 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

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

#### debs3759

• Global Moderator
• Full Member
• Posts: 126
• Country:
##### 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