NASM - The Netwide Assembler

NASM Forum => Programming with NASM => Topic started by: mjrice on June 01, 2021, 07:15:21 PM

Title: Rotate 64-bit word
Post by: mjrice on June 01, 2021, 07:15:21 PM
Hi,

How would I rotate the other dword of qword the same 8 bits?

mov eax, [eax]?

-mjrice

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

global lanorm_

section .text ;rotation of 64-bit word

lanorm_:
  push   ebp
  mov   ebp, esp
  mov   eax, [ebp+8]   ;eax <- addr of qword
  pop   ebp
  mov eax, [eax+4]   ;eax <- contents of hi dword of qword
  rol eax, 8
  mov   edx, 0
  ret

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

mrice@debian10-uni:~/work$ nasm -f elf lanorm.asm -o lanorm.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 lanorm.o -o test
mrice@debian10-uni:~/work$ ./test
ABCDEFGH
ABCDEFGH
HEFG
mrice@debian10-uni:~/work$
Title: Re: Rotate 64-bit word
Post by: mjrice on June 04, 2021, 02:24:32 PM
Figured it out for myself. Trying to get nasm reoriented after a two year absence.

Working with 64-bit integers and reals in 32 bit nasm. The following asm code should (I hope) count the blanks in one of the dwords of  a double dword argument ("ABCD##GH" -> 2). But there seems to be some problem with my data statement (see below).

--mjrice

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

global lcount_

section .text ;return blank count in hi-end dw

section .data
blank   db 32
k1   dw 0   ;byte index
k2   dw 0   ;blank count

lcount_:
  push   ebp
  mov   ebp, esp
  mov   eax, [ebp+8]   ;eax <- addr of qword
nextbyte:
  cmp   k1, 4
  jz   finished
  cmp   [eax+k1], blank
  jz   add1
  inc   k1   ;increment byte index
  jmp   nextbyte
add1:
  inc   k2   ;increment byte-count
  inc   k1   ;increment byte index
  jmp   nextbyte
finished:
  pop   ebp
  mov   eax, k2
  mov   edx, 0
  ret

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

mrice@debian10-uni:~/work$ nasm -f elf lcount.asm -o lcount.o
lcount.asm:7: error: label or instruction expected at start of line
lcount.asm:8: error: label or instruction expected at start of line
mrice@debian10-uni:~/work$
Title: Re: Rotate 64-bit word
Post by: fredericopissarra on June 04, 2021, 03:16:02 PM
Rotate QWORD 8 bits to the left in i386 mode:

Code: [Select]
  bits  32

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
Title: Re: Rotate 64-bit word
Post by: mjrice on June 05, 2021, 02:55:14 AM
These two lines are what the compiler is complaining about.

k1   dw 0   ;byte index
k2   dw 0   ;blank count

I don't understand what that has to do with a qword as I'm not using any in my code.

-mjrice


Title: Re: Rotate 64-bit word
Post by: mjrice on June 05, 2021, 12:58:19 PM
To fredericopissarra:

Thanks!

I misunderstood your last message, that you weren't addressing my compiler problem but offering a way to rotate a qword in 32-bit environment, a replacement for my first lanorm effort?

My usual input to lanorm is a 64-bit 8-char word, composed of some number of blanks on the left, possibly 0, the rest being non-blank character(s). It's task to rotate the non-blank characters all the way to the left, followed by all the blank characters (left-justification).  So the number of blanks determine the number of 8-bit rotates.  Thus my most recent post of the function lcount, which counts blanks in a dword.

--mjrice



Title: Re: Rotate 64-bit word
Post by: mjrice on June 06, 2021, 01:57:44 AM
mrice@debian10-uni:~$ cd work
mrice@debian10-uni:~/work$ nasm -f elf rot8left64.asm -o rot8left64.o
rot8left64.asm:11: error: symbol `rot8left64_stk.lo' undefined
rot8left64.asm:12: error: symbol `rot8left64_stk.hi' undefined
mrice@debian10-uni:~/work$

The code:

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

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

-mjrice

Title: Re: Rotate 64-bit word
Post by: fredericopissarra on June 06, 2021, 12:10:07 PM
sorry. The structure is defined as:

Code: [Select]
struc rot8left64_stk
      resd 1
.lo:  resd 1
.hi:  resd 1
endstruc
Title: Re: Rotate 64-bit word
Post by: mjrice on June 06, 2021, 02:33:15 PM
I added inhalt.asm to my fortran to deal with its fussiness about un-declared integer and real variables and functions, your rot8left64,asm function being "real" to fortran and the receiver variable (MW) in my main program being an "integer." Discrimination!? But there's still a linking problem (see bottom output).

