News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

turning 10 pages to 3

Started by shadow, June 30, 2005, 05:25:33 AM

Previous topic - Next topic

shadow

ok... I know there is a simple answer to this as usual.  :red


d11 db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#0.rt",0
d12 db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#1.rt",0
d13 db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#2.rt",0

finalpth db 4000 DUP (?)
copypath db 4000 DUP (?)
a:

invoke lstrcat,addr copypath,addr d11
invoke SetDlgItemText,hWnd,IDC_EDT4,addr d11
invoke CopyFile,addr finalpth,addr copypath,FALSE
.if eax==0
invoke MessageBox,hWnd,addr cantt,addr cantc,MB_OKCANCEL + MB_ICONERROR
.if eax==IDCANCEL
invoke ExitProcess,0
.endif
jmp a
.endif
invoke SendDlgItemMessage,hWnd,IDC_PGB1,PBM_STEPIT,0,0


Now I have about 10 pages of this...

invoke lstrcat,addr copypath,addr d11
invoke SetDlgItemText,hWnd,IDC_EDT4,addr d11
invoke CopyFile,addr finalpth,addr copypath,FALSE[
...
invoke lstrcat,addr copypath,addr d12;<< increments
invoke SetDlgItemText,hWnd,IDC_EDT4,addr d12 ;<< increments
invoke CopyFile,addr finalpth,addr copypath,FALSE


Is there a way to store the name of a variable inside of a variable so that I can just increment d11 to d12 instead of having 30 blocks of identical code with the exeption of d11...d12...?

Mark Jones

Sure Shadow. There are several ways to accomplish this. One way would be to convert the repetitive code into a procedure with a passed value. Try something like this:


include masm32rt.inc  ; MASM v8.2 SP2a "runtime" libs

myproc PROTO :DWORD

.data
d11        db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#0.rt",0
d12        db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#1.rt",0
d13        db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#2.rt",0

.data?
finalpth   db 4000 DUP(?)
copypath   db 4000 DUP(?)

.code
start:

    invoke myproc,DWORD PTR D11
    invoke myproc,DWORD PTR D12
    invoke myproc,DWORD PTR D13
    invoke ExitProcess,0 ; terminate gracefully

myproc PROC passedval:DWORD
    invoke lstrcat,ADDR copypath,ADDR passedval
    invoke SetDlgItemText,hWnd,IDC_EDT4,ADDR passedval
    invoke CopyFile,ADDR finalpth,ADDR copypath,FALSE
    .if eax==0
        invoke MessageBox,hWnd,ADDR cantt,ADDR cantc,MB_OKCANCEL + MB_ICONERROR
        .if eax==IDCANCEL
            invoke ExitProcess,0
        .endif
         call loc_a
    .endif
myproc ENDP

loc_a:
; do whatever here
ret

end start
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

shadow

It's beautifull!  Thanks!   :P

zooba

Another is to create a lookup/address table and use that instead:

include masm32rt.inc  ; MASM v8.2 SP2a "runtime" libs

myproc PROTO :DWORD

.data
d11        db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#0.rt",0
d12        db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#1.rt",0
d13        db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#2.rt",0

addrtable DWORD d11, d12, d13, 0      ; zero terminated array :-D

.data?
finalpth   db 4000 DUP(?)
copypath   db 4000 DUP(?)

.code
start:
    ; I haven't preserved any registers for two reasons.
    ; 1. I was lazy and this is quick and untested code
    ; 2. Register preservation is only a good habit and is
    ;    not required all the time, for example, here :-D

    mov esi, OFFSET addrtable
    mov ebx, [esi]    ; assumes there is at least one entry
@@:
    invoke lstrcat,ADDR copypath,[ebx]
    invoke SetDlgItemText,hWnd,IDC_EDT4,[ebx]
    invoke CopyFile,ADDR finalpth,ADDR copypath,FALSE
    add esi, 4
    mov ebx, [esi]
    or ebx, ebx   ; tests to see if entry is ZERO
    jnz @B

    invoke ExitProcess,0 ; terminates gracefully

Titan

I am only making a guess here, I'm no ASM expert.  Please bash me to the ground if I'm wrong... I did try to come up with something.

So you could do an array type like this? :

.data
d11        db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#0.rt",0
d12        db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#1.rt",0
d13        db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#2.rt",0
d14        db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#3.rt",0
d15        db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#4.rt",0
d16        db "lm_alpha-numeric-symbol14#1-7_0_5700x40000000_#5.rt",0

array      dd  d11,d12,d13,d14,d15,d16

.code
xor eax, eax
.while eax != 6
     pushad
     invoke lstrcat,addr copypath,dword ptr [array*eax+04h] ; Find the item in the array
     invoke SetDlgItemText,hWnd,IDC_EDT4, dword ptr [array*eax+04h]
invoke CopyFile,addr finalpth,addr copypath,FALSE
     popad
     inc eax
.endw


Am I stupid or would this work? :red

AeroASM

#5
Yes, in fact that is exactly what zooba did, with these differences:

1. He zero-terminated the array instead of running the loop a set number of times.

2. He counted from 5 to 0 rather than 0 to 5, since the former is more conventional.

3. He used ebx as the loop counter so he did not have to preserve it himself.

Also, you have a couple of mistakes:

1. why do you use pushad and popad? Why not push eax and pop eax?

2. You should not add 4 to the array+eax.

Mark Jones

One other thing Titan, you'll need to parse the code with a debugger to see if the INVOKEs overwrite registers. A lot of the time, EAX is not preserved. Nor is EDX or ECX (and sometimes others.) :)
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

Titan

Quote from: AeroASM on June 30, 2005, 10:04:20 AM
1. why do you use pushad and popad? Why not push eax and pop eax?

2. You should not add 4 to the array+eax.
1. You're right, push eax and pop eax would be better there. :red

2. Isn't each entry in the array a dword.. and therefore 4 bytes long.

dsouza123

dword ptr [array*eax+04h]

should be

dword ptr [array + eax*4]

It is indexing into a dd array of zero terminated string addresses,
each string address indexed equals the address of the start of array + (index * 4).
The * 4 is because an address is 4 bytes so the next index has to be increased by 4 bytes.