Author Topic: Save register value in data variable (386)?  (Read 15741 times)

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Save register value in data variable (386)?
« on: June 29, 2021, 03:34:52 AM »
This function returns the highest character in the input qword that contains ABCDEFGH, printed in hex. The high word mask is hard coded in mhigh. How does one move the two dwords pointed to by EAX into mhigh and mlow?


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


section .data
mhigh:  dw  255
mlow:   dw  0 

section .text  ;AND 64-bit 2nd arg source with 1st arg mask

global sqout_

sqout_:
  push  ebp
  mov   ebp, esp
  mov   eax, [ebp+8]      ;eax <- addr of 1st arg, mask
  mov   ecx, [ebp+12]     ;ecx <- addr of 2nd arg, source

  pop   ebp

  mov   eax, [ecx]
  mov   edx, [ecx+4]

  and   eax, [mhigh]
  and   edx, [mlow]
 
  ret
« Last Edit: June 29, 2021, 01:41:33 PM by mjrice »

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Save register value in data variable (386)?
« Reply #1 on: July 02, 2021, 02:53:50 PM »
Why does ANY usage of register EBX, one of 4 general purpose registers, cause a seg-fault?  Is there a way to temporarily unspecialize it for regular usage? In the code below it just replaces the EAX, pointer to the mask dwords, its only usage in the code, but still get a seg-fault. Why? B/t/w, checked out  Gnu Fortran website but no 386 download was available.

global sqout_

section .text  ;AND 64-bit 2nd arg source with 1st arg mask

global sqout_

sqout_:
  push  ebp
  mov   ebp, esp
  mov   ebx, [ebp+8]      ;ebc <- addr of 1st arg, mask
  mov   ecx, [ebp+12]     ;ecx <- addr of 2nd arg, source

  pop   ebp

  mov   eax, [ecx]
  mov   edx, [ecx+4]
 
;  and   eax, [ebx]
;  and   edx, [ebx+4]

  ret

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Re: Save register value in data variable (386)?
« Reply #2 on: July 02, 2021, 04:24:07 PM »

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Save register value in data variable (386)?
« Reply #3 on: July 03, 2021, 12:26:36 AM »
So, EBX is off-limits. Thanks.

I was trying to print out the 8 character mask passed to my sqout function just to see if it jives with the input. If I can print it out I can also use it in an AND function. But seem to have a problem with one of the two dwords.

global sqout_
section .data
.mymask   dd 0

section .text  ;AND 64-bit 2nd arg source with 1st arg mask

global sqout_

sqout_:
  push  ebp
  mov   ebp, esp
  mov   eax, [ebp+8]      ;eax <- addr of 1st arg, mask
  mov   ecx, [ebp+12]     ;ecx <- addr of 2nd arg, source

  pop   ebp

  mov   dword [.mymask], eax

  mov   eax, [.mymask]
  mov   edx, [eax+4]

  ret

Is there a way around this problem in asm?

For CP(8) input:

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

00472098 could be an address.

Just thought of another way to do it, a loop that increments the two pointers, ecx and eax, ANDing each pair.

AND byte [ECX], [EAX]
AND byte [ECX+1], [EAX+1]
...
 



 


 

 

« Last Edit: July 03, 2021, 01:15:02 AM by mjrice »

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Save register value in data variable (386)?
« Reply #4 on: July 03, 2021, 02:49:47 PM »
Seems like I'm almost there. I'm asking for the 1st character CP(1) in "ABCDEFGH", and getting it (see I/O(CP(1)), 041h, but returning the high-order mask (which accurately matches the character retrieved), instead of what I expected in the low end, the result of

AND HGFE, 00000000h

which is 00000000h,

given that the the order of the characters in EAX and EDX is

EAX   EDX
DCBA  HGFE.

Masks are shown, in order, 1 to 8, in the fortran DATA statement, which matches the order of the characters in memory.

Ditto for the 2nd I/O(CP(4).

These outputs lack the right shifting, none for the 1st character, that would follow their retrieval.

Suggests welcome.

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


MAIN:

      INTEGER CP(8),SQOUT
      DATA CP /Z'00000000000000FF', Z'000000000000FF00',
     1 Z'0000000000FF0000', Z'00000000FF000000',
     2 Z'000000FF00000000', Z'0000FF0000000000',
     3 Z'00FF000000000000', Z'FF00000000000000'/
  100 FORMAT(A8)
  110 FORMAT(Z16)
      READ(*,100) IGET
      IWORD=SQOUT(CP(1),IGET)
      WRITE(*,110) IWORD
      END

SQOUT:

global sqout_

section .text  ;AND 64-bit 2nd arg source with 1st arg mask

global sqout_

sqout_:
  push  ebp
  mov   ebp, esp
  mov   eax, [ebp+8]      ;eax <- addr of 1st arg, mask
  mov   ecx, [ebp+12]     ;ecx <- addr of 2nd arg, source

  pop   ebp

  mov   edx, [eax+4]
  and   [ecx+4], edx
  mov   edx, [ecx+4]

  mov   edx, [eax]
  and   [ecx], edx
  mov   eax, [ecx]

  ret

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

I/O(CP(1):

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

I/O(CP(4):

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




 


 

 


Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Save register value in data variable (386)?
« Reply #5 on: July 04, 2021, 01:55:31 AM »
Got it working. Wasn't saving EDX after using it for one job. Live and learn.


global sqout_

section .text  ;AND 64-bit 2nd arg source with 1st arg mask

global sqout_

sqout_:
  push  ebp
  mov   ebp, esp
  mov   eax, [ebp+8]      ;eax <- addr of 1st arg, mask
  mov   ecx, [ebp+12]     ;ecx <- addr of 2nd arg, source

  pop   ebp

  mov   edx, [eax+4]
  and   [ecx+4], edx
  mov   edx, [ecx+4]

  push   edx

  mov   edx, [eax]
  and   [ecx], edx
  mov   eax, [ecx]

  pop   edx

  ret

Offline mjrice

  • Jr. Member
  • *
  • Posts: 66
Re: Save register value in data variable (386)?
« Reply #6 on: July 07, 2021, 04:41:30 PM »
Discovered that my 2nd arg, the 8 character qword was getting changed, bad for use in looping fortran code.  Fixed it so both args remain unchanged.


ABCDEFGH                   ;2nd arg
0ffh                              ;1st arg
              41                   ;output, extracted letter 
4847464544434241     ;2nd arg, after returning
              FF                    ;1st arg, after returning

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

global sqout_

section .text  ;AND 64-bit 2nd arg source with 1st arg mask

global sqout_

sqout_:
  push  ebp
  mov   ebp, esp
  mov   eax, [ebp+8]      ;eax <- addr of 1st arg, mask
  mov   ecx, [ebp+12]     ;ecx <- addr of 2nd arg, source

  pop   ebp

; Isolate the character

  push   dword [ecx+4]

  mov   edx, [eax+4]
  and   [ecx+4], edx
  mov   edx, [ecx+4]

  pop   dword [ecx+4]

  push   edx

  push   dword [ecx]   

  mov   edx, [eax]
  and   [ecx], edx
  mov   eax, [ecx]

  pop   dword [ecx]

  pop edx

; Right-shift the character

  mov   ecx,edx

loop:
;  cmp   al, 32
  cmp   al, 0
  jnz   finished
   shld  edx,eax,8
   shld  eax,ecx,8
  mov   ecx, edx
  jmp   loop
finished:

  ret