-mjrice

-----------------TEST.F95----------------------

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

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

global inhalt_

section  .text ;return contents given the addr of a 64-bit integer

inhalt_:
  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

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

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

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

mrice@debian10-uni:~$ cd work
mrice@debian10-uni:~/work$ nasm -f elf inhalt.asm -o inhalt.o
mrice@debian10-uni:~/work$ nasm -f elf rot8left64.asm -o rot8left64.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 inhalt.o rot8left64.o -o test
/usr/bin/ld: test.o: in function `MAIN__':
test.f95:(.text+0x115): undefined reference to `rot8left64_'
collect2: error: ld returned 1 exit status
mrice@debian10-uni:~/work$
Title: Re: Rotate 64-bit word
Post by: fredericopissarra on June 06, 2021, 03:16:56 PM
/usr/bin/ld: test.o: in function `MAIN__':
test.f95:(.text+0x115): undefined reference to `rot8left64_'
What this says to you?
Title: Re: Rotate 64-bit word
Post by: mjrice on June 06, 2021, 06:23:31 PM
MAIN_ is my fortran program, but I see no misspelling of ROT8LEFT64. What does it mean to you?

-mjrice
Title: Re: Rotate 64-bit word
Post by: mjrice on June 06, 2021, 06:40:56 PM
An afterthought: ROT8LEFT64 might be a procedure, not a function?

-mjrice
Title: Re: Rotate 64-bit word
Post by: fredericopissarra on June 06, 2021, 07:19:57 PM
An afterthought: ROT8LEFT64 might be a procedure, not a function?

-mjrice

Change:
Code: [Select]
  global rot8left64
rot8left64:
To:
Code: [Select]
  global rot8left64_
rot8left64_:
Title: Re: Rotate 64-bit word
Post by: mjrice on June 07, 2021, 01:15:54 AM
Hurray, this time it found the function, but got a segmentation error.

As requested:

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

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

mrice@debian10-uni:~$ cd work
mrice@debian10-uni:~/work$ nasm -f rot8left64.asm -o rot8left64.o
nasm:fatal: unrecognised output format `rot8left64.asm' - use -hf for a list
type `nasm -h' for help
mrice@debian10-uni:~/work$ nasm -f elf rot8left64.asm -o rot8left64.o
mrice@debian10-uni:~/work$ nasm -f elf inhalt.asm -o inhalt.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 rot8left64.o inhalt.o -o test
mrice@debian10-uni:~/work$ ./test
 ABCDEFG
 ABCDEFG

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

Backtrace for this error:
#0  0xb7cd974b
#1  0xb7cd884e
#2  0xb7f29d6b
#3  0x474449
Segmentation fault
mrice@debian10-uni:~/work$



Title: Re: Rotate 64-bit word
Post by: fredericopissarra on June 07, 2021, 01:59:14 PM
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0xb7cd974b
#1  0xb7cd884e
#2  0xb7f29d6b
#3  0x474449
Segmentation fault
mrice@debian10-uni:~/work$

I'm not familiar about fortran ABI. Strings, as I understood, are blocks of chars, not NUL terminated, with a hidden length argument attached. I can't find a reliable reference for mixing fortran/asm...

So, what, exactly this inhalt_ function is supposed to do? Why use a stack frame?
Title: Re: Rotate 64-bit word
Post by: mjrice on June 07, 2021, 03:25:11 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

 




 
Title: Re: Rotate 64-bit word
Post by: fredericopissarra 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?
Title: Re: Rotate 64-bit word
Post by: fredericopissarra 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
Title: Re: Rotate 64-bit word
Post by: mjrice 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











Title: Re: Rotate 64-bit word
Post by: fredericopissarra 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.
Title: Re: Rotate 64-bit word
Post by: mjrice 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
Title: Re: Rotate 64-bit word
Post by: fredericopissarra 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
Title: Re: Rotate 64-bit word
Post by: mjrice 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$
Title: Re: Rotate 64-bit word
Post by: mjrice 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



 
Title: Re: Rotate 64-bit word
Post by: fredericopissarra 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
Title: Re: Rotate 64-bit word
Post by: mjrice 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?
Title: Re: Rotate 64-bit word
Post by: mjrice 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?





Title: Re: Rotate 64-bit word
Post by: fredericopissarra 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...
Title: Re: Rotate 64-bit word
Post by: mjrice on June 09, 2021, 12:46:11 PM
Thanks for trying.
Title: Re: Rotate 64-bit word
Post by: mjrice 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
Title: Re: Rotate 64-bit word
Post by: debs3759 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.
Title: Re: Rotate 64-bit word
Post by: fredericopissarra on June 12, 2021, 01:46:45 PM
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.
The lower byte of EAX will be filled with the upper byte of EDX in the first SHLD. SHLD.

