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

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Rotate 64-bit word
« 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$

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #1 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$

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Re: Rotate 64-bit word
« Reply #2 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
« Last Edit: June 06, 2021, 12:08:12 PM by fredericopissarra »

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #3 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



Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #4 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




Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #5 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


Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Re: Rotate 64-bit word
« Reply #6 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

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #7 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$

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Re: Rotate 64-bit word
« Reply #8 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?

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #9 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

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #10 on: June 06, 2021, 06:40:56 PM »
An afterthought: ROT8LEFT64 might be a procedure, not a function?

-mjrice

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Re: Rotate 64-bit word
« Reply #11 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_:

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #12 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$




Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Re: Rotate 64-bit word
« Reply #13 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?
« Last Edit: June 07, 2021, 02:02:06 PM by fredericopissarra »

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Rotate 64-bit word
« Reply #14 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