The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: shadow on June 30, 2005, 05:25:33 AM

Title: turning 10 pages to 3
Post by: shadow on June 30, 2005, 05:25:33 AM
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...?
Title: Re: turning 10 pages to 3
Post by: Mark Jones on June 30, 2005, 06:22:11 AM
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
Title: Re: turning 10 pages to 3
Post by: shadow on June 30, 2005, 06:43:29 AM
It's beautifull!  Thanks!   :P
Title: Re: turning 10 pages to 3
Post by: zooba on June 30, 2005, 08:38:52 AM
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
Title: Re: turning 10 pages to 3
Post by: Titan on June 30, 2005, 09:07:44 AM
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
Title: Re: turning 10 pages to 3
Post by: AeroASM on June 30, 2005, 10:04:20 AM
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.
Title: Re: turning 10 pages to 3
Post by: Mark Jones on June 30, 2005, 02:40:37 PM
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.) :)
Title: Re: turning 10 pages to 3
Post by: Titan on June 30, 2005, 07:10:20 PM
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.
Title: Re: turning 10 pages to 3
Post by: dsouza123 on June 30, 2005, 11:49:14 PM
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.