A small program to demonstrate:

Code: [Select]
  ; Using x86-64 because I don't have a i386 linux here.
  bits  64
  default rel

  section .rodata

hexdigits:
  db  "0123456789ABCDEF"
nl:
  db  `\n`

  section .text

  global _start
_start:

  mov  edx,0x01234567
  mov  eax,0x89abcdef

  push rax
  push rdx
  mov   eax,edx
  call  printhex
  mov   eax,[rsp+8]
  call  printhex

  call  printnl

  pop  rdx
  pop  rax

  call f

  push rax
  mov  eax,edx
  call printhex
  pop  rax
  call printhex

  call printnl

  mov  eax,60
  xor  edi,edi
  syscall

; Under test...
f:
  mov   ecx,eax
  shld  eax,edx,8     ; EAX << EDX << 8
  shld  edx,ecx,8     ; EDX << ECX << 8
  ret

printnl:
  mov  eax,1
  mov  edi,eax
  mov  edx,eax
  lea  rsi,[nl]
  syscall
  ret

printhex:
  mov  ebx,8

  rol  eax,4
.loop:
  push rax

  and  eax,0xf
  lea  rsi,[hexdigits+eax] 
  mov  eax,1
  mov  edi,eax
  mov  edx,eax
  syscall

  pop   rax

  rol   eax,4
  dec   ebx
  jnz   .loop

  ret
Title: Re: Rotate 64-bit word
Post by: mjrice on June 12, 2021, 02:24:34 PM
As I understand it (asterisk representing zero):

The 1st shld changes eax (" ABC") to "ABCD" leaving edx with "EFG*".

The 2nd shld changes edx ("EFG*") to "EFG " leaving ecx with "ABC*".

That is, if ecx holds a copy of eax's initial value (" ABC").

-mjrice
Title: Re: Rotate 64-bit word
Post by: fredericopissarra on June 12, 2021, 06:10:45 PM
As I understand it (asterisk representing zero):

The 1st shld changes eax (" ABC") to "ABCD" leaving edx with "EFG*".

The 2nd shld changes edx ("EFG*") to "EFG " leaving ecx with "ABC*".

That is, if ecx holds a copy of eax's initial value (" ABC").

-mjrice
Nope... as demonstrated by the code above, your "string" in EDX:EAX as 0x20414243:0x44454647, the first SHLD will get EAX as 0x45464720, and the second EDX as 0x41424344. So your "string" will be translated from " ABCDEFG" to "ABCDEFG ".
Title: Re: Rotate 64-bit word
Post by: mjrice on June 12, 2021, 07:39:19 PM
" ABCDEFG" to "ABCDEFG " happens to be exactly what it is supposed to do, move all the leading blanks, one by one, from left to right. That's why I needed to know how many leading blanks are in the qword. I thought I made that very clear.
Title: Re: Rotate 64-bit word
Post by: mjrice on June 12, 2021, 08:16:11 PM
The input to rot8left64, no exceptions (X=blank), A...H  represent alphanumeric characters.
"ABCDEFGH"
"XABCDEFG"
"XXABCDEF"
"XXXABCDE"
"XXXXABCD"
"XXXXXABC"
"XXXXXXAB"
"XXXXXXXA"





Title: Re: Rotate 64-bit word
Post by: debs3759 on June 12, 2021, 08:29:07 PM
I stand corrected. I have never used shld, so just looked it up. Didn't realise that shld eax,edx,8 only changes eax.
Title: Re: Rotate 64-bit word
Post by: fredericopissarra on June 13, 2021, 01:22:53 AM
The input to rot8left64, no exceptions (X=blank), A...H  represent alphanumeric characters.
"ABCDEFGH"
"XABCDEFG"
"XXABCDEF"
"XXXABCDE"
"XXXXABCD"
"XXXXXABC"
"XXXXXXAB"
"XXXXXXXA"
That's because there is something wrong with the calling convention you are using... AND I made a mistake... rotating the string to left as an uint64 is the same as rotating the chars to the right:
Code: [Select]
;  rot.asm
  bits  64
  default rel

  section .text

  global rot
rot:
  mov   eax,[rdi]
  mov   edx,[rdi+4]

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

  mov   [rdi],eax
  mov   [rdi+4],edx
  ret
Code: [Select]
/* test.c */
#include <stdio.h>

extern void rot( char * );

int main( void )
{
  char s[] = " ABCDEFG";

  printf( "%s\n", s );
  rot( s );
  printf( "%s\n", s );
}
Code: [Select]
$ nasm -felf64 -o rot.o rot.asm
$ cc -O2 -c -o test.o test.c
$ cc -o test test.o
$ ./test
 ABCDEFG
