Author Topic: Shift leading blanks out of 64-bit word  (Read 16077 times)

nobody

  • Guest
Shift leading blanks out of 64-bit word
« on: January 13, 2009, 04:27:58 PM »
Hi,

I need a function that will shift leading blanks out of a 64-bit word that contains ascii characters. I think the logic below is correct but I'm guessing I'll have to use (MMX?) different register(s).

Note: This is called from Fortran, which passes memory addresses of functional arguments rather than copies of their values.

Michael


global lanorm_

section  .text ;shift leading blanks out of 64-bit word

lanorm_:

push  ebp
  mov   ebp, esp
  mov   eax, [ebp+8]
  pop   ebp
  mov   edx, [eax+4]
  mov   eax, [eax]
.loop:
  cmp byte   al,0x20
  jne .done
  shr      edx:eax,8     ;incorrect
  jmp short .loop
.done:
  ret

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Shift leading blanks out of 64-bit word
« Reply #1 on: January 13, 2009, 07:44:28 PM »
Hi Michael,

Hmmmm... there's a "shrd" instruction, syntax would be "shrd eax, edx, 8". That *might* do what you want...

How would you use the "result" of this? As I understand it, say we've got "___abcde" (spaces represented by underscores, so the accursed forum software won't "optimize" them away). We'll return "abcd" in eax (little-endian, so the 'a' is in al) and "e000" in edx (right?). What then? Put 'em back in a buffer to print? I guess that would work - the result string would be zero-terminated... unless there were no spaces in the input, when it wouldn't be (possible bug?).

I think I'd approach it differently... return a pointer to the first non-space byte in the input...

...
mov eax, [ebp + 8] ; address of string
top:
cmp byte [eax], ' '
jnz done
inc eax
jmp short top
done:
...

Or something like that...

But maybe I don't understand what you have in mind... Try "shrd", and see if that helps. There may be a way to use MMX, too, but I'm woefully ignorant...

Best,
Frank

nobody

  • Guest
Re: Shift leading blanks out of 64-bit word
« Reply #2 on: January 14, 2009, 12:16:46 AM »
The description of the function:

"LANORM ring shifts a word until the highest order character of the result is nonblank. The value of the function is a word so shifted. The word specified as an input parameter is left unmodified."

I'm going to try the SHRD instruction to see what I get but I think I need some kind of character rotating mechanism.

By the way, please explain the effective addr notation in the 4th line below. I've looked
around and can't find any docs.

Michael

wordvar dw      123
        mov     ax,[wordvar]
        mov     ax,[wordvar+1]
        mov     ax,[es:wordvar+bx]

nobody

  • Guest
Re: Shift leading blanks out of 64-bit word
« Reply #3 on: January 14, 2009, 01:35:13 AM »
Hi Frank,

That worked, with the added statement after the shrd instruction (see below), because you also must shift EDX, but as blanks are shifted out on one end zeros are shifted in on the other, just as you said.

That may be adequate. I need to go through the code that calls it to see what's what.

Fortran has a character variable but it's kind of funky so I'm sticking characters in a 64-bit word using a Hollerith field for generality. So, I can store an 8-byte integer, an 8-byte real (float) or 8 characters in a 64-bit word.

iword1 = 8hABCDEFGH
 iword2 = 8h_CHICAGO (underscore represents blank)

Also, Fortran doesn't require the \0 at the end.

Thanks,

Michael


global lanorm_

section .text ;shift leading blanks out of 64-bit word

lanorm_:

push ebp
mov ebp, esp
mov eax, [ebp+8]
pop ebp
mov edx, [eax+4]
mov eax, [eax]
.loop:
cmp byte al,0x20
jne .done
shrd eax,edx,8
shr   edx,8
jmp short .loop
.done:
ret