Recent Posts

Pages: [1] 2 3 ... 10
1
MASM64 SDK / Re: Two version of upper and lower case conversions.
« Last post by jj2007 on Today at 05:57:33 PM »
Maybe. Here are timings for a version (attached) using also CharUpperBuff:
Code: [Select]
This code was assembled with ml64 in 64-bit format
@#%&$+*THIS IS A TEST STRING {123}[456] - 1763 ms for CharUpperBuff
@#%&$+*THIS IS A TEST STRING {123}[456] - 296 ms for Upper$()
@#%&$+*THIS IS A TEST STRING {123}[456] - 468 ms for upper
@#%&$+*this is a test string {123}[456] - 359 ms for Lower$()
@#%&$+*this is a test string {123}[456] - 281 ms for lower

@#%&$+*THIS IS A TEST STRING {123}[456] - 1747 ms for CharUpperBuff
@#%&$+*THIS IS A TEST STRING {123}[456] - 281 ms for Upper$()
@#%&$+*THIS IS A TEST STRING {123}[456] - 452 ms for upper
@#%&$+*this is a test string {123}[456] - 359 ms for Lower$()
@#%&$+*this is a test string {123}[456] - 296 ms for lower

@#%&$+*THIS IS A TEST STRING {123}[456] - 1763 ms for CharUpperBuff
@#%&$+*THIS IS A TEST STRING {123}[456] - 297 ms for Upper$()
@#%&$+*THIS IS A TEST STRING {123}[456] - 452 ms for upper
@#%&$+*this is a test string {123}[456] - 374 ms for Lower$()
@#%&$+*this is a test string {123}[456] - 375 ms for lower

It's horribly slow, probably using a table for the LOCALE. I have tried to think of how to use SIMD instructions here, but it's not so easy because of the range restrictions. For example:
Code: [Select]
  mov rdi, offset srcdest
  movups xmm0, spaces
  movups xmm1, OWORD ptr src
  orps xmm1, xmm0
  movups OWORD ptr srcdest, xmm1