G ABCDEF
To rotate the chars to the left I should rotate to the right:
Code: [Select]
rot8left64_:
  mov  ecx,edx
  shrd  edx,eax,8
  shrd  eax,ecx,8
  ret
Title: Re: Rotate 64-bit word
Post by: mjrice on June 13, 2021, 03:49:50 AM
I'm trying to duplicate the code, and its execution, in my post from June 08, 2021, 10:29:54 PM, the one that gave G ABCDEFG. In that I compiled krot8left64.asm, eliminating the need for INHALT, so I must have changed your rot8left64.asm to krot8left64.asm, and its call from fortran to krot8left64, as below. But now the link step fails and I'm failing to see why. Your code is as it was in that post, except for the addition of the "K".  Do
you see a problem?

;;;;;;;;;;;;;;;;;;;;; 

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

;;;;;;;;;;;;;;;;;;;;;

  bits 32      ; to be sure.

struc krot8left64_stk
      resd 1
.ptr: resd 1
endstruc

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

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

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

;;;;;;;;;;;;;;;;;;;;;
mrice@debian10-uni:~$ nasm -f elf krot8left64.asm
mrice@debian10-uni:~$ gfortran -c -fdefault-integer-8 -fdefault-real-8 -fno-range-check test.f95 -o test.o
mrice@debian10-uni:~$ 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:~$
Title: Re: Rotate 64-bit word
Post by: mjrice on June 13, 2021, 01:33:49 PM
I was missing to "K" on one of the rot8left64's. Fixed.

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

The fortran:

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

  bits 32      ; to be sure.

struc krot8left64_stk
      resd 1
.ptr: resd 1
endstruc

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

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

  mov   ecx,edx
  shrd  edx,eax,8
  shrd  eax,ecx,8
  ret

Thanks to all.

-mjrice
Title: Re: Rotate 64-bit word
Post by: mjrice on June 13, 2021, 04:36:31 PM
Just after posting my previous message my Debian x86 Box went kaput on me, Will get it all back later today as I have backup on Dropbox. By the way, I'm doing this for fun. Have been at it since the late '70s when I implemented part of Weizenbaum's SLIP on a 16 bit IBM 1130 clone, later doing it again for 64-bit.  It's quite a surprising "app" for the early 1960s. Would be happy to share what I have with anyone interested. Will post an example when I get operational again.

The shifting (rotation?) function krot8left64.asm needs to pass its input qword to yet another function, one that returns the qword's number of blanks, it to be used to loop through the shrds the needed number of times. Or maybe there's a simpler way to do this without a function call?

-mjrice
Title: Re: Rotate 64-bit word
Post by: mjrice on June 14, 2021, 02:45:06 PM
I modified the bottom part of my code, as below, but something is amiss. My input is "XXXXXXXA" (X as blank) but only get a blank output. Why didn't the "A" get shifted left 6 times?

  mov   esi, 6
l2:
  shrd  edx,eax,8
  shrd  eax,ecx,8
  dec esi
  jnz l2
  ret
Title: Re: Rotate 64-bit word
Post by: mjrice on June 14, 2021, 03:37:16 PM
Just realized I wasn't resaving edx  in ecx after a shift.

mrice@debian10-uni:~/work$ ./test
       A
       A
 A     
mrice@debian10-uni:~/work$
Title: Re: Rotate 64-bit word
Post by: mjrice on June 16, 2021, 12:55:15 AM
An attempt at counting blanks. Anyone see a problem in my code? Answer should be 3.

-mjrice

mrice@debian10-uni:~/work$ ./test
   ABCDE
   ABCDE

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

Backtrace for this error:
#0  0xb7cfa74b
#1  0xb7cf984e
#2  0xb7f4ad6b
#3  0x4e2045
Segmentation fault
mrice@debian10-uni:~/work$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  bits 32      ; to be sure.

Section .data
indx   dw 0
nblank   dw 0

struc kblank_stk
      resd 1
.ptr: resd 1
endstruc

  global kblank_
kblank_:
  mov   eax,[esp+kblank_stk.ptr]  ; get pointer

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

testeax:
  cmp   byte [eax+indx], " "
  jnz   testedx
  inc   dword [nblank]
testedx:
  cmp   byte [edx+indx], " "
  jnz   bumpup
  inc   dword [nblank]
bumpup:
  inc   dword [indx]
  cmp   dword [indx], 4
  jz   finished
  jmp   testeax
finished:
  mov   eax, nblank
  mov   edx, 0
  ret 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  100 FORMAT(A8)
  110 FORMAT(I8)
      READ(*,100) LW
      WRITE(*,100) LW
      MW=KBLANK(LW)
      WRITE(*,110) MW
      END


Title: Re: Rotate 64-bit word
Post by: mjrice on June 18, 2021, 02:03:40 AM
How does one test a single byte of a register for a particular value? Maybe one doesn't, or can't?

-mjrice
Title: Re: Rotate 64-bit word
Post by: mjrice on June 18, 2021, 01:39:47 PM
;;;;;This

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

  mov   ecx, 0

  cmp   al, 32
  jnz   finished
  inc   ecx
finished:
  mov   eax, ecx
  mov   edx, 0
  ret

;;;;;Produced

mrice@debian10-uni:~/work$ ./test
ABCDEFG
ABCDEFG
       0
mrice@debian10-uni:~/work$

;;;;;Question

For an input of "ABCDEFG ", doesn't register AL hold the blank?

-mjrice
Title: Re: Rotate 64-bit word
Post by: fredericopissarra on June 20, 2021, 09:49:35 AM
How do you get the size of an string? I recall that FORTRAN don't use NUL char terminated strings...

Hummmm... reading about FORTRAN seems like it not allow for variable size strings (am I right?). So, to scan for a string of 8 chars counting spaces, you should do something like this.

Code: [Select]
  bits  32

  section .text

struc kblank_stk
      resd  1   ; ret addr
.str: resd  1   ; pointer to string.
endstruc

  global kblank_

kblank_:
  ; SysV ABI for i386 mode. Must preserve ESI.
  push  esi

  mov   ecx,8       ; # of chars to check.
  xor   edx,edx     ; # of spaces found.

  ; Get string pointer from stack.
  mov   esi,[esp+kblank_stk.str]

  jmp   .test
 
  align 4
.loop:
  lodsb             ; AL = next char from string.
  cmp   al,' '      ; AL == ' '?
  jnz   .skip       ; No, skip counting
  inc   edx         ; Increment # spaces found
.skip:
  dec   ecx         ; Decrement char counter
.test:
  test  ecx,ecx     ; Is there any char left?
  jnz   .loop       ; Yes, loop.

  ; Restore ESI.
  pop   esi

  mov   eax,edx     ; return count in EAX.

  ret
Title: Re: Rotate 64-bit word
Post by: mjrice on June 21, 2021, 01:55:55 AM
Welcome back. I think you're correct about the strings.

I've been busy. After my last message I poked around some and finally wrote some code that will count blanks in my 8 character 64-bit variables. I'm using ECX as a counter (code below). Tried using ESI so I wouldn't have to set it for the later shifting but got segmentation errors. Compiler, don't know which, perhaps both, seem to flake out on me, was giving me segmentation errors for the code below earlier, so I removed both NASM and gfortran and reinstalled both, after rebooting. The code then ran fine. Weird, huh?  I'll try ESI again tomorrow. I knew the code was good because when I finally got it to run I emailed a copy to myself. I'm aware that EAX must be restored before
shifting occurs. Will try out your code tomorrow.

-mjrice


mrice@debian10-uni:~/work$ ./test
ABCDEFG
ABCDEFG
       1
mrice@debian10-uni:~/work$ ./test
A       
A       
       7

;;;;;;;;;;;;;;;;;;;

  bits 32      ; to be sure.

struc kjunk_stk
      resd 1
.ptr: resd 1
endstruc

  global kjunk_
kjunk_:
  mov   eax,[esp+kjunk_stk.ptr]  ; get pointer

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

  mov ecx, 0

l1:
  cmp al, 32
  jnz l2
  inc ecx
l2:
  ror eax, 8
  cmp al, 32
  jnz l3
  inc ecx
l3:
  ror eax, 8
  cmp al, 32
  jnz l4
  inc ecx
l4:
  ror eax, 8
  cmp al, 32
  jnz l5
  inc ecx
l5:
;  ror eax, 8
  mov eax, edx

l6:
  cmp al, 32
  jnz l7
  inc ecx
l7:
  ror eax, 8
  cmp al, 32
  jnz l8
  inc ecx
l8:
  ror eax, 8
  cmp al, 32
  jnz l9
  inc ecx
l9:
  ror eax, 8
  cmp al, 32
  jnz finished
  inc ecx

finished:
  mov eax, ecx
  mov edx, 0
ret



Title: Re: Rotate 64-bit word
Post by: mjrice on June 21, 2021, 02:02:27 PM
Code I sent worked fine after changing ECX to ESI.

Added this line up before the rotations to save EAX

;  mov   ebx, eax   ;save EAX

It alone caused a seg-fault. I commented it out and, suprise! - it worked again.