Output:
Code: [Select]
@#%&$+*This is A
`#%&$+*this is a
Almost perfect ;)
2
MASM64 SDK / Re: Two version of upper and lower case conversions.
« Last post by hutch-- on Today at 05:11:07 PM »
I think for a lot of these things that memory read/write speed is the limiting factor.
3
The Campus / Re: Parsing a string for NULL terminator
« Last post by jj2007 on Today at 05:02:56 PM »
Some more tricks:
Code: [Select]
include \masm32\include\masm32rt.inc

.data
HelloW db "Hello World", 0

.code
start:
; loop until '\0'
xor ecx, ecx ; same as mov ecx, 0 but much shorter
lp:
pushad
invoke MessageBox, 0, addr HelloW[ecx], chr$("Title"), 0
popad
inc ecx
cmp byte ptr HelloW[ecx], 0
jne lp
MsgBox 0, "bye", "Hi", MB_OK  ; a handy Masm32 macro
  exit

end start
4
The Campus / Re: Parsing a string for NULL terminator
« Last post by Lonewolff on Today at 04:07:00 PM »
Thanks guys!

I think the key thing was the 'cmp byte ptr'. This was the main thing that I was struggling with.

I'll have to start taking notes in a word document for these little intricate details.  :t
5
The Campus / Re: Parsing a string for NULL terminator
« Last post by RussG on Today at 03:54:42 PM »
nevermind, listen to hutch.   :biggrin:

I forgot about eax etc getting overwritten   ::)

I'm used to writing buggy code  :icon_mrgreen:
6
The Campus / Re: Parsing a string for NULL terminator
« Last post by RussG on Today at 03:52:36 PM »
Hi guys,

A basic question involving a simple loop.  :biggrin:

I am trying to loop through a null terminated string and have the count until '/0' stored in ecx.

I have a message box in the middle of the loop for debugging purposes only, but am having trouble with an infinite loop.

Code: [Select]
; loop until '\0'
mov ecx, 0
lp:
invoke MessageBox, 0, addr szBuffer, addr szTitle, 0

mov eax, offset szBuffer
add eax, ecx
cmp eax, 0

inc ecx
jne lp

I am pretty sure I am probably comparing the address itself to zero and not the value.

Any help would be greatly appreciated.  8)

mov eax, offset szBuffef
xor ecx, ecx
loopy:
cmp byte ptr [eax+ecx], 0
je endloopy
inc ecx
; message box code
jmp loopy
endloopy:



sorry for the sloppiness, posting from phone



7
The Campus / Re: Parsing a string for NULL terminator
« Last post by hutch-- on Today at 03:49:37 PM »
This is a simple one. If you want the result in ecx, use ecx instead of eax.

  slen proc pstr:DWORD
    mov eax, pstr
    sub eax, 1
  lbl:
    add eax, 1
    cmp BYTE PTR [eax], 0
    jne lbl
    sub eax, pstr
    ret
  slen endp


For the MessageBox so you don't get problems, use pushad before it and popad after it. Only do this for test code, they are too slow for production code.

What is happening is the code in MessageBox is overwriting the registers you are using.
8
The Campus / Parsing a string for NULL terminator
« Last post by Lonewolff on Today at 03:39:53 PM »
Hi guys,

A basic question involving a simple loop.  :biggrin:

I am trying to loop through a null terminated string and have the count until '/0' stored in ecx.

I have a message box in the middle of the loop for debugging purposes only, but am having trouble with an infinite loop.

Code: [Select]
; loop until '\0'
mov ecx, 0
lp:
invoke MessageBox, 0, addr szBuffer, addr szTitle, 0

mov eax, offset szBuffer
add eax, ecx
cmp eax, 0

inc ecx
jne lp

I am pretty sure I am probably comparing the address itself to zero and not the value.

Any help would be greatly appreciated.  8)
9
MASM64 SDK / Re: Two version of upper and lower case conversions.
« Last post by jj2007 on Today at 03:07:27 PM »
I've hacked together some timings but cannot see a clear winner on my Core i5. Upper$() and Lower$() use the naive and al, -31 resp. or al, 32 thing:
Code: [Select]
This code was assembled with ml64 in 64-bit format
@#%&$+*THIS IS A TEST STRING {123}[456] - 889 ms for Upper$()
@#%&$+*this is a test string {123}[456] - 1108 ms for Lower$()
@#%&$+*THIS IS A TEST STRING {123}[456] - 1123 ms for upper
@#%&$+*this is a test string {123}[456] - 1404 ms for lower

@#%&$+*THIS IS A TEST STRING {123}[456] - 889 ms for Upper$()
@#%&$+*this is a test string {123}[456] - 1108 ms for Lower$()
@#%&$+*THIS IS A TEST STRING {123}[456] - 858 ms for upper
@#%&$+*this is a test string {123}[456] - 1389 ms for lower

@#%&$+*THIS IS A TEST STRING {123}[456] - 889 ms for Upper$()
@#%&$+*this is a test string {123}[456] - 1092 ms for Lower$()
@#%&$+*THIS IS A TEST STRING {123}[456] - 1107 ms for upper
@#%&$+*this is a test string {123}[456] - 1389 ms for lower

@#%&$+*THIS IS A TEST STRING {123}[456] - 889 ms for Upper$()
@#%&$+*this is a test string {123}[456] - 1108 ms for Lower$()
@#%&$+*THIS IS A TEST STRING {123}[456] - 858 ms for upper
@#%&$+*this is a test string {123}[456] - 1419 ms for lower

@#%&$+*THIS IS A TEST STRING {123}[456] - 889 ms for Upper$()
@#%&$+*this is a test string {123}[456] - 1108 ms for Lower$()
@#%&$+*THIS IS A TEST STRING {123}[456] - 1092 ms for upper
@#%&$+*this is a test string {123}[456] - 1404 ms for lower

Same with OPT_64 0:
Code: [Select]
This code was assembled with ML in 32-bit format
@#%&$+*THIS IS A TEST STRING {123}[456] - 889 ms for Upper$()
@#%&$+*this is a test string {123}[456] - 1092 ms for Lower$()
@#%&$+*THIS IS A TEST STRING {123}[456] - 874 ms for upper
@#%&$+*this is a test string {123}[456] - 1107 ms for lower

@#%&$+*THIS IS A TEST STRING {123}[456] - 889 ms for Upper$()
@#%&$+*this is a test string {123}[456] - 1092 ms for Lower$()
@#%&$+*THIS IS A TEST STRING {123}[456] - 874 ms for upper
@#%&$+*this is a test string {123}[456] - 874 ms for lower

@#%&$+*THIS IS A TEST STRING {123}[456] - 889 ms for Upper$()
@#%&$+*this is a test string {123}[456] - 1076 ms for Lower$()
@#%&$+*THIS IS A TEST STRING {123}[456] - 843 ms for upper
@#%&$+*this is a test string {123}[456] - 873 ms for lower
10
MASM64 SDK / Two version of upper and lower case conversions.
« Last post by hutch-- on Today at 01:14:35 PM »
I prototyped these 2 in 32 bit and they were a very easy conversion to 64 bit MASM. They run OK but I have a sneaking suspicion that there is a much faster way to do this using either supplementary SSE3 or SSE4.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    LOCAL pstr  :QWORD

    mrm pstr, "This is a test"

    rcall upper,pstr
    conout pstr,lf

    rcall lower,pstr
    conout pstr,lf

    waitkey
    .exit

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 NOSTACKFRAME

 upper proc

    mov rax, rcx                            ; load string address
    sub rax, 1                              ; set up for loop
    lea rdx, table                          ; load the table address
    jmp lbl                                 ; jump over pre into loop

  pre:
    sub BYTE PTR [rax], 32                  ; sub 32 = convert character to upper case
  lbl:
    add rax, 1
    movzx rcx, BYTE PTR [rax]               ; load byte address in rcx
    cmp BYTE PTR [rcx+rdx], 1               ; test if that byte is lower case
    je pre                                  ; jump to pre to convert
    test rcx, rcx                           ; test for terminator
    jnz lbl                                 ; loop back if not

    ret

  align 16
  table:
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1      ; lower case table
    db 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

 upper endp

 STACKFRAME

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 NOSTACKFRAME

 lower proc

    mov rax, rcx                            ; load string address
    sub rax, 1                              ; set up for loop
    lea rdx, table1                         ; load the table address
    jmp lbl                                 ; jump over pre into loop

  pre:
    add BYTE PTR [rax], 32                  ; add 32 = make lower case
  lbl:
    add rax, 1
    movzx rcx, BYTE PTR [rax]               ; load byte address in rcx
    cmp BYTE PTR [rcx+rdx], 1               ; test if that byte is upper case
    je pre                                  ; jump to pre to convert
    test rcx, rcx                           ; test for terminator
    jnz lbl                                 ; loop back if not

    ret

  align 16
  table1:
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1      ; upper case table
    db 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

 lower endp

 STACKFRAME

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end
Pages: [1] 2 3 ... 10