Also, after label "finished:", I swapped these

  mov   eax, esi
  mov   edx, 0

for

;  mov   eax, ebx   ;restore EAX
;
;  mov   ecx, edx
;
;l10:
;  shrd  edx,eax,8
;  shrd  eax,ecx,8
;  mov   ecx, edx
;  dec esi
;  jnz l10

Can you think of any reason why using EBX would cause a seg-fault?

 
Title: Re: Rotate 64-bit word
Post by: mjrice on June 21, 2021, 06:27:04 PM
Just ran the code you supplied:

ABCD   
ABCD   
       0
mrice@debian10-uni:~/work$ ./test
ABCDEF 
ABCDEF 
       0
mrice@debiIan10-uni:~/work$ ./test
A       
A       
       0

Let me know if you have any changes.

Title: Re: Rotate 64-bit word
Post by: mjrice on June 21, 2021, 07:21:18 PM
Got my code working.  EAX gets used and abused in the blank search, so I pushed it before, and popped it after. Will post code later. May be a way to make it briefer now that we have it working.

mrice@debian10-uni:~/work$ ./test
    ABCD
    ABCD
ABCD   
mrice@debian10-uni:~/work$ ./test
  ABCDEF
  ABCDEF
ABCDEF 
mrice@debian10-uni:~/work$
Title: Re: Rotate 64-bit word
Post by: mjrice on June 22, 2021, 01:31:13 AM

mrice@debian10-uni:~/work$ ./test
       A
       A
A       

mrice@debian10-uni:~/work$ ./test
 ABCDEFG
 ABCDEFG
ABCDEFG

mrice@debian10-uni:~/work$ ./test
ABCDEFGH
ABCDEFGH
ABCDEFGH


The function, named lanorm.asm, because that's what it's called by the other code.

 bits 32      ; to be sure.

struc lanorm_stk
      resd 1
.ptr: resd 1
endstruc

  global lanorm_
lanorm_:
  mov   eax,[esp+lanorm_stk.ptr]  ; get pointer

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

  push   eax      ;save eax
  mov esi, 0      ;initialize counter for blanks

l1:
  cmp al, 32      ;search EAX for blanks
  jnz l2
  inc esi
l2:
  ror eax, 8
  cmp al, 32
  jnz l3
  inc esi
l3:
  ror eax, 8
  cmp al, 32
  jnz l4
  inc esi
l4:
  ror eax, 8
  cmp al, 32
  jnz l5
  inc esi
l5:
  mov eax, edx      ;search EDX for blanks
l6:
  cmp al, 32
  jnz l7
  inc esi
l7:
  ror eax, 8
  cmp al, 32
  jnz l8
  inc esi
l8:
  ror eax, 8
  cmp al, 32
  jnz l9
  inc esi
l9:
  ror eax, 8
  cmp al, 32
  jnz finished
  inc esi
finished:
  pop   eax      ;restore EAX
  mov   ecx, edx
l10:
  shrd  edx,eax,8
  shrd  eax,ecx,8
  mov   ecx, edx
  dec esi
  jnz l10
  ret   
Title: Re: Rotate 64-bit word
Post by: mjrice on June 22, 2021, 03:20:19 PM
Finding that the AL register points at the "highest" character :

mov    al, 63

ABCDEFGH becomes ?BCDEFGH

Here's a much shorter version, with no blank counting.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

bits 32      ; to be sure.

struc lanorm_stk
      resd 1
.ptr: resd 1
endstruc

  global lanorm_
lanorm_:
  mov   eax,[esp+lanorm_stk.ptr]  ; get pointer

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

  mov   ecx,edx

loop:
  cmp   al, 32
  jnz   finished
   shrd  edx,eax,8
   shrd  eax,ecx,8
  mov   ecx, edx
  jmp   loop
finished:
  ret
Title: Re: Rotate 64-bit word
Post by: fredericopissarra on June 23, 2021, 01:18:32 PM
You still don't provide any reference of what calling convention is used by gfortran and what exactly you want to do, so the only thing I can do is to GUESS...

gfortran (and fortran, in general) is a shitty compiler in terms of optimization. You **could** make your function in fortran and take e look at the generated assembly code using -S option (and `-masm=intel` to see assembly in intel syntax, not AT&T syntax), but gfortran creates a bad code (in terms of optimization)...

OR.. you can use `gcc` (which is a very good compiler, in terms of optimization)... Here's a test of a function rotating 8 first chars in a string:
Code: [Select]
/* test.c */
#include <stdio.h>
#include <stdint.h>
#include <limits.h>

// Generic rotate left 1 QWORD 'bits' bits.
static uint64_t rotateleft ( uint64_t n, unsigned int bits )
{
  // Rotate bits to the left.
  n = ( n << bits ) |
      ( n >> sizeof ( uint64_t ) * CHAR_BIT - bits );

  return n;
}

// This will deal only with the 8 first chars.
// Rotating them 1 char to the right.
void krotateright ( char *s )
{
  // Convert the first 8 bytes to QWORD.
  uint64_t n = * ( uint64_t * ) s;

  // Rotate CHAT_BIT bits and stores back at the memory pointed by s.
  * ( uint64_t * ) s = rotateleft ( n, CHAR_BIT );
}

/* test */
int main ( void )
{
  char s[] = "ABCDEFG ";

  for ( int i = 0; i < 8; i++ )
  {
    printf ( "\"%s\" --rotate right 1 char--> ", s );
    krotateright ( s );
    printf ( "\"%s\"\n", s );
  }
}
Compiling and running:
Code: [Select]
$ cc -O2 -o test test.c
$ ./test
"ABCDEFG " --rotate right 1 char--> " ABCDEFG"
" ABCDEFG" --rotate right 1 char--> "G ABCDEF"
"G ABCDEF" --rotate right 1 char--> "FG ABCDE"
"FG ABCDE" --rotate right 1 char--> "EFG ABCD"
"EFG ABCD" --rotate right 1 char--> "DEFG ABC"
"DEFG ABC" --rotate right 1 char--> "CDEFG AB"
"CDEFG AB" --rotate right 1 char--> "BCDEFG A"
"BCDEFG A" --rotate right 1 char--> "ABCDEFG "
If you compile with:
Code: [Select]
$ cc -O2 -S -masm=intel -fcf-protection=none test.c -o test.sThis will generate the assembly listing of the entire code. Take a look at `test.s` and you'll see something like this:
Code: [Select]
krotateright:
  push  ebx
  mov   ecx, [esp+8]
  mov   eax, [ecx]
  mov   edx, [ecx+4]
  mov   ebx, eax
  shrd  eax, edx, 8
  shrd  edx, ebx, 8
  mov   [ecx], eax
  mov   [ecx+4], edx
  pop   ebx
  ret
Which isn't the best code possible, but it is a start.
Title: Re: Rotate 64-bit word
Post by: mjrice on June 24, 2021, 12:56:28 AM
A lot of this is already implemented. Will send an example to give you a better idea of what SLIP all about.
Title: Re: Rotate 64-bit word
Post by: mjrice on June 24, 2021, 01:26:24 PM
Two figures attached, both from the ACM document "Symmetric List Processor," author Joseph Weizenbaum.

The part I'm working on now allows a user to enter a textual representation of a list, like the one in Fig. 3, from the keyboard, and construct from it an internal list, as shown in the diagrams. Currently lists can only be constructed programmatically.  Will post an example of that next.
Title: Re: Rotate 64-bit word
Post by: mjrice on June 24, 2021, 02:37:30 PM
Ran this this morning.

! Sums structural list of real numbers, prints list and sum.
      dimension space(100)    !  Set aside list space
      call initas(space,100)

      l1 = 0
      l2 = 0
      idummy = list(l1)    !  Function list both assigns list-name to its argument and returns the list name
      idummy = list(l2)

      idummy = newbot(1.0,l1)
      idummy = newbot(6.0,l2)
      idummy = newbot(l2,l1)
      idummy = newbot(3.0,l1)
      call prlsts(l1,3)    !  3 means list is real numbers; 2 is characters; 1 is integers
      total = 0.0
      k = lrdrov(l1)       !  Create list reader
    1 x = advsel(k,f)    !  Advance reader structurally, (s), by element (e). Parameter f is a flag
    if (f .ne. 0) go to 2  !  Reader at end of list?
      total = total + x
      go to 1
    2 continue
      print *, total
      end

mrice@debian10-uni:~/slip/test$ ./test
                    BEGIN LIST
                         1.0000
                     BEGIN SUBLIST
                         6.0000
                     END SUBLIST
                         3.0000
                    END LIST
   10.000000000000000 
Title: Re: Rotate 64-bit word
Post by: mjrice on June 24, 2021, 02:51:49 PM
Btw, used your shifting function to create 8 masks I'll need for my next task. Just changed the  Rs to Ls in the shifting functions. Started at the low end with 255 rather than the high end with -72 quadrillion.

mrice@debian10-uni:~$ ./test
FF00000000000000
  FF000000000000
    FF0000000000
      FF00000000
        FF000000
          FF0000
            FF00
              FF

! Create a mask for each of 8 characters
      INTEGER CP,COPY
      DIMENSION CP(8)
  100 FORMAT(Z16)

      DO 10, I=1,8
      CP(I)=0
   10 CONTINUE

! Start with the low end
      CP(8)=255

! Shift the other 7 leftward from it
      DO 20, I=7,1,-1
      COPY=CP(I+1)
      CP(I)=KROT8LEFT64(COPY)
   20 CONTINUE

      DO 30, I=1,8
      WRITE(*,100) CP(I)
   30 CONTINUE

      END
Title: Re: Rotate 64-bit word
Post by: mjrice on June 25, 2021, 04:15:32 PM
Oops, asked for the G CP(7), shifted it rightward, got the B instead.

      READ(*,100) IGET
      IWORD=ISHFT(IAND(IGET,CP(7)),-8)

mrice@debian10-uni:~$ ./test
ABCDEFGH
B
mrice@debian10-uni:~$

Think of the variable IGET as one 64 bit  word  from an array of 10 of them read from a punched card.  The characters on the word are removed from that word one at a time and shoved one at a time into a waiting all blank 64 bit word from the left end, the same for each succeeding character, shifting earlier characters leftward, until a blank or a comma is found, then the word shifted leftward until all blanks, if any, are to the right of the other characters, forming a token which can be pushed up from the bottom of a waiting list. Encountering a right paren character completes the list. The function RDLSTA recursively reads sublists encountered in this process.

Looking for a way to data-ize the masks to be local to the function. Will try this later:

!      DATA CP(1:8)
!       /
!        Z'FF00000000000000',
!        Z'00FF000000000000',
!        Z'0000FF0000000000',
!        Z'000000FF00000000',
!        Z'00000000FF000000',
!        Z'0000000000FF0000',
!        Z'000000000000FF00',
!        Z'00000000000000FF'
!       /



Title: Re: Rotate 64-bit word
Post by: mjrice on June 26, 2021, 01:53:55 AM
root@debian10-uni:/home/mrice# ./test
              FF
            FF00
          FF0000
        FF000000
      FF00000000
    FF0000000000
  FF000000000000
FF00000000000000
root@debian10-uni:/home/mrice# gfortran -c -fdefault-integer-8 -fdefault-real-8 -fno-range-check test.f95 -o test.o
root@debian10-uni:/home/mrice# gfortran test.o krot8left64.o -o test
root@debian10-uni:/home/mrice# ./test
ABCDEFGH
G

Reversed the order of  the masks and got the 7th character, the G. The computer that was used in he early 1960s must have been big endian?

Can't find a gfortran that will accept hexadecimals in a data statement. Tried gfortran-8. Now to write SQOUT, a function that will "squeeze out" individual characters as this fortran code does.  Another function, to come later, called SQIN will squeeze the output from SQOUT into a waiting, initially all blank, 64 bit word a character at a time.

A line from the fortran code of the SLIP document:

SYMBOL = SQIN(CP(8),SQOUT(CP(IC),CRDBUF(IW)),PLACE)

CP(8) should probably be changed to CP(1)? Also, since IC currently starts at 1 and increments upward, it should begin at 8 and decrement downward.  Or, easier, re-reverse the order of the masks? :-)


Title: Re: Rotate 64-bit word
Post by: mjrice on June 27, 2021, 03:20:28 PM
Finally found a way to localize the masking variables to the RDLSTA function.. Using them to print a few characters on the low end of "ABCDEFGH". On to asm function SQOUT(MASK,WORD).

mrice@debian10-uni:~$ ./test
ABCDEFGH
H
G
F
E
mrice@debian10-uni:~$


! Create a mask for each of 8 characters
      INTEGER CP(8),COPY
      DATA CP(1)/Z'00000000000000FF'/
      DATA CP(2)/Z'000000000000FF00'/
      DATA CP(3)/Z'0000000000FF0000'/
      DATA CP(4)/Z'00000000FF000000'/
      DATA CP(5)/Z'000000FF00000000'/
      DATA CP(6)/Z'0000FF0000000000'/
      DATA CP(7)/Z'00FF000000000000'/
      DATA CP(8)/Z'FF00000000000000'/

  100 FORMAT(A8)
  110 FORMAT(Z16)
 
!      DO 30, I=1,8
!      WRITE(*,110) CP(I)
!   30 CONTINUE

      READ(*,100) IGET

      IWORD=ISHFT(IAND(IGET,CP(8)),0)
      WRITE(*,100) IWORD
      IWORD=ISHFT(IAND(IGET,CP(7)),-8)
      WRITE(*,100) IWORD
      IWORD=ISHFT(IAND(IGET,CP(6)),-16)
      WRITE(*,100) IWORD
      IWORD=ISHFT(IAND(IGET,CP(5)),-24)
      WRITE(*,100) IWORD